diff --git a/docs/compiled/artplayer.js b/docs/compiled/artplayer.js index 4f492346d..12af87024 100644 --- a/docs/compiled/artplayer.js +++ b/docs/compiled/artplayer.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),l(()=>i.finalizers.dispose()),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function w(t,e){return{on:(r,n)=>{b(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const x=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),k=/^(?:(?!chrome|android).)*safari/i.test(x),$=/iPad|iPhone|iPod/i.test(x)&&!window.MSStream,E=$||x.includes("Macintosh")&&navigator.maxTouchPoints>=1,C=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(x)||E,T="undefined"!==typeof window&&"undefined"!==typeof document;function L(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function S(t,e=document){return e.querySelector(t)}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){C||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function W(t){return document.createElement(t)}function V(t="",e=""){const r=W("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function Y(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function B(t){return t.getBoundingClientRect()}function H(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:P,append:A,assToVtt:ut,capitalize:Q,clamp:J,createElement:W,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:j,getExt:K,getIcon:V,getRect:B,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:z,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:$,isIOS13:E,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:C,isSafari:k,loadImg:H,mergeDeep:ct,query:S,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:tt,setStyle:R,setStyleText:L,setStyles:O,siblings:I,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:Y,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:N,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:x,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return A(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Ct=new WeakSet;class Tt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=g(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){P(t,`art-${r}`),P(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):A(e,t),i.html&&A(t,i.html),i.style&&O(t,i.style),i.tooltip&&N(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{y(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Ct.has(e)){Ct.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Ct.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Tt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),C||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=w(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=B(e),{height:c,width:d}=B(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}function zt(t,e){const{$progress:r}=t.template,{left:n}=B(r),o=J((C?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function At(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=zt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Rt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=w(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?R(h,"left",0):o>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",o-a/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&C;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?R(h,"left",0):n>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",n-i/2+"px")}(a):f(a),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{M(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Ot(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Rt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=w(t,e);if(!C){let e=!1;i(r,"click",e=>{e.target!==n&&At(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=zt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=zt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function It(t){const{option:e}=t.art;e.isLive||t.add(Ot({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){R(a,"display","flex"),R(s,"display","none")}function c(){R(a,"display","none"),R(s,"display","flex")}N(a,i.get("Play")),N(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=B(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(i,"display","none"),R(a,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(i,"display","flex"),R(a,"display","none"),R(h,"top",100-t+"%"),R(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),C)R(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:C?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=w(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!C&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,i.get("Exit Web Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Web Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,i.get("Exit Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rNt.get(t).option.selector}),it(t,"$control_item",{get:()=>Nt.get(t).item}),it(t,"$control_value",{get:()=>Nt.get(t).value})),Nt.set(t,e)}function Ft(t,e){t.innerHTML=e}function Wt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return _t.set(t,e),()=>{_t.get(t)===e&&_t.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Ft(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Vt extends Tt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;g(t,n);const{on:o}=w(t,n);o("mousemove",()=>{C||(this.show=!0)}),o("click",()=>{C?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=w(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){It(this)}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Ft(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Yt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),h(t))return;(!C||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;C?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const Bt=new WeakMap,Ht=new WeakMap,jt=new WeakMap;function qt(t){return jt.get(t)||u(t)}function Ut(t){const e=Bt.get(t),r=jt.get(t);return()=>Bt.get(t)===e&&(!e||e.active())&&jt.get(t)===r&&(!r||!r.closed)}function Xt(t){const e=jt.get(t),r=u(t).child(),n=r.child();jt.set(t,r),r.add(()=>{jt.get(t)===r&&jt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&Bt.get(t)===o};return Bt.set(t,o),n.add(()=>{Bt.get(t)===o&&Bt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function Gt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Kt(t,e,r){Ht.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Ht.get(t)===e&&(Ht.delete(t),Gt(e))}}function Zt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),u(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(h(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:Ut(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{At(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Yt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(P(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!C||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=u(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||h(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),C||this.init()}init(){const t=this.art;if(h(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!h(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>V(r,e[r])})}}const me=new WeakMap;class ge extends Tt{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),C||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),h(this.art)||t.revision!==e)return;const r=u(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!h(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Tt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{R(i,"display","none"),R(s,"display",null),h(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,p(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),h(t)||n.proxy(e.$state,"click",()=>{h(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),u(t).add(()=>{t.off("destroy",e)}),u(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(h(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!h(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(P(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(h(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",h(this.art)||e.revision!==t||M(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else M(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ee(t,e){if(!$e(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return $e(r)?r:void 0}function Ce(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!$e(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Te(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Le(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function Se(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=qt(t),l=0;return{reset(){l=0,a?.dispose(),M(i,"art-error")},loadStart(){M(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=qt(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!h(t)&&!p.closed&&d===qt(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Pe(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Se(t);!function(t,e){Te(t,"video:canplay",()=>{e.reset(),Le(t,[["loading",!1]])}),Te(t,"video:canplay",()=>{Le(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Te(t,"video:ended",()=>{if(e.loop){const e=Ut(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Le(t,[["controls",!1],["mask",!1]],e)}else Le(t,[["controls",!0],["mask",!0]])})}(t),Te(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Te(t,"video:loadedmetadata",()=>{t.emit("resize"),C&&Le(t,[["loading",!1],["controls",!0],["mask",!0]])}),Te(t,"video:loadstart",()=>{e.loadStart(),Le(t,[["loading",!0],["mask",!1],["controls",!0]])}),Te(t,"video:pause",()=>{Le(t,[["controls",!0],["mask",!0]])}),Te(t,"video:play",()=>{Le(t,[["mask",!1]]),h(t)||R(r,"display","none")}),Te(t,"video:playing",()=>Le(t,[["mask",!1]])),Te(t,"video:progress",()=>{t.playing&&Le(t,[["loading",!1]])}),Te(t,"video:seeked",()=>Le(t,[["loading",!1],["mask",!0]])),Te(t,"video:seeking",()=>Le(t,[["loading",!0],["mask",!1]])),Te(t,"video:timeupdate",()=>Le(t,[["mask",!1]])),Te(t,"video:waiting",()=>Le(t,[["loading",!0],["mask",!1]]))}(t,e)}const Me=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],ze=(()=>{if("undefined"===typeof document)return!1;const t=Me[0],e={};for(const r of Me){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Ae={change:ze.fullscreenchange,error:ze.fullscreenerror},Re={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Re.off("change",o),r()};Re.on("change",o);const i=t[ze.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Re.isFullscreen)return void t();const r=()=>{Re.off("change",r),t()};Re.on("change",r);const n=document[ze.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Re.isFullscreen?Re.exit():Re.request(t,e),onchange(t){Re.on("change",t)},onerror(t){Re.on("error",t)},on(t,e){const r=Ae[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Ae[t];r&&document.removeEventListener(r,e,!1)},raw:ze};function Oe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Re,{isFullscreen:{get:()=>Boolean(document[ze.fullscreenElement])},element:{enumerable:!0,get:()=>document[ze.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[ze.fullscreenEnabled])}});const Ie=new WeakMap;function _e(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Ne(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ie.get(t);if(!n){n=new WeakMap,Ie.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),_e(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),_e(i))}function De(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&Ne(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){Ie.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&Ne(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Fe(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ie.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();f=!0,d=c;const s=De(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const We=new WeakSet;function Ve(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ye(t){We.delete(t),t.removeEventListener("webkitbeginfullscreen",Be),t.removeEventListener("webkitpresentationmodechanged",Be)}function Be(t){if(We.has(this)&&Ve(this,"webkitbeginfullscreen"===t.type)){Ye(this);try{this.webkitExitFullscreen?.()}catch{}}}function He(t){We.add(t),t.addEventListener("webkitbeginfullscreen",Be),t.addEventListener("webkitpresentationmodechanged",Be)}function je(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=Ve(e),i=o,a=!1,s=0;const l=()=>Ve(e,n);function c(r){if(h(t)||(c=e,We.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&He(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(Ye(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,He(e)),l()&&e.webkitExitFullscreen()}}}function qe(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Re.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Oe(t,e.requestFullscreen,void 0),exit:()=>Oe(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",je(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function Ue(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Xe({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Ge(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Xe(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:Ue(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Ke(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Ze(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Je(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Ke(i.left,i.top,Ze(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Qe(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Xe(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=Ue(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Je(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Ke(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ze(o.element));if(h(t)||u!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const tr=new WeakSet,er=t=>"picture-in-picture"===t.webkitPresentationMode;function rr(t){tr.delete(t),t.removeEventListener("webkitpresentationmodechanged",nr),t.removeEventListener("enterpictureinpicture",nr)}function nr(){if(tr.has(this)&&er(this)){rr(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function or(t){tr.add(t),t.addEventListener("webkitpresentationmodechanged",nr),t.addEventListener("enterpictureinpicture",nr)}function ir(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=u(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&a||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||tr.has(e))return;const s=er(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||er(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&or(e),er(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&er(e),set(r){if(h(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(rr(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,or(e)),er(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||er(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function ar(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&_t.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}function sr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function lr(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const i=Xt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=a.child(),f=[],m=Object.keys(u);for(const e of m)sr(h,t,e,t=>{i.acceptingEvents&&f.push([e,t])},!1);if(Kt(t,i,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=sr(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};i.assigned?g():i.onAssigned=g}catch(p){d(p)}})}function cr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&C){if(a||i||(i=!0,a=await H(d,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(i,"left",r.clientWidth-u+"px"):R(i,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function dr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=Ht.get(t);return Ht.delete(t),e||Xt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;sr(l,t,"video:canplay",()=>{c=!d}),sr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Zt(o,t))}else{if(i&&URL.revokeObjectURL(i),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||sr(o.scope,t,"video:canplay",e)}}catch(i){Zt(o,i)}finally{Gt(o)}}})}class pr{constructor(t){dr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Ut(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=J(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>lr(t,e,0);it(t,"switchQuality",{value:e=>lr(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ee({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,h(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=W("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return Z(n,`${e||`artplayer_${tt(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),qe(t),Ge(t),ir(t),function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!$e(o))return;const i=B(e),a=Ee(i,o.width/o.height);a&&!h(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>B(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Qe(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),Ce(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),ar(t),cr(t),Pe(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const ur=new WeakMap,hr="art-auto-orientation-fullscreen";function fr(t){if(ur.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const mr="art-auto-orientation",gr=["width","height","transform-origin","transform"];function vr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return $e(t)&&$e(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(mr);r.classList.remove(mr),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=gr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(mr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{h(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(hr),t&&(t.cancelled=!0,fr(t),t.settled&&ur.get(t.orientation)===t&&ur.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&ur.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,ur.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&ur.get(a)===s,c=e=>{s.settled=!0;const o=l();ur.get(a)===s&&ur.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(hr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(hr):(fr(s),ur.get(a)===s&&ur.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function yr(t){return t.get("times")||{}}function br(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||h(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=v(a);let p,u=0;const f=()=>{const r=++u;if(p?.dispose(),d.closed||h(t)||u!==r)return;const f=d.child();p=f;const m=()=>p===f&&!f.closed&&!h(t);f.add(()=>{p===f&&(p=void 0,R(a,"display","none"))});const g=qt(t).add(()=>{f.dispose()});f.add(()=>{g()});const v=yr(n)[t.option.id||t.option.url];if(!m())return;if(R(a,"display","none"),!m()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!m())return;if(R(a,"display","flex"),!m())return;const y=`${e.get("Last Seen")} ${tt(v)}`;if(!m())return;if(s.textContent=y,!m())return;const b=e.get("Jump Play");if(!m())return;if(l.textContent=b,!m())return;const w=(e,r)=>{const n=t.events.proxy(e,"click",()=>{m()&&r()});f.add(()=>{t.events.remove(n)})};if(w(c,()=>{R(a,"display","none")}),!m())return;if(w(l,()=>{t.seek=v,m()&&(G(t.play()),m()&&(R(i,"display","none"),m()&&R(a,"display","none")))}),!m())return;let x=()=>{},k=!1;const $=()=>{!k&&m()&&(k=!0,x(),Pt(f,()=>{m()&&R(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{b(t,a,"ready",f),b(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=yr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;h(t)||(o.length>i&&delete n[o[0]],n[a]=s,h(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return yr(e)},clear:()=>e.del("times"),delete(t){const r=yr(e);return delete r[t],e.set("times",r),r}}}function wr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||h(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:qt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||M(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||h(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||h(t))return;t.playbackRate=r,e!==i||i.scope.closed||h(t)||P(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function xr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=wr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return z(r,"art-fast-forward")}}}function kr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function i(){h(t)||(P(n,"art-lock"),h(t)||(t.isLock=!0,h(t)||t.emit("lock",!0)))}function a(){h(t)||(M(n,"art-lock"),h(t)||(t.isLock=!1,h(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=v(e);if(n.closed||h(t))return;const o=ft(e,r.lock);if(n.closed||h(t))return;const i=ft(e,r.unlock);n.closed||h(t)||(R(o,"display","none"),b(t,e,"lock",e=>{h(t)||(R(o,"display",e?"inline-flex":"none"),n.closed||h(t)||R(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function $r(t){return oe(t)("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Er{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add($r),!h(t.art)&&e.lock&&C&&t.add(kr),h(t.art)||!e.autoPlayback||e.isLive||t.add(br),!h(t.art)&&e.autoOrientation&&C&&t.add(vr),!h(t.art)&&e.fastForward&&C&&!e.isLive&&t.add(xr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Cr=new WeakMap;function Tr(t){return!t.closed&&!Cr.get(t)}function Lr(t){Cr.set(t,(Cr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Cr.get(t)||1)-1;r?Cr.set(t,r):Cr.delete(t)}}const Sr=new WeakMap,Pr=new WeakMap,Mr=["$parent","$parents","$option","$events","$formatted"];function zr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Sr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Sr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Ar(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Rr(t){const e=Sr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Or(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>Vr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),Wr.set(r,o),Dr.set(e,r),Fr.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function qr(t,e,r,n,o,i){const a=i||Br(e);if(!Tr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(Tr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Tr(a)||h(t)?t.events.remove(s):(Rr(e).events.push(s),i&&i!==Dr.get(e)&&i.add(()=>{const r=Rr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Ur(t,e,r,n){const o=Br(e);if(!Tr(o)||h(t))return;const i=(...e)=>{if(Tr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Xr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/a.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||C||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Gr=new WeakMap;function Kr(t){Gr.delete(t)}const Zr=new WeakMap;function Jr(t,e){e?Zr.set(t,e):Zr.delete(t)}function Qr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Zr.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Jr(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const tn=new WeakMap;async function en(t,e,r,n,o,i,a,s){try{const l=Br(e),c=Br(i),d=(tn.get(i)||0)+1;tn.set(i,d);const p=()=>Tr(l)&&Tr(c)&&!h(t.art)&&tn.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function rn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const nn=new WeakMap;function on(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function an(t){nn.get(t)?.()}function sn(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);Kr(r),an(r);const n=Qr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?rn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=jr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Lr(_r(t)))}catch(l){try{on([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,on([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,on([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Nr(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{on([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&nn.get(r)===m;for(const u of d.items)nn.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const ln=new WeakMap;function cn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function dn(t,e,r=!1){const n=function(t){const e=nn.get(t);return()=>!e||nn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Dr.get(e);(!n||Tr(n)||n.closed)&&Hr(t,e);const o=r.child();return Dr.set(e,o),Fr.set(e,r),Wr.set(o,Rr(e).events),o.add(()=>{Vr(t,Wr.get(o))}),o}(t.art,e,_r(o)),d=()=>Tr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Jr(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;cn(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),cn(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),cn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Jr(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Jr(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Br(e),a=(t,r,n)=>qr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>en(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>en(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return en(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>en(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):A(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function pn(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!Tr(_r(r)))return;const n=(ln.get(t)||0)+1;ln.set(t,n);const o=()=>ln.get(t)===n&&!h(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&_(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!_r(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Ir.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Pr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Ur(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Or(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&_(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Pr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nRr(t).parent},$parents:{get:()=>Rr(t).parents},$option:{get:()=>Rr(t).option},$events:{get:()=>Rr(t).events},$formatted:{get:()=>!0}}),Sr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Or(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Xr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Nr(n)}catch(i){r.push(i)}}try{Hr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Kr(t),an(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return sn(this,t)}add(t,e=this.option){if(h(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};Gr.set(t,e);const r=()=>Gr.get(t)===e;return{current:r,finish(){r()&&Gr.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");R(i,"height",`${o}px`),P(i,"art-setting-item"),P(i,"art-setting-item-back");const a=A(i,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(a,s),A(a,e.$parent.html),qr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),_r(r)),A(r,i)}(this,t)}createItem(t,e=!1){dn(this,t,e)}render(t=this.option){pn(this,t)}}class fn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const mn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class gn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const vn=new WeakMap;function yn(t){return vn.get(t)}function bn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const wn=Tt;class xn extends wn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return vn.set(t,n),r.add(()=>{bn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?O(r,t):R(r,t,e)}update(){!function(t){const e=yn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=yn(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=yn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&bn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=yn(this),r=function(t){const e=t.request,r=new gn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const kn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class $n{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=S(e.container),X(this.$container,`No container element found by ${e.container}`)),X(Y(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=d.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=p(t);o.rollback=r,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,rn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return kn}query(t){return S(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=$n.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&P(this.$player,"art-backdrop"),C&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const En=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Cn{on(t,e,r){const n=this.e||(this.e={});let o=En(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(En(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=En(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new $n(this),this.events=new ae(this),this.storage=new fn(this),this.icons=new fe(this),this.i18n=new ue(this),this.notice=new ke(this),this.player=new pr(this),this.layers=new ve(this),this.controls=new Vt(this),this.contextmenu=new Lt(this),this.subtitle=new xn(this),this.info=new ge(this),this.loading=new ye(this),this.hotkey=new de(this),this.mask=new be(this),this.setting=new hn(this),this.plugins=new Er(this),u(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Sn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Sn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&Ln.push(this)}catch(r){try{f(this,Ln,!0,Sn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Ln}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return Cn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return $n.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:k?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){f(this,Ln,t,Sn.REMOVE_SRC_WHEN_DESTROY)}}return Sn.STYLE=mn,Sn.DEBUG=!1,Sn.CONTEXTMENU=!0,Sn.NOTICE_TIME=2e3,Sn.SETTING_WIDTH=250,Sn.SETTING_ITEM_WIDTH=200,Sn.SETTING_ITEM_HEIGHT=35,Sn.RESIZE_TIME=200,Sn.SCROLL_TIME=200,Sn.SCROLL_GAP=50,Sn.AUTO_PLAYBACK_MAX=10,Sn.AUTO_PLAYBACK_MIN=5,Sn.AUTO_PLAYBACK_TIMEOUT=3e3,Sn.RECONNECT_TIME_MAX=5,Sn.RECONNECT_SLEEP_TIME=1e3,Sn.CONTROL_HIDE_TIME=3e3,Sn.DBCLICK_TIME=300,Sn.DBCLICK_FULLSCREEN=!0,Sn.MOBILE_DBCLICK_PLAY=!0,Sn.MOBILE_CLICK_PLAY=!1,Sn.AUTO_ORIENTATION_TIME=200,Sn.INFO_LOOP_TIME=1e3,Sn.FAST_FORWARD_VALUE=3,Sn.FAST_FORWARD_TIME=1e3,Sn.TOUCH_MOVE_RATIO=.5,Sn.VOLUME_STEP=.1,Sn.SEEK_STEP=5,Sn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Sn.ASPECT_RATIO=["default","4:3","16:9"],Sn.FLIP=["normal","horizontal","vertical"],Sn.FULLSCREEN_WEB_IN_BODY=!0,Sn.LOG_VERSION=!0,Sn.USE_RAF=!1,Sn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=Sn,L("artplayer-style",mn),setTimeout(()=>{Sn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Sn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Sn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),l(()=>i.finalizers.dispose()),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function w(t,e){return{on:(r,n)=>{b(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const x=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),k=/^(?:(?!chrome|android).)*safari/i.test(x),$=/iPad|iPhone|iPod/i.test(x)&&!window.MSStream,E=$||x.includes("Macintosh")&&navigator.maxTouchPoints>=1,C=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(x)||E,T="undefined"!==typeof window&&"undefined"!==typeof document;function L(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new l;let a=!1,s=()=>{};function c(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function d(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;p(n,()=>{if(!e||1===e)return void d(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;p(l,()=>d(l)),i.closed||(l.src=e)}catch(e){c(e)}}))}),i.closed||(n.src=t)}catch(u){c(u)}function p(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){c(u)}},e.onerror=()=>c(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}function S(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function P(t,e=document){return e.querySelector(t)}function M(t,e){return t.classList.add(e)}function z(t,e){return t.classList.remove(e)}function A(t,e){return t.classList.contains(e)}function R(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function O(t,e,r){return t.style[e]=r,t}function I(t,e){for(const r in e)O(t,r,e[r]);return t}function N(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){N(t).forEach(t=>z(t,e)),M(t,e)}function W(t,e,r="top"){C||(t.setAttribute("aria-label",e),M(t,"hint--rounded"),M(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t="",e=""){const r=V("i");return M(r,"art-icon"),M(r,`art-icon-${t}`),R(r,e),r}function B(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function H(t){return t.getBoundingClientRect()}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:M,append:R,assToVtt:ut,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:j,getExt:K,getIcon:Y,getRect:H,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:A,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:$,isIOS13:E,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:C,isSafari:k,loadImg:function(t,e){return L(t,e,void 0)},mergeDeep:ct,query:P,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:z,replaceElement:F,secondToTime:tt,setStyle:O,setStyleText:S,setStyles:I,siblings:N,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:B,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:W,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:x,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return R(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Ct=new WeakSet;class Tt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return A(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?M(e,r):z(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=g(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){M(t,`art-${r}`),M(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):R(e,t),i.html&&R(t,i.html),i.style&&I(t,i.style),i.tooltip&&W(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{y(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Ct.has(e)){Ct.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Ct.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Tt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),C||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=w(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=H(e),{height:c,width:d}=H(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),I(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const zt=new WeakMap,At=new WeakMap,Rt=new WeakMap;function Ot(t){return Rt.get(t)||u(t)}function It(t){const e=zt.get(t),r=Rt.get(t);return()=>zt.get(t)===e&&(!e||e.active())&&Rt.get(t)===r&&(!r||!r.closed)}function Nt(t){const e=Rt.get(t),r=u(t).child(),n=r.child();Rt.set(t,r),r.add(()=>{Rt.get(t)===r&&Rt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&zt.get(t)===o};return zt.set(t,o),n.add(()=>{zt.get(t)===o&&zt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function _t(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Wt(t,e,r){At.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{At.get(t)===e&&(At.delete(t),_t(e))}}function Dt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Ft(t,e){const{$progress:r}=t.template,{left:n}=H(r),o=J((C?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function Vt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Ft(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Yt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=w(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Ft(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?O(h,"left",0):o>e.clientWidth-a/2?O(h,"left",e.clientWidth-a+"px"):O(h,"left",o-a/2+"px")}r.indicator?R(u,r.indicator):O(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&C;if("loaded"===r&&O(c,"width",100*n+"%"),"hover"===r&&(O(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=Ft(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?O(h,"left",0):n>e.clientWidth-i/2?O(h,"left",e.clientWidth-i+"px"):O(h,"left",n-i/2+"px")}(a):f(a),0===n?z(o,"art-progress-hover"):M(o,"art-progress-hover")),"played"===r&&(O(d,"width",100*n+"%"),O(u,"left",100*n+"%")),m){M(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{z(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Bt(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Yt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=w(t,e),a=v(e);let s=0;const l=()=>{const e=It(t);return()=>!a.closed&&!h(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!C){let e;i(r,"click",e=>{e.target!==n&&Vt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Ft(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=Ft(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function Ht(t){const{option:e}=t.art;e.isLive||t.add(Bt({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){O(a,"display","flex"),O(s,"display","none")}function c(){O(a,"display","none"),O(s,"display","flex")}W(a,i.get("Play")),W(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=H(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)O(i,"display","none"),O(a,"display","flex"),O(h,"top","100%"),O(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;O(i,"display","flex"),O(a,"display","none"),O(h,"top",100-t+"%"),O(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),C)O(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:C?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=w(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!C&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{W(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{W(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);O(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(W(t,i.get("Exit Web Fullscreen")),O(a,"display","none"),O(s,"display","inline-flex")):(W(t,i.get("Web Fullscreen")),O(a,"display","inline-flex"),O(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);O(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(W(t,i.get("Exit Fullscreen")),O(a,"display","none"),O(s,"display","inline-flex")):(W(t,i.get("Fullscreen")),O(a,"display","inline-flex"),O(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rqt.get(t).option.selector}),it(t,"$control_item",{get:()=>qt.get(t).item}),it(t,"$control_value",{get:()=>qt.get(t).value})),qt.set(t,e)}function Xt(t,e){t.innerHTML=e}function Gt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;M(n,"art-control-selector");const l=document.createElement("div");M(l,"art-selector-value"),R(l,r.html),n.textContent="",R(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return jt.set(t,e),()=>{jt.get(t)===e&&jt.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Xt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Kt extends Tt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;g(t,n);const{on:o}=w(t,n);o("mousemove",()=>{C||(this.show=!0)}),o("click",()=>{C?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(z(r,"art-hide-cursor"),M(r,"art-hover"),this.timer=Date.now()):(M(r,"art-hide-cursor"),z(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=w(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){Ht(this)}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Xt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Zt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),h(t))return;(!C||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;C?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),u(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(h(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:It(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Vt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Zt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(z(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!C||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=u(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||h(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),C||this.init()}init(){const t=this.art;if(h(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!h(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>Y(r,e[r])})}}const me=new WeakMap;class ge extends Tt{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),C||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),h(this.art)||t.revision!==e)return;const r=u(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!h(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Tt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{O(i,"display","none"),O(s,"display",null),h(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,p(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),h(t)||n.proxy(e.$state,"click",()=>{h(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),u(t).add(()=>{t.off("destroy",e)}),u(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(h(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!h(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(M(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(h(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",h(this.art)||e.revision!==t||z(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else z(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ee(t,e){if(!$e(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return $e(r)?r:void 0}function Ce(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!$e(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}const Te=new WeakMap;function Le(t){return Te.get(t)||0}function Se(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){Te.set(t,Le(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})}function Pe(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Me(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function ze(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Ot(t),l=0;return{reset(){l=0,a?.dispose(),z(i,"art-error")},loadStart(){z(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=Ot(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!h(t)&&!p.closed&&d===Ot(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ae(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ze(t);!function(t,e){Pe(t,"video:canplay",()=>{e.reset(),Me(t,[["loading",!1]])}),Pe(t,"video:canplay",()=>{Me(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Pe(t,"video:ended",()=>{if(e.loop){const e=It(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Me(t,[["controls",!1],["mask",!1]],e)}else Me(t,[["controls",!0],["mask",!0]])})}(t),Pe(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Pe(t,"video:loadedmetadata",()=>{t.emit("resize"),C&&Me(t,[["loading",!1],["controls",!0],["mask",!0]])}),Pe(t,"video:loadstart",()=>{e.loadStart(),Me(t,[["loading",!0],["mask",!1],["controls",!0]])}),Pe(t,"video:pause",()=>{Me(t,[["controls",!0],["mask",!0]])}),Pe(t,"video:play",()=>{Me(t,[["mask",!1]]),h(t)||O(r,"display","none")}),Pe(t,"video:playing",()=>Me(t,[["mask",!1]])),Pe(t,"video:progress",()=>{t.playing&&Me(t,[["loading",!1]])}),Pe(t,"video:seeked",()=>Me(t,[["loading",!1],["mask",!0]])),Pe(t,"video:seeking",()=>Me(t,[["loading",!0],["mask",!1]])),Pe(t,"video:timeupdate",()=>Me(t,[["mask",!1]])),Pe(t,"video:waiting",()=>Me(t,[["loading",!0],["mask",!1]]))}(t,e)}const Re=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Oe=(()=>{if("undefined"===typeof document)return!1;const t=Re[0],e={};for(const r of Re){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Ie={change:Oe.fullscreenchange,error:Oe.fullscreenerror},Ne={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ne.off("change",o),r()};Ne.on("change",o);const i=t[Oe.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ne.isFullscreen)return void t();const r=()=>{Ne.off("change",r),t()};Ne.on("change",r);const n=document[Oe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ne.isFullscreen?Ne.exit():Ne.request(t,e),onchange(t){Ne.on("change",t)},onerror(t){Ne.on("error",t)},on(t,e){const r=Ie[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Ie[t];r&&document.removeEventListener(r,e,!1)},raw:Oe};function _e(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Ne,{isFullscreen:{get:()=>Boolean(document[Oe.fullscreenElement])},element:{enumerable:!0,get:()=>document[Oe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Oe.fullscreenEnabled])}});const We=new WeakMap;function De(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Fe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=We.get(t);if(!n){n=new WeakMap,We.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),De(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),De(i))}function Ve(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&Fe(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){We.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&Fe(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ye(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return We.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();f=!0,d=c;const s=Ve(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const Be=new WeakSet;function He(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function je(t){Be.delete(t),t.removeEventListener("webkitbeginfullscreen",qe),t.removeEventListener("webkitpresentationmodechanged",qe)}function qe(t){if(Be.has(this)&&He(this,"webkitbeginfullscreen"===t.type)){je(this);try{this.webkitExitFullscreen?.()}catch{}}}function Ue(t){Be.add(t),t.addEventListener("webkitbeginfullscreen",qe),t.addEventListener("webkitpresentationmodechanged",qe)}function Xe(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=He(e),i=o,a=!1,s=0;const l=()=>He(e,n);function c(r){if(h(t)||(c=e,Be.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&Ue(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(je(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Ue(e)),l()&&e.webkitExitFullscreen()}}}function Ge(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Ne.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>_e(t,e.requestFullscreen,void 0),exit:()=>_e(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Ye(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Xe(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function Ke(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Ze({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Je(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Ze(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:Ke(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Qe(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function tr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function er(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Qe(i.left,i.top,tr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function rr(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Ze(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=Ke(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=er(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Qe(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,tr(o.element));if(h(t)||u!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const nr=new WeakSet,or=t=>"picture-in-picture"===t.webkitPresentationMode;function ir(t){nr.delete(t),t.removeEventListener("webkitpresentationmodechanged",ar),t.removeEventListener("enterpictureinpicture",ar)}function ar(){if(nr.has(this)&&or(this)){ir(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function sr(t){nr.add(t),t.addEventListener("webkitpresentationmodechanged",ar),t.addEventListener("enterpictureinpicture",ar)}function lr(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=u(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&a||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||nr.has(e))return;const s=or(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||or(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&sr(e),or(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&or(e),set(r){if(h(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(ir(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,sr(e)),or(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||or(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function cr(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&jt.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}function dr(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=It(t);return new Promise((a,s)=>{const l=r=>{try{!h(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=It(t),o=await t.getDataURL();if(!h(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!h(t)&&n()&&Z(o,`${i}.png`),!h(t)&&n()&&t.emit("screenshot",o)}return o}})}function pr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function ur(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const i=Nt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let u=!1,h=!1,f=!1;const m=function(t,e,r){let n,o=!1,i=!1,a=!1,s=Le(t);const l=()=>a||Le(t)!==s,c=()=>!!t.template?.$video?.seeking;return{restore(){if(!r()||l())return;const i=Le(t);t.currentTime=e,s=Le(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),g=async()=>{if(t.aspectRatio=o,c()){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}},v=()=>{if(c()&&!h&&u)try{if(t.template?.$video?.seeking)return;if(!c())return;if(f||(f=!0,t.playbackRate=s),!m.ready()||!c()||h)return;h=!0,p.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(c())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{u=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)pr(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(Wt(t,i,e),!c())return;if(t.notice.show="",!c())return;const k=()=>{if(b.dispose(),!e)return void l();const r={};for(const e of x)r[e]=pr(p,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!c()||p.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(p){d(p)}})}function hr(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:l,videoHeight:c,progressWidth:d,position:p}=e,u=Number(n),h=Number(o)*Number(a)||s/u,f=Number(i)*Number(a)||h/(l/c),m=Math.floor(p/(d/Number(r)));return{height:`${f}px`,width:`${h}px`,backgroundPosition:`-${m%u*h}px -${Math.floor(m/u)*f}px`,left:p<=h/2?0:p>d-h/2?d-h+"px":p-h/2+"px"}}function fr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=u(t).child(),l=!1;function c(){const e=s;s=u(t).child(),o=void 0,l=!1,a=void 0,e.dispose()}function d(){const i=a,l=s;if(!i||!o)return;const c=()=>!h(t)&&!l.closed&&s===l&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!c())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const u=t.controls?.thumbnails,{url:f,scale:m}=e.thumbnails;if(!h(t)&&u&&f&&("hover"===r||"played"===r&&p&&C)){if(i!==u){const t=v(u);if(t.closed)return;i=u,t.add(()=>{i===u&&(i=void 0,c())})}if(a={percentage:n,element:u,sourceActive:It(t)},o)d();else if(!l){const t=s;l=!0,function(t,e,r){return L(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(l=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(l=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{h(t)||!e.url||t.option.isLive||h(t)||(t.option.thumbnails=e,c())}})}function mr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=At.get(t);return At.delete(t),e||Nt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;pr(l,t,"video:canplay",()=>{c=!d}),pr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Dt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||pr(o.scope,t,"video:canplay",e)}}catch(i){Dt(o,i)}finally{_t(o)}}})}class gr{constructor(t){mr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=It(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),Se(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>ur(t,e,0);it(t,"switchQuality",{value:e=>ur(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ee({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,h(t)||t.emit("aspectRatio",i)}}})}(t),dr(t),Ge(t),Je(t),lr(t),function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!$e(o))return;const i=H(e),a=Ee(i,o.width/o.height);a&&!h(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>H(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",rr(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){O(e,"backgroundImage",`url(${t})`)}})}(t),Ce(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),cr(t),fr(t),Ae(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&O(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const vr=new WeakMap,yr="art-auto-orientation-fullscreen";function br(t){if(vr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const wr="art-auto-orientation",xr=["width","height","transform-origin","transform"];function kr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return $e(t)&&$e(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(wr);r.classList.remove(wr),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=xr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(wr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{h(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(yr),t&&(t.cancelled=!0,br(t),t.settled&&vr.get(t.orientation)===t&&vr.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&vr.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,vr.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&vr.get(a)===s,c=e=>{s.settled=!0;const o=l();vr.get(a)===s&&vr.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(yr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(yr):(br(s),vr.get(a)===s&&vr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function $r(t){return t.get("times")||{}}function Er(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||h(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=v(a);let p,u=0;const f=()=>{const r=++u;if(p?.dispose(),d.closed||h(t)||u!==r)return;const f=d.child();p=f;const m=()=>p===f&&!f.closed&&!h(t);f.add(()=>{p===f&&(p=void 0,O(a,"display","none"))});const g=Ot(t).add(()=>{f.dispose()});f.add(()=>{g()});const v=$r(n)[t.option.id||t.option.url];if(!m())return;if(O(a,"display","none"),!m()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!m())return;if(O(a,"display","flex"),!m())return;const y=`${e.get("Last Seen")} ${tt(v)}`;if(!m())return;if(s.textContent=y,!m())return;const b=e.get("Jump Play");if(!m())return;if(l.textContent=b,!m())return;const w=(e,r)=>{const n=t.events.proxy(e,"click",()=>{m()&&r()});f.add(()=>{t.events.remove(n)})};if(w(c,()=>{O(a,"display","none")}),!m())return;if(w(l,()=>{t.seek=v,m()&&(G(t.play()),m()&&(O(i,"display","none"),m()&&O(a,"display","none")))}),!m())return;let x=()=>{},k=!1;const $=()=>{!k&&m()&&(k=!0,x(),Pt(f,()=>{m()&&O(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{b(t,a,"ready",f),b(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=$r(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;h(t)||(o.length>i&&delete n[o[0]],n[a]=s,h(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return $r(e)},clear:()=>e.del("times"),delete(t){const r=$r(e);return delete r[t],e.set("times",r),r}}}function Cr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||h(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Ot(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||z(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||h(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||h(t))return;t.playbackRate=r,e!==i||i.scope.closed||h(t)||M(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function Tr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Cr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return A(r,"art-fast-forward")}}}function Lr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return A(n,"art-lock")}function i(){h(t)||(M(n,"art-lock"),h(t)||(t.isLock=!0,h(t)||t.emit("lock",!0)))}function a(){h(t)||(z(n,"art-lock"),h(t)||(t.isLock=!1,h(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=v(e);if(n.closed||h(t))return;const o=ft(e,r.lock);if(n.closed||h(t))return;const i=ft(e,r.unlock);n.closed||h(t)||(O(o,"display","none"),b(t,e,"lock",e=>{h(t)||(O(o,"display",e?"inline-flex":"none"),n.closed||h(t)||O(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Sr(t){return oe(t)("control",e=>{e?z(t.template.$player,"art-mini-progress-bar"):M(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Pr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add(Sr),!h(t.art)&&e.lock&&C&&t.add(Lr),h(t.art)||!e.autoPlayback||e.isLive||t.add(Er),!h(t.art)&&e.autoOrientation&&C&&t.add(kr),!h(t.art)&&e.fastForward&&C&&!e.isLive&&t.add(Tr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Mr=new WeakMap;function zr(t){return!t.closed&&!Mr.get(t)}function Ar(t){Mr.set(t,(Mr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Mr.get(t)||1)-1;r?Mr.set(t,r):Mr.delete(t)}}const Rr=new WeakMap,Or=new WeakMap,Ir=["$parent","$parents","$option","$events","$formatted"];function Nr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Rr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Rr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function _r(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Wr(t){const e=Rr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Dr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>qr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),jr.set(r,o),Br.set(e,r),Hr.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function Zr(t,e,r,n,o,i){const a=i||Xr(e);if(!zr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(zr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!zr(a)||h(t)?t.events.remove(s):(Wr(e).events.push(s),i&&i!==Br.get(e)&&i.add(()=>{const r=Wr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Jr(t,e,r,n){const o=Xr(e);if(!zr(o)||h(t))return;const i=(...e)=>{if(zr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Qr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/a.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||C||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const tn=new WeakMap;function en(t){tn.delete(t)}const rn=new WeakMap;function nn(t,e){e?rn.set(t,e):rn.delete(t)}function on(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=rn.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),nn(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const an=new WeakMap;async function sn(t,e,r,n,o,i,a,s){try{const l=Xr(e),c=Xr(i),d=(an.get(i)||0)+1;an.set(i,d);const p=()=>zr(l)&&zr(c)&&!h(t.art)&&an.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function ln(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const cn=new WeakMap;function dn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function pn(t){cn.get(t)?.()}function un(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);en(r),pn(r);const n=on(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?ln(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Kr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Ar(Vr(t)))}catch(l){try{dn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,dn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,dn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Yr(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{dn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&cn.get(r)===m;for(const u of d.items)cn.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const hn=new WeakMap;function fn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",R(r,t)}})}function mn(t,e,r=!1){const n=function(t){const e=cn.get(t);return()=>!e||cn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Br.get(e);(!n||zr(n)||n.closed)&&Gr(t,e);const o=r.child();return Br.set(e,o),Hr.set(e,r),jr.set(o,Wr(e).events),o.add(()=>{qr(t,jr.get(o))}),o}(t.art,e,Vr(o)),d=()=>zr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(nn(e),M(p,"art-setting-item"),O(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=R(p,'
'),u=R(p,'
'),f=document.createElement("div");switch(M(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;R(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;R(f,t)}else R(f,s.check)}if(R(n,f),!d())return;fn(e,"icon",f);const m=document.createElement("div");M(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;R(m,g),R(n,m),fn(e,"html",m);const v=document.createElement("div");M(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(R(v,y),R(u,v),fn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");M(t,"art-setting-item-right-icon");const r=R(t,s.switchOn),n=R(t,s.switchOff),o=e.switch;if(!d())return;O(o?n:r,"display","none"),R(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;nn(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(O(n,"display","none"),O(r,"display",null)):(O(n,"display",null),O(r,"display","none"))}});break}case"range":{const t=document.createElement("div");M(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",R(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}M(r,"art-setting-range"),R(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;nn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");M(t,"art-setting-item-right-icon"),R(t,s.arrowRight),R(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Xr(e),a=(t,r,n)=>Zr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>sn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>sn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return sn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&M(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>sn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):R(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function gn(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!zr(Vr(r)))return;const n=(hn.get(t)||0)+1;hn.set(t,n);const o=()=>hn.get(t)===n&&!h(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&_(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Vr(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Fr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;M(r,"art-setting-panel"),R(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Or.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Jr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Dr(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&_(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Or.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nWr(t).parent},$parents:{get:()=>Wr(t).parents},$option:{get:()=>Wr(t).option},$events:{get:()=>Wr(t).events},$formatted:{get:()=>!0}}),Rr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Dr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Qr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Yr(n)}catch(i){r.push(i)}}try{Gr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{en(t),pn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return un(this,t)}add(t,e=this.option){if(h(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};tn.set(t,e);const r=()=>tn.get(t)===e;return{current:r,finish(){r()&&tn.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");O(i,"height",`${o}px`),M(i,"art-setting-item"),M(i,"art-setting-item-back");const a=R(i,'
'),s=document.createElement("div");M(s,"art-setting-item-left-icon"),R(s,n),R(a,s),R(a,e.$parent.html),Zr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Vr(r)),R(r,i)}(this,t)}createItem(t,e=!1){mn(this,t,e)}render(t=this.option){gn(this,t)}}class bn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const wn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class xn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const kn=new WeakMap;function $n(t){return kn.get(t)}function En(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Cn=Tt;class Tn extends Cn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return kn.set(t,n),r.add(()=>{En(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?I(r,t):O(r,t,e)}update(){!function(t){const e=$n(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=$n(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=$n(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&En(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=$n(this),r=function(t){const e=t.request,r=new xn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const Ln=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Sn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=P(e.container),X(this.$container,`No container element found by ${e.container}`)),X(B(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=d.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=p(t);o.rollback=r,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,ln(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return Ln}query(t){return P(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Sn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&M(this.$player,"art-backdrop"),C&&M(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":M(this.$player,"art-destroy")}}const Pn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Mn{on(t,e,r){const n=this.e||(this.e={});let o=Pn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Pn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Pn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Sn(this),this.events=new ae(this),this.storage=new bn(this),this.icons=new fe(this),this.i18n=new ue(this),this.notice=new ke(this),this.player=new gr(this),this.layers=new ve(this),this.controls=new Kt(this),this.contextmenu=new Lt(this),this.subtitle=new Tn(this),this.info=new ge(this),this.loading=new ye(this),this.hotkey=new de(this),this.mask=new be(this),this.setting=new yn(this),this.plugins=new Pr(this),u(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Rn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Rn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&An.push(this)}catch(r){try{f(this,An,!0,Rn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return An}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return Mn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return Sn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:k?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){f(this,An,t,Rn.REMOVE_SRC_WHEN_DESTROY)}}return Rn.STYLE=wn,Rn.DEBUG=!1,Rn.CONTEXTMENU=!0,Rn.NOTICE_TIME=2e3,Rn.SETTING_WIDTH=250,Rn.SETTING_ITEM_WIDTH=200,Rn.SETTING_ITEM_HEIGHT=35,Rn.RESIZE_TIME=200,Rn.SCROLL_TIME=200,Rn.SCROLL_GAP=50,Rn.AUTO_PLAYBACK_MAX=10,Rn.AUTO_PLAYBACK_MIN=5,Rn.AUTO_PLAYBACK_TIMEOUT=3e3,Rn.RECONNECT_TIME_MAX=5,Rn.RECONNECT_SLEEP_TIME=1e3,Rn.CONTROL_HIDE_TIME=3e3,Rn.DBCLICK_TIME=300,Rn.DBCLICK_FULLSCREEN=!0,Rn.MOBILE_DBCLICK_PLAY=!0,Rn.MOBILE_CLICK_PLAY=!1,Rn.AUTO_ORIENTATION_TIME=200,Rn.INFO_LOOP_TIME=1e3,Rn.FAST_FORWARD_VALUE=3,Rn.FAST_FORWARD_TIME=1e3,Rn.TOUCH_MOVE_RATIO=.5,Rn.VOLUME_STEP=.1,Rn.SEEK_STEP=5,Rn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Rn.ASPECT_RATIO=["default","4:3","16:9"],Rn.FLIP=["normal","horizontal","vertical"],Rn.FULLSCREEN_WEB_IN_BODY=!0,Rn.LOG_VERSION=!0,Rn.USE_RAF=!1,Rn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=Rn,S("artplayer-style",wn),setTimeout(()=>{Rn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Rn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Rn}); diff --git a/docs/compiled/artplayer.legacy.js b/docs/compiled/artplayer.legacy.js index fed1f19f9..d43f073d0 100644 --- a/docs/compiled/artplayer.legacy.js +++ b/docs/compiled/artplayer.legacy.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function C(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const T=new WeakMap;function L(t,e){const r=$(t).child();return T.set(e,r),r}function S(t){const e=T.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=T.get(t))||e.dispose()}function M(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function z(t,e){return{on:(r,n)=>{M(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const A=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",O=/^(?:(?!chrome|android).)*safari/i.test(A),R=/iPad|iPhone|iPod/i.test(A)&&!window.MSStream,I=R||A.includes("Macintosh")&&navigator.maxTouchPoints>=1,_=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(A)||I,N="undefined"!==typeof window&&"undefined"!==typeof document;function D(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function F(t,e=document){return e.querySelector(t)}function W(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function H(t,e){for(const r in e)j(t,r,e[r]);return t}function q(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),W(t,e)}function X(t,e,r="top"){_||(t.setAttribute("aria-label",e),W(t,"hint--rounded"),W(t,`hint--${r}`))}function G(t,e){return rt(t).includes(e)}function K(t,e){return e.parentNode.replaceChild(t,e),t}function Z(t){return document.createElement(t)}function J(t="",e=""){const r=Z("i");return W(r,"art-icon"),W(r,`art-icon-${t}`),B(r,e),r}function Q(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function tt(t){return t.getBoundingClientRect()}function et(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:W,append:B,assToVtt:$t,capitalize:dt,clamp:ct,createElement:Z,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:rt,getExt:st,getIcon:J,getRect:tt,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:Y,includeFromEvent:G,inverseClass:U,isBrowser:N,isIOS:R,isIOS13:I,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:_,isSafari:O,loadImg:et,mergeDeep:wt,query:F,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:K,secondToTime:ut,setStyle:j,setStyleText:D,setStyles:H,siblings:q,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:Q,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:X,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:A,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Ct(t,e){return B(t,e)}function Tt(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[c(l({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},_t=new WeakSet;class Nt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?W(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){W(t,`art-${r}`),W(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):B(e,t),i.html&&B(t,i.html),i.style&&H(t,i.style),i.tooltip&&X(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{P(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!_t.has(e)){_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Dt extends Nt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),_||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=z(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return c(l({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return c(l({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return c(l({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=tt(e),{height:c,width:d}=tt(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),H(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{G(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Ft(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Wt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}function Yt(t,e){const{$progress:r}=t.template,{left:n}=tt(r),o=ct((_?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Bt(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Yt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function jt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=z(t,e);let s=()=>{};const l=Tt(".art-progress-hover",e),c=Tt(".art-progress-loaded",e),d=Tt(".art-progress-played",e),u=Tt(".art-progress-highlight",e),p=Tt(".art-progress-indicator",e),h=Tt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Yt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?B(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&_;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),G(a,u)?function(r){const{width:n}=Yt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):W(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){W(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Wt(i,()=>{V(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Ht(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{jt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=z(t,e);if(!_){let e=!1;i(r,"click",e=>{e.target!==n&&Bt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Yt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Yt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function qt(t){const{option:e}=t.art;e.isLive||t.add(Ht({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.play),s=Ct(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}X(a,i.get("Play")),X(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o}=e,i=Ct(t,o.volume),a=Ct(t,o.volumeClose),s=Ct(t,'
'),l=Ct(s,'
'),c=Ct(l,'
'),d=Ct(l,'
'),u=Ct(d,'
'),p=Ct(u,'
'),h=Ct(d,'
');function f(t){const{top:e,height:r}=tt(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),_)j(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>c(l({},t),{style:_?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=z(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!_&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Ct(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Ct(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Ct(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Ct(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.fullscreenWebOn),s=Ct(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.fullscreenOn),s=Ct(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rXt.get(t).option.selector}),gt(t,"$control_item",{get:()=>Xt.get(t).item}),gt(t,"$control_value",{get:()=>Xt.get(t).value})),Xt.set(t,e)}function Kt(t,e){t.innerHTML=e}function Zt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;W(n,"art-control-selector");const l=document.createElement("div");W(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Ct(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return Ut.set(t,e),()=>{Ut.get(t)===e&&Ut.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&Kt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class Jt extends Nt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;L(t,n);const{on:o}=z(t,n);o("mousemove",()=>{_||(this.show=!0)}),o("click",()=>{_?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=G(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(V(r,"art-hide-cursor"),W(r,"art-hover"),this.timer=Date.now()):(W(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=z(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){qt(this)}add(t){if(E(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Kt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Qt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=G(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),E(t))return;(!_||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;_?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const te=new WeakMap,ee=new WeakMap,re=new WeakMap;function ne(t){return re.get(t)||$(t)}function oe(t){const e=te.get(t),r=re.get(t);return()=>te.get(t)===e&&(!e||e.active())&&re.get(t)===r&&(!r||!r.closed)}function ie(t){const e=re.get(t),r=$(t).child(),n=r.child();re.set(t,r),r.add(()=>{re.get(t)===r&&re.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&te.get(t)===o};return te.set(t,o),n.add(()=>{te.get(t)===o&&te.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ae(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function se(t,e,r){ee.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ee.get(t)===e&&(ee.delete(t),ae(e))}}function le(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),$(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(E(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:oe(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Bt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Qt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(W(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Wt(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!_||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=$(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),E(t)||(s=!0,Wt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||E(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),_||this.init()}init(){const t=this.art;if(E(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!E(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Ce{constructor(t){const e=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>J(r,e[r])})}}const Te=new WeakMap;class Le extends Nt{constructor(t){super(t),this.name="info",Te.set(this,{revision:0}),_||this.init()}init(){var t;const e=Te.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),E(this.art)||e.revision!==r)return;const n=$(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!E(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Wt(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends Nt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{j(i,"display","none"),j(s,"display",null),E(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,k(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),E(t)||n.proxy(e.$state,"click",()=>{E(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),$(t).add(()=>{t.off("destroy",e)}),$(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(E(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!E(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(W(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(E(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",E(this.art)||e.revision!==t||V(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else V(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ie(t,e){if(!Re(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Re(r)?r:void 0}function _e(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Re(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Ne(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function De(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function Fe(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=ne(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=ne(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===ne(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function We(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Fe(t);!function(t,e){Ne(t,"video:canplay",()=>{e.reset(),De(t,[["loading",!1]])}),Ne(t,"video:canplay",()=>{De(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Ne(t,"video:ended",()=>{if(e.loop){const e=oe(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&De(t,[["controls",!1],["mask",!1]],e)}else De(t,[["controls",!0],["mask",!0]])})}(t),Ne(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Ne(t,"video:loadedmetadata",()=>{t.emit("resize"),_&&De(t,[["loading",!1],["controls",!0],["mask",!0]])}),Ne(t,"video:loadstart",()=>{e.loadStart(),De(t,[["loading",!0],["mask",!1],["controls",!0]])}),Ne(t,"video:pause",()=>{De(t,[["controls",!0],["mask",!0]])}),Ne(t,"video:play",()=>{De(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Ne(t,"video:playing",()=>De(t,[["mask",!1]])),Ne(t,"video:progress",()=>{t.playing&&De(t,[["loading",!1]])}),Ne(t,"video:seeked",()=>De(t,[["loading",!1],["mask",!0]])),Ne(t,"video:seeking",()=>De(t,[["loading",!0],["mask",!1]])),Ne(t,"video:timeupdate",()=>De(t,[["mask",!1]])),Ne(t,"video:waiting",()=>De(t,[["loading",!0],["mask",!1]]))}(t,e)}const Ve=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Ye=(()=>{if("undefined"===typeof document)return!1;const t=Ve[0],e={};for(const r of Ve){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Be={change:Ye.fullscreenchange,error:Ye.fullscreenerror},je={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{je.off("change",o),r()};je.on("change",o);const i=t[Ye.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!je.isFullscreen)return void t();const r=()=>{je.off("change",r),t()};je.on("change",r);const n=document[Ye.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>je.isFullscreen?je.exit():je.request(t,e),onchange(t){je.on("change",t)},onerror(t){je.on("error",t)},on(t,e){const r=Be[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Be[t];r&&document.removeEventListener(r,e,!1)},raw:Ye};function He(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(je,{isFullscreen:{get:()=>Boolean(document[Ye.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ye.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ye.fullscreenEnabled])}});const qe=new WeakMap;function Ue(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Xe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=qe.get(t);if(!n){n=new WeakMap,qe.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ue(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ue(i))}function Ge(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Xe(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Ft(i,t.document,t.changeEvent,m),Ft(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=qe.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Xe(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ke(t,e){const r=$(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Ft(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=qe.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Ft(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Ge(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Ze=new WeakSet;function Je(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Qe(t){Ze.delete(t),t.removeEventListener("webkitbeginfullscreen",tr),t.removeEventListener("webkitpresentationmodechanged",tr)}function tr(t){var e;if(Ze.has(this)&&Je(this,"webkitbeginfullscreen"===t.type)){Qe(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function er(t){Ze.add(t),t.addEventListener("webkitbeginfullscreen",tr),t.addEventListener("webkitpresentationmodechanged",tr)}function rr(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Je(e),i=o,a=!1,s=0;const l=()=>Je(e,n);function c(r){if(E(t)||(c=e,Ze.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>E(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&er(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Ft(r,e,"webkitbeginfullscreen",()=>c(!0)),Ft(r,e,"webkitendfullscreen",()=>c(!1)),Ft(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Qe(e),t.state="fullscreen",E(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,er(e)),l()&&e.webkitExitFullscreen()}}}function nr(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=je.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>He(t,e.requestFullscreen,void 0),exit:()=>He(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ke(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",rr(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function or(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function ir({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function ar(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(ir(t.placement),r()))}return $(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:or(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function sr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function lr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function cr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Ft(o,e,"click",n),Ft(o,l,"click",()=>{at(t.play())}),Ft(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Ft(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=sr(i.left,i.top,lr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function dr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{ir(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=or(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=cr(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:c(l({},sr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,lr(o.element));if(E(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const ur=new WeakSet,pr=t=>"picture-in-picture"===t.webkitPresentationMode;function hr(t){ur.delete(t),t.removeEventListener("webkitpresentationmodechanged",fr),t.removeEventListener("enterpictureinpicture",fr)}function fr(){var t;if(ur.has(this)&&pr(this)){hr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function mr(t){ur.add(t),t.addEventListener("webkitpresentationmodechanged",fr),t.addEventListener("enterpictureinpicture",fr)}function gr(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=$(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Ft(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Ft(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||ur.has(e))return;const s=pr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||pr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&mr(e),pr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Ft(r,e,l,()=>s());return{get:()=>!E(t)&&pr(e),set(r){var n;if(E(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(hr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,mr(e)),pr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||pr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function vr(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return d(this,null,function*(){const r=function(t){return t&&Ut.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function yr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function br(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=ie(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)yr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(se(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=yr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function wr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&_){if(a||i||(i=!0,a=yield et(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?j(s,"left",r.clientWidth-h+"px"):j(s,"left",o-h/2+"px")}(o)}})),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function xr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=ee.get(t);return ee.delete(t),e||ie(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;yr(l,t,"video:canplay",()=>{c=!d}),yr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>le(o,t))}else{if(i&&URL.revokeObjectURL(i),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||yr(o.scope,t,"video:canplay",e)}}catch(i){le(o,i)}finally{ae(o)}})}})}class kr{constructor(t){xr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=oe(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=ct(n,0,t.duration))}})}(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>br(t,e,0);gt(t,"switchQuality",{value:e=>br(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ie({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=Z("canvas");gt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),gt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return lt(n,`${e||`artplayer_${ut(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),nr(t),ar(t),gr(t),function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Re(o))return;const i=tt(e),a=Ie(i,o.width/o.height);a&&!E(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>tt(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",dr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),_e(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),vr(t),wr(t),We(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const $r=new WeakMap,Er="art-auto-orientation-fullscreen";function Cr(t){if($r.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Tr="art-auto-orientation",Lr=["width","height","transform-origin","transform"];function Sr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Re(t)&&Re(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Tr);r.classList.remove(Tr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Lr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Tr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Wt(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Er),t&&(t.cancelled=!0,Cr(t),t.settled&&$r.get(t.orientation)===t&&$r.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(t))return;if(!i)return void o();if(n&&!n.cancelled&&$r.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,$r.set(l,c);const d=()=>!E(t)&&!c.cancelled&&n===c&&$r.get(l)===c,u=e=>{c.settled=!0;const o=d();$r.get(l)===c&&$r.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(Er),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(Er):(Cr(c),$r.get(l)===c&&$r.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Pr(t){return t.get("times")||{}}function Mr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||E(t))return()=>{};const s=Tt(".art-auto-playback-last",a),l=Tt(".art-auto-playback-jump",a),c=Tt(".art-auto-playback-close",a);Ct(c,r.close);const d=S(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||E(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!E(t);h.add(()=>{u===h&&(u=void 0,j(a,"display","none"))});const m=ne(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Pr(n)[t.option.id||t.option.url];if(!f())return;if(j(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(j(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{j(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(j(i,"display","none"),f()&&j(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Wt(h,()=>{f()&&j(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{M(t,a,"ready",h),M(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Pr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;E(t)||(o.length>i&&delete n[o[0]],n[a]=s,E(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Pr(e)},clear:()=>e.del("times"),delete(t){const r=Pr(e);return delete r[t],e.set("times",r),r}}}function zr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||E(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:ne(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||V(t.template.$player,"art-fast-forward")}}),Wt(i.scope,()=>{if(e!==i||E(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||E(t))return;t.playbackRate=r,e!==i||i.scope.closed||E(t)||W(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Ar(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=zr(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return Y(r,"art-fast-forward")}}}function Or(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){E(t)||(W(n,"art-lock"),E(t)||(t.isLock=!0,E(t)||t.emit("lock",!0)))}function a(){E(t)||(V(n,"art-lock"),E(t)||(t.isLock=!1,E(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=S(e);if(n.closed||E(t))return;const o=Ct(e,r.lock);if(n.closed||E(t))return;const i=Ct(e,r.unlock);n.closed||E(t)||(j(o,"display","none"),M(t,e,"lock",e=>{E(t)||(j(o,"display",e?"inline-flex":"none"),n.closed||E(t)||j(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Rr(t){return me(t)("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):W(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ir{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Rr),!E(t.art)&&e.lock&&_&&t.add(Or),E(t.art)||!e.autoPlayback||e.isLive||t.add(Mr),!E(t.art)&&e.autoOrientation&&_&&t.add(Sr),!E(t.art)&&e.fastForward&&_&&!e.isLive&&t.add(Ar)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const _r=new WeakMap;function Nr(t){return!t.closed&&!_r.get(t)}function Dr(t){_r.set(t,(_r.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(_r.get(t)||1)-1;r?_r.set(t,r):_r.delete(t)}}const Fr=new WeakMap,Wr=new WeakMap,Vr=["$parent","$parents","$option","$events","$formatted"];function Yr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Fr.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Fr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Br(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function jr(t){const e=Fr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Hr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Jr(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),Zr.set(r,o),Gr.set(e,r),Kr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function nn(t,e,r,n,o,i){const a=i||tn(e);if(!Nr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Nr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Nr(a)||E(t)?t.events.remove(s):(jr(e).events.push(s),i&&i!==Gr.get(e)&&i.add(()=>{const r=jr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function on(t,e,r,n){const o=tn(e);if(!Nr(o)||E(t))return;const i=(...e)=>{if(Nr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function an(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||_||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const sn=new WeakMap;function ln(t){sn.delete(t)}const cn=new WeakMap;function dn(t,e){e?cn.set(t,e):cn.delete(t)}function un(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=cn.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),dn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const pn=new WeakMap;function hn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=tn(e),c=tn(i),d=(pn.get(i)||0)+1;pn.set(i,d);const u=()=>Nr(l)&&Nr(c)&&!E(t.art)&&pn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function fn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const mn=new WeakMap;function gn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function vn(t){var e;null==(e=mn.get(t))||e()}function yn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);ln(r),vn(r);const n=un(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?fn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=rn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Dr(Ur(t)))}catch(l){try{gn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,gn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,gn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Xr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{gn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&U(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!E(t.art)&&mn.get(r)===h;for(const v of d.items)mn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const bn=new WeakMap;function wn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function xn(t,e,r=!1){var n,o;const i=function(t){const e=mn.get(t);return()=>!e||mn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Gr.get(e);(!n||Nr(n)||n.closed)&&en(t,e);const o=r.child();return Gr.set(e,o),Kr.set(e,r),Zr.set(o,jr(e).events),o.add(()=>{Jr(t,Zr.get(o))}),o}(t.art,e,Ur(a)),p=()=>Nr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(dn(e),W(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(W(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;wn(e,"icon",m);const g=document.createElement("div");W(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),wn(e,"html",g);const y=document.createElement("div");W(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),wn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),B(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;dn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}W(r,"art-setting-range"),B(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;dn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");W(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=tn(e),a=(t,r,n)=>nn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>hn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>hn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return hn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&W(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>hn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):B(a,h),e.mounted&&p()&&Wt(u,()=>{var r;if(!E(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function kn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Nr(Ur(n)))return;const o=(bn.get(t)||0)+1;bn.set(t,o);const i=()=>bn.get(t)===o&&!E(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&U(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Ur(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return qr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;W(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Wr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=G(r,e.controls.setting),o=G(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{on(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Hr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&U(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Wr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;ojr(t).parent},$parents:{get:()=>jr(t).parents},$option:{get:()=>jr(t).option},$events:{get:()=>jr(t).events},$formatted:{get:()=>!0}}),Fr.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Hr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){an(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Xr(n)}catch(i){r.push(i)}}try{en(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{ln(t),vn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return yn(this,t)}add(t,e=this.option){var r;if(E(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};sn.set(t,e);const r=()=>sn.get(t)===e;return{current:r,finish(){r()&&sn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");j(i,"height",`${o}px`),W(i,"art-setting-item"),W(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");W(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),nn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Ur(r)),B(r,i)}(this,t)}createItem(t,e=!1){xn(this,t,e)}render(t=this.option){kn(this,t)}}class Cn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const Tn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class Ln{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const Sn=new WeakMap;function Pn(t){return Sn.get(t)}function Mn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const zn=Nt;class An extends zn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return Sn.set(t,n),r.add(()=>{Mn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?H(r,t):j(r,t,e)}update(){!function(t){const e=Pn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=Pn(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=Pn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Mn(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return d(this,null,function*(){const e=Pn(this),r=function(t){const e=t.request,r=new Ln(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const On=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${g}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Rn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=F(e.container),it(this.$container,`No container element found by ${e.container}`)),it(Q(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,fn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return On}query(t){return F(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Rn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),K(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&W(this.$player,"art-backdrop"),_&&W(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":W(this.$player,"art-destroy")}}const In=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class _n{on(t,e,r){const n=this.e||(this.e={});let o=In(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(In(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=In(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Rn(this),this.events=new ve(this),this.storage=new Cn(this),this.icons=new Ce(this),this.i18n=new $e(this),this.notice=new Oe(this),this.player=new kr(this),this.layers=new Se(this),this.controls=new Jt(this),this.contextmenu=new Dt(this),this.subtitle=new An(this),this.info=new Le(this),this.loading=new Pe(this),this.hotkey=new xe(this),this.mask=new Me(this),this.setting=new En(this),this.plugins=new Ir(this),$(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Fn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Fn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Dn.push(this)}catch(r){try{C(this,Dn,!0,Fn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Dn}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return _n}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Rn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:O?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){C(this,Dn,t,Fn.REMOVE_SRC_WHEN_DESTROY)}}return Fn.STYLE=Tn,Fn.DEBUG=!1,Fn.CONTEXTMENU=!0,Fn.NOTICE_TIME=2e3,Fn.SETTING_WIDTH=250,Fn.SETTING_ITEM_WIDTH=200,Fn.SETTING_ITEM_HEIGHT=35,Fn.RESIZE_TIME=200,Fn.SCROLL_TIME=200,Fn.SCROLL_GAP=50,Fn.AUTO_PLAYBACK_MAX=10,Fn.AUTO_PLAYBACK_MIN=5,Fn.AUTO_PLAYBACK_TIMEOUT=3e3,Fn.RECONNECT_TIME_MAX=5,Fn.RECONNECT_SLEEP_TIME=1e3,Fn.CONTROL_HIDE_TIME=3e3,Fn.DBCLICK_TIME=300,Fn.DBCLICK_FULLSCREEN=!0,Fn.MOBILE_DBCLICK_PLAY=!0,Fn.MOBILE_CLICK_PLAY=!1,Fn.AUTO_ORIENTATION_TIME=200,Fn.INFO_LOOP_TIME=1e3,Fn.FAST_FORWARD_VALUE=3,Fn.FAST_FORWARD_TIME=1e3,Fn.TOUCH_MOVE_RATIO=.5,Fn.VOLUME_STEP=.1,Fn.SEEK_STEP=5,Fn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Fn.ASPECT_RATIO=["default","4:3","16:9"],Fn.FLIP=["normal","horizontal","vertical"],Fn.FULLSCREEN_WEB_IN_BODY=!0,Fn.LOG_VERSION=!0,Fn.USE_RAF=!1,Fn.REMOVE_SRC_WHEN_DESTROY=!0,N&&(window.Artplayer=Fn,D("artplayer-style",Tn),setTimeout(()=>{Fn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Fn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Fn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function z(t,e){return{on:(r,n)=>{M(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const A=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",O=/^(?:(?!chrome|android).)*safari/i.test(A),R=/iPad|iPhone|iPod/i.test(A)&&!window.MSStream,I=R||A.includes("Macintosh")&&navigator.maxTouchPoints>=1,N=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(A)||I,_="undefined"!==typeof window&&"undefined"!==typeof document;function W(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new b;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}function D(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function F(t,e=document){return e.querySelector(t)}function V(t,e){return t.classList.add(e)}function Y(t,e){return t.classList.remove(e)}function B(t,e){return t.classList.contains(e)}function H(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function q(t,e){for(const r in e)j(t,r,e[r]);return t}function U(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function X(t,e){U(t).forEach(t=>Y(t,e)),V(t,e)}function G(t,e,r="top"){N||(t.setAttribute("aria-label",e),V(t,"hint--rounded"),V(t,`hint--${r}`))}function K(t,e){return rt(t).includes(e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t="",e=""){const r=J("i");return V(r,"art-icon"),V(r,`art-icon-${t}`),H(r,e),r}function tt(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function et(t){return t.getBoundingClientRect()}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:V,append:H,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:rt,getExt:st,getIcon:Q,getRect:et,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:B,includeFromEvent:K,inverseClass:X,isBrowser:_,isIOS:R,isIOS13:I,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:N,isSafari:O,loadImg:function(t,e){return W(t,e,void 0)},mergeDeep:wt,query:F,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:Y,replaceElement:Z,secondToTime:ut,setStyle:j,setStyleText:D,setStyles:q,siblings:U,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:tt,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:G,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:A,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return H(t,e)}function Ct(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[c(l({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},Nt=new WeakSet;class _t{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return B(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?V(e,r):Y(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){V(t,`art-${r}`),V(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):H(e,t),i.html&&H(t,i.html),i.style&&q(t,i.style),i.tooltip&&G(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{P(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Nt.has(e)){Nt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Nt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Wt extends _t{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),N||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=z(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return c(l({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="1"]',t);n&&X(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&X(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return c(l({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="default"]',t);n&&X(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&X(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return c(l({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="normal"]',t);n&&X(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&X(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=et(e),{height:c,width:d}=et(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),q(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{K(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Dt(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ft(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Yt=new WeakMap,Bt=new WeakMap,Ht=new WeakMap;function jt(t){return Ht.get(t)||$(t)}function qt(t){const e=Yt.get(t),r=Ht.get(t);return()=>Yt.get(t)===e&&(!e||e.active())&&Ht.get(t)===r&&(!r||!r.closed)}function Ut(t){const e=Ht.get(t),r=$(t).child(),n=r.child();Ht.set(t,r),r.add(()=>{Ht.get(t)===r&&Ht.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&Yt.get(t)===o};return Yt.set(t,o),n.add(()=>{Yt.get(t)===o&&Yt.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Xt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Gt(t,e,r){Bt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Bt.get(t)===e&&(Bt.delete(t),Xt(e))}}function Kt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Zt(t,e){const{$progress:r}=t.template,{left:n}=et(r),o=ct((N?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Jt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Zt(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=z(t,e);let s=()=>{};const l=Ct(".art-progress-hover",e),c=Ct(".art-progress-loaded",e),d=Ct(".art-progress-played",e),u=Ct(".art-progress-highlight",e),p=Ct(".art-progress-indicator",e),h=Ct(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?H(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&N;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),K(a,u)?function(r){const{width:n}=Zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?Y(o,"art-progress-hover"):V(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){V(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ft(i,()=>{Y(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function te(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Qt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=z(t,e),a=S(e);let s=0;const l=()=>{const e=qt(t);return()=>!a.closed&&!E(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!N){let e;i(r,"click",e=>{e.target!==n&&Jt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Zt(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=Zt(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function ee(t){const{option:e}=t.art;e.isLive||t.add(te({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}G(a,i.get("Play")),G(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o}=e,i=Tt(t,o.volume),a=Tt(t,o.volumeClose),s=Tt(t,'
'),l=Tt(s,'
'),c=Tt(l,'
'),d=Tt(l,'
'),u=Tt(d,'
'),p=Tt(u,'
'),h=Tt(d,'
');function f(t){const{top:e,height:r}=et(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),N)j(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>c(l({},t),{style:N?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=z(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!N&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{G(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{G(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Tt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(G(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(G(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(G(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(G(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rne.get(t).option.selector}),gt(t,"$control_item",{get:()=>ne.get(t).item}),gt(t,"$control_value",{get:()=>ne.get(t).value})),ne.set(t,e)}function ie(t,e){t.innerHTML=e}function ae(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;V(n,"art-control-selector");const l=document.createElement("div");V(l,"art-selector-value"),H(l,r.html),n.textContent="",H(n,l);const c=Tt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return re.set(t,e),()=>{re.get(t)===e&&re.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&ie(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class se extends _t{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;L(t,n);const{on:o}=z(t,n);o("mousemove",()=>{N||(this.show=!0)}),o("click",()=>{N?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=K(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(Y(r,"art-hide-cursor"),V(r,"art-hover"),this.timer=Date.now()):(V(r,"art-hide-cursor"),Y(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=z(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){ee(this)}add(t){if(E(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){ie(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function le(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=K(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),E(t))return;(!N||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;N?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),$(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(E(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:qt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Jt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),le(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(Y(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Ft(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!N||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=$(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),E(t)||(s=!0,Ft(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||E(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),N||this.init()}init(){const t=this.art;if(E(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!E(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Te{constructor(t){const e=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>Q(r,e[r])})}}const Ce=new WeakMap;class Le extends _t{constructor(t){super(t),this.name="info",Ce.set(this,{revision:0}),N||this.init()}init(){var t;const e=Ce.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),E(this.art)||e.revision!==r)return;const n=$(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!E(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ft(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends _t{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{j(i,"display","none"),j(s,"display",null),E(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,k(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),E(t)||n.proxy(e.$state,"click",()=>{E(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),$(t).add(()=>{t.off("destroy",e)}),$(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(E(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!E(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(V(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(E(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",E(this.art)||e.revision!==t||Y(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else Y(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ie(t,e){if(!Re(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Re(r)?r:void 0}function Ne(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Re(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}const _e=new WeakMap;function We(t){return _e.get(t)||0}function De(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){_e.set(t,We(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})}function Fe(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function Ve(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function Ye(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=jt(t),l=0;return{reset(){l=0,null==a||a.dispose(),Y(i,"art-error")},loadStart(){Y(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=jt(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===jt(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Be(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Ye(t);!function(t,e){Fe(t,"video:canplay",()=>{e.reset(),Ve(t,[["loading",!1]])}),Fe(t,"video:canplay",()=>{Ve(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Fe(t,"video:ended",()=>{if(e.loop){const e=qt(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&Ve(t,[["controls",!1],["mask",!1]],e)}else Ve(t,[["controls",!0],["mask",!0]])})}(t),Fe(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Fe(t,"video:loadedmetadata",()=>{t.emit("resize"),N&&Ve(t,[["loading",!1],["controls",!0],["mask",!0]])}),Fe(t,"video:loadstart",()=>{e.loadStart(),Ve(t,[["loading",!0],["mask",!1],["controls",!0]])}),Fe(t,"video:pause",()=>{Ve(t,[["controls",!0],["mask",!0]])}),Fe(t,"video:play",()=>{Ve(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Fe(t,"video:playing",()=>Ve(t,[["mask",!1]])),Fe(t,"video:progress",()=>{t.playing&&Ve(t,[["loading",!1]])}),Fe(t,"video:seeked",()=>Ve(t,[["loading",!1],["mask",!0]])),Fe(t,"video:seeking",()=>Ve(t,[["loading",!0],["mask",!1]])),Fe(t,"video:timeupdate",()=>Ve(t,[["mask",!1]])),Fe(t,"video:waiting",()=>Ve(t,[["loading",!0],["mask",!1]]))}(t,e)}const He=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],je=(()=>{if("undefined"===typeof document)return!1;const t=He[0],e={};for(const r of He){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),qe={change:je.fullscreenchange,error:je.fullscreenerror},Ue={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ue.off("change",o),r()};Ue.on("change",o);const i=t[je.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ue.isFullscreen)return void t();const r=()=>{Ue.off("change",r),t()};Ue.on("change",r);const n=document[je.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ue.isFullscreen?Ue.exit():Ue.request(t,e),onchange(t){Ue.on("change",t)},onerror(t){Ue.on("error",t)},on(t,e){const r=qe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=qe[t];r&&document.removeEventListener(r,e,!1)},raw:je};function Xe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Ue,{isFullscreen:{get:()=>Boolean(document[je.fullscreenElement])},element:{enumerable:!0,get:()=>document[je.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[je.fullscreenEnabled])}});const Ge=new WeakMap;function Ke(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Ze(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ge.get(t);if(!n){n=new WeakMap,Ge.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ke(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ke(i))}function Je(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Ze(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Dt(i,t.document,t.changeEvent,m),Dt(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=Ge.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Ze(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Qe(t,e){const r=$(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Dt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Ge.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Dt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Je(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const tr=new WeakSet;function er(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function rr(t){tr.delete(t),t.removeEventListener("webkitbeginfullscreen",nr),t.removeEventListener("webkitpresentationmodechanged",nr)}function nr(t){var e;if(tr.has(this)&&er(this,"webkitbeginfullscreen"===t.type)){rr(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function or(t){tr.add(t),t.addEventListener("webkitbeginfullscreen",nr),t.addEventListener("webkitpresentationmodechanged",nr)}function ir(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=er(e),i=o,a=!1,s=0;const l=()=>er(e,n);function c(r){if(E(t)||(c=e,tr.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>E(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&or(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Dt(r,e,"webkitbeginfullscreen",()=>c(!0)),Dt(r,e,"webkitendfullscreen",()=>c(!1)),Dt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(rr(e),t.state="fullscreen",E(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,or(e)),l()&&e.webkitExitFullscreen()}}}function ar(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Ue.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Xe(t,e.requestFullscreen,void 0),exit:()=>Xe(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Qe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",ir(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function sr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function lr({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function cr(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(lr(t.placement),r()))}return $(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:sr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function dr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function ur(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function pr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Dt(o,e,"click",n),Dt(o,l,"click",()=>{at(t.play())}),Dt(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Dt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=dr(i.left,i.top,ur(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function hr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{lr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=sr(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=pr(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:c(l({},dr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,ur(o.element));if(E(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const fr=new WeakSet,mr=t=>"picture-in-picture"===t.webkitPresentationMode;function gr(t){fr.delete(t),t.removeEventListener("webkitpresentationmodechanged",vr),t.removeEventListener("enterpictureinpicture",vr)}function vr(){var t;if(fr.has(this)&&mr(this)){gr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function yr(t){fr.add(t),t.addEventListener("webkitpresentationmodechanged",vr),t.addEventListener("enterpictureinpicture",vr)}function br(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=$(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Dt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Dt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||fr.has(e))return;const s=mr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||mr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&yr(e),mr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Dt(r,e,l,()=>s());return{get:()=>!E(t)&&mr(e),set(r){var n;if(E(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(gr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,yr(e)),mr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||mr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function wr(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return d(this,null,function*(){const r=function(t){return t&&re.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function xr(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=qt(t);return new Promise((a,s)=>{const l=r=>{try{!E(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}gt(t,"getDataURL",{value:()=>o(!1)}),gt(t,"getBlobUrl",{value:()=>o(!0)}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=qt(t),o=yield t.getDataURL();if(!E(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!E(t)&&n()&<(o,`${i}.png`),!E(t)&&n()&&t.emit("screenshot",o)}return o})})}function kr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function $r(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=Ut(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let h=!1,f=!1,m=!1;const g=function(t,e,r){let n,o=!1,i=!1,a=!1,s=We(t);const l=()=>a||We(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(){if(!r()||l())return;const i=We(t);t.currentTime=e,s=We(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),v=()=>d(null,null,function*(){if(t.aspectRatio=o,c()){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(c()&&!f&&h)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!c())return;if(m||(m=!0,t.playbackRate=s),!g.ready()||!c()||f)return;f=!0,p.dispose(),v().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(c())try{g.restore()}catch(t){u(t)}},"video:canplay":()=>{h=!0,y()},"video:seeked":y,seek:g.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)kr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(Gt(t,i,e),!c())return;if(t.notice.show="",!c())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=kr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!c()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function Er(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=$(t).child(),c=!1;function d(){const e=s;s=$(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=s;if(!i||!o)return;const d=()=>{var e;return!E(t)&&!c.closed&&s===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-h/2?d-h+"px":u-h/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;j(i.element,t,e)}}me(t)("setBar",(r,n,l)=>{var p;const h=null==(p=t.controls)?void 0:p.thumbnails,{url:f,scale:m}=e.thumbnails;if(!E(t)&&h&&f&&("hover"===r||"played"===r&&l&&N)){if(i!==h){const t=S(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,d())})}if(a={percentage:n,element:h,sourceActive:qt(t)},o)u();else if(!c){const t=s;c=!0,function(t,e,r){return W(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{s!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{E(t)||!e.url||t.option.isLive||E(t)||(t.option.thumbnails=e,d())}})}function Tr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=Bt.get(t);return Bt.delete(t),e||Ut(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;kr(l,t,"video:canplay",()=>{c=!d}),kr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Kt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||kr(o.scope,t,"video:canplay",e)}}catch(i){Kt(o,i)}finally{Xt(o)}})}})}class Cr{constructor(t){Tr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=qt(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),De(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>$r(t,e,0);gt(t,"switchQuality",{value:e=>$r(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ie({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,E(t)||t.emit("aspectRatio",i)}}})}(t),xr(t),ar(t),cr(t),br(t),function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Re(o))return;const i=et(e),a=Ie(i,o.width/o.height);a&&!E(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>et(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",hr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),Ne(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),wr(t),Er(t),Be(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const Lr=new WeakMap,Sr="art-auto-orientation-fullscreen";function Pr(t){if(Lr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Mr="art-auto-orientation",zr=["width","height","transform-origin","transform"];function Ar(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Re(t)&&Re(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Mr);r.classList.remove(Mr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=zr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Mr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Ft(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Sr),t&&(t.cancelled=!0,Pr(t),t.settled&&Lr.get(t.orientation)===t&&Lr.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(t))return;if(!i)return void o();if(n&&!n.cancelled&&Lr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,Lr.set(l,c);const d=()=>!E(t)&&!c.cancelled&&n===c&&Lr.get(l)===c,u=e=>{c.settled=!0;const o=d();Lr.get(l)===c&&Lr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(Sr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(Sr):(Pr(c),Lr.get(l)===c&&Lr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Or(t){return t.get("times")||{}}function Rr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||E(t))return()=>{};const s=Ct(".art-auto-playback-last",a),l=Ct(".art-auto-playback-jump",a),c=Ct(".art-auto-playback-close",a);Tt(c,r.close);const d=S(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||E(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!E(t);h.add(()=>{u===h&&(u=void 0,j(a,"display","none"))});const m=jt(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Or(n)[t.option.id||t.option.url];if(!f())return;if(j(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(j(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{j(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(j(i,"display","none"),f()&&j(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Ft(h,()=>{f()&&j(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{M(t,a,"ready",h),M(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Or(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;E(t)||(o.length>i&&delete n[o[0]],n[a]=s,E(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Or(e)},clear:()=>e.del("times"),delete(t){const r=Or(e);return delete r[t],e.set("times",r),r}}}function Ir(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||E(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:jt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||Y(t.template.$player,"art-fast-forward")}}),Ft(i.scope,()=>{if(e!==i||E(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||E(t))return;t.playbackRate=r,e!==i||i.scope.closed||E(t)||V(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Nr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Ir(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return B(r,"art-fast-forward")}}}function _r(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return B(n,"art-lock")}function i(){E(t)||(V(n,"art-lock"),E(t)||(t.isLock=!0,E(t)||t.emit("lock",!0)))}function a(){E(t)||(Y(n,"art-lock"),E(t)||(t.isLock=!1,E(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=S(e);if(n.closed||E(t))return;const o=Tt(e,r.lock);if(n.closed||E(t))return;const i=Tt(e,r.unlock);n.closed||E(t)||(j(o,"display","none"),M(t,e,"lock",e=>{E(t)||(j(o,"display",e?"inline-flex":"none"),n.closed||E(t)||j(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Wr(t){return me(t)("control",e=>{e?Y(t.template.$player,"art-mini-progress-bar"):V(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Dr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Wr),!E(t.art)&&e.lock&&N&&t.add(_r),E(t.art)||!e.autoPlayback||e.isLive||t.add(Rr),!E(t.art)&&e.autoOrientation&&N&&t.add(Ar),!E(t.art)&&e.fastForward&&N&&!e.isLive&&t.add(Nr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const Fr=new WeakMap;function Vr(t){return!t.closed&&!Fr.get(t)}function Yr(t){Fr.set(t,(Fr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Fr.get(t)||1)-1;r?Fr.set(t,r):Fr.delete(t)}}const Br=new WeakMap,Hr=new WeakMap,jr=["$parent","$parents","$option","$events","$formatted"];function qr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Br.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Br.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Ur(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Xr(t){const e=Br.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Gr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>rn(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),en.set(r,o),Qr.set(e,r),tn.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function ln(t,e,r,n,o,i){const a=i||on(e);if(!Vr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Vr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Vr(a)||E(t)?t.events.remove(s):(Xr(e).events.push(s),i&&i!==Qr.get(e)&&i.add(()=>{const r=Xr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function cn(t,e,r,n){const o=on(e);if(!Vr(o)||E(t))return;const i=(...e)=>{if(Vr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function dn(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||N||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const un=new WeakMap;function pn(t){un.delete(t)}const hn=new WeakMap;function fn(t,e){e?hn.set(t,e):hn.delete(t)}function mn(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=hn.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),fn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const gn=new WeakMap;function vn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=on(e),c=on(i),d=(gn.get(i)||0)+1;gn.set(i,d);const u=()=>Vr(l)&&Vr(c)&&!E(t.art)&&gn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function yn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const bn=new WeakMap;function wn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function xn(t){var e;null==(e=bn.get(t))||e()}function kn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);pn(r),xn(r);const n=mn(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?yn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=sn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Yr(Zr(t)))}catch(l){try{wn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,wn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,wn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Jr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{wn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&X(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!E(t.art)&&bn.get(r)===h;for(const v of d.items)bn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const $n=new WeakMap;function En(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",H(r,t)}})}function Tn(t,e,r=!1){var n,o;const i=function(t){const e=bn.get(t);return()=>!e||bn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Qr.get(e);(!n||Vr(n)||n.closed)&&an(t,e);const o=r.child();return Qr.set(e,o),tn.set(e,r),en.set(o,Xr(e).events),o.add(()=>{rn(t,en.get(o))}),o}(t.art,e,Zr(a)),p=()=>Vr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(fn(e),V(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=H(h,'
'),f=H(h,'
'),m=document.createElement("div");switch(V(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;H(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;H(m,t)}else H(m,c.check)}if(H(i,m),!p())return;En(e,"icon",m);const g=document.createElement("div");V(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;H(g,v),H(i,g),En(e,"html",g);const y=document.createElement("div");V(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(H(y,b),H(f,y),En(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");V(t,"art-setting-item-right-icon");const r=H(t,c.switchOn),n=H(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),H(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;fn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");V(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",H(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}V(r,"art-setting-range"),H(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;fn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");V(t,"art-setting-item-right-icon"),H(t,c.arrowRight),H(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=on(e),a=(t,r,n)=>ln(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>vn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>vn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return vn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&V(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>vn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):H(a,h),e.mounted&&p()&&Ft(u,()=>{var r;if(!E(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function Cn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Vr(Zr(n)))return;const o=($n.get(t)||0)+1;$n.set(t,o);const i=()=>$n.get(t)===o&&!E(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&X(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{X(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Zr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Kr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;V(n,"art-setting-panel"),H(t.$parent,n),X(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Hr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=K(r,e.controls.setting),o=K(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{cn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Gr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&X(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Hr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oXr(t).parent},$parents:{get:()=>Xr(t).parents},$option:{get:()=>Xr(t).option},$events:{get:()=>Xr(t).events},$formatted:{get:()=>!0}}),Br.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Gr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){dn(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Jr(n)}catch(i){r.push(i)}}try{an(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{pn(t),xn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return kn(this,t)}add(t,e=this.option){var r;if(E(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};un.set(t,e);const r=()=>un.get(t)===e;return{current:r,finish(){r()&&un.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");j(i,"height",`${o}px`),V(i,"art-setting-item"),V(i,"art-setting-item-back");const a=H(i,'
'),s=document.createElement("div");V(s,"art-setting-item-left-icon"),H(s,n),H(a,s),H(a,e.$parent.html),ln(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Zr(r)),H(r,i)}(this,t)}createItem(t,e=!1){Tn(this,t,e)}render(t=this.option){Cn(this,t)}}class Pn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const Mn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class zn{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const An=new WeakMap;function On(t){return An.get(t)}function Rn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const In=_t;class Nn extends In{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return An.set(t,n),r.add(()=>{Rn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?q(r,t):j(r,t,e)}update(){!function(t){const e=On(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=On(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=On(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Rn(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return d(this,null,function*(){const e=On(this),r=function(t){const e=t.request,r=new zn(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const _n=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${g}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Wn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=F(e.container),it(this.$container,`No container element found by ${e.container}`)),it(tt(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,yn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return _n}query(t){return F(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Wn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&V(this.$player,"art-backdrop"),N&&V(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":V(this.$player,"art-destroy")}}const Dn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Fn{on(t,e,r){const n=this.e||(this.e={});let o=Dn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Dn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Dn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Wn(this),this.events=new ve(this),this.storage=new Pn(this),this.icons=new Te(this),this.i18n=new $e(this),this.notice=new Oe(this),this.player=new Cr(this),this.layers=new Se(this),this.controls=new se(this),this.contextmenu=new Wt(this),this.subtitle=new Nn(this),this.info=new Le(this),this.loading=new Pe(this),this.hotkey=new xe(this),this.mask=new Me(this),this.setting=new Sn(this),this.plugins=new Dr(this),$(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Bn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Bn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Yn.push(this)}catch(r){try{T(this,Yn,!0,Bn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Yn}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return Fn}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Wn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:O?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){T(this,Yn,t,Bn.REMOVE_SRC_WHEN_DESTROY)}}return Bn.STYLE=Mn,Bn.DEBUG=!1,Bn.CONTEXTMENU=!0,Bn.NOTICE_TIME=2e3,Bn.SETTING_WIDTH=250,Bn.SETTING_ITEM_WIDTH=200,Bn.SETTING_ITEM_HEIGHT=35,Bn.RESIZE_TIME=200,Bn.SCROLL_TIME=200,Bn.SCROLL_GAP=50,Bn.AUTO_PLAYBACK_MAX=10,Bn.AUTO_PLAYBACK_MIN=5,Bn.AUTO_PLAYBACK_TIMEOUT=3e3,Bn.RECONNECT_TIME_MAX=5,Bn.RECONNECT_SLEEP_TIME=1e3,Bn.CONTROL_HIDE_TIME=3e3,Bn.DBCLICK_TIME=300,Bn.DBCLICK_FULLSCREEN=!0,Bn.MOBILE_DBCLICK_PLAY=!0,Bn.MOBILE_CLICK_PLAY=!1,Bn.AUTO_ORIENTATION_TIME=200,Bn.INFO_LOOP_TIME=1e3,Bn.FAST_FORWARD_VALUE=3,Bn.FAST_FORWARD_TIME=1e3,Bn.TOUCH_MOVE_RATIO=.5,Bn.VOLUME_STEP=.1,Bn.SEEK_STEP=5,Bn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Bn.ASPECT_RATIO=["default","4:3","16:9"],Bn.FLIP=["normal","horizontal","vertical"],Bn.FULLSCREEN_WEB_IN_BODY=!0,Bn.LOG_VERSION=!0,Bn.USE_RAF=!1,Bn.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Bn,D("artplayer-style",Mn),setTimeout(()=>{Bn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Bn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Bn}); diff --git a/docs/compiled/artplayer.mjs b/docs/compiled/artplayer.mjs index bd4940049..3a9f59cd8 100644 --- a/docs/compiled/artplayer.mjs +++ b/docs/compiled/artplayer.mjs @@ -496,6 +496,132 @@ const isIOS = /iPad|iPhone|iPod/i.test(userAgent) && !window.MSStream; const isIOS13 = isIOS || userAgent.includes("Macintosh") && navigator.maxTouchPoints >= 1; const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || isIOS13; const isBrowser = typeof window !== "undefined" && typeof document !== "undefined"; +function requestImage(url, scale, owner) { + return new Promise((resolve, reject) => { + const request = owner ? owner.child() : new ResourceScope(); + let complete = false; + let releaseBlob = () => { + }; + function fail(error2) { + if (complete) + return; + complete = true; + try { + request.dispose(); + } catch (cleanupError) { + console.warn("Additional image cleanup failure:", cleanupError); + } + try { + releaseBlob(); + } catch (cleanupError) { + console.warn("Additional image cleanup failure:", cleanupError); + } + reject(error2); + } + function finish2(image) { + if (complete || request.closed) + return; + complete = true; + try { + request.dispose(); + resolve(image); + } catch (error2) { + try { + releaseBlob(); + } finally { + reject(error2); + } + } + } + request.add(() => { + if (!complete) { + complete = true; + try { + releaseBlob(); + } finally { + resolve(void 0); + } + } + }); + if (request.closed) + return; + function watch(image, loaded) { + image.onload = () => { + if (!complete && !request.closed) { + try { + loaded(); + } catch (error2) { + fail(error2); + } + } + }; + image.onerror = () => fail(new Error(`Image load failed: ${url}`)); + request.add(() => { + image.onload = null; + image.onerror = null; + if (!complete) + image.removeAttribute("src"); + }); + } + try { + const image = new Image(); + watch(image, () => { + if (!scale || scale === 1) { + finish2(image); + return; + } + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + canvas.width = image.width * scale; + canvas.height = image.height * scale; + if (!context) + throw new TypeError("Canvas 2D context is unavailable"); + if (complete || request.closed) + return; + context.drawImage(image, 0, 0, canvas.width, canvas.height); + if (complete || request.closed) + return; + canvas.toBlob((blob) => { + if (complete || request.closed) + return; + try { + if (!blob) + throw new Error("Unable to encode thumbnail image"); + const blobUrl = URL.createObjectURL(blob); + let revoked = false; + const revoke = () => { + if (!revoked) { + revoked = true; + URL.revokeObjectURL(blobUrl); + } + }; + releaseBlob = owner ? owner.add(revoke) : revoke; + if (complete || request.closed) { + releaseBlob(); + return; + } + const scaled = new Image(); + watch(scaled, () => finish2(scaled)); + if (!request.closed) + scaled.src = blobUrl; + } catch (error2) { + fail(error2); + } + }); + }); + if (!request.closed) + image.src = url; + } catch (error2) { + fail(error2); + } + }); +} +function loadImg(url, scale) { + return requestImage(url, scale, void 0); +} +function loadThumbnailImage(url, scale, owner) { + return requestImage(url, scale, owner); +} function setStyleText(id2, style) { let $style = document.getElementById(id2); if (!$style) { @@ -598,38 +724,6 @@ function supportsFlex() { function getRect(el) { return el.getBoundingClientRect(); } -function loadImg(url, scale) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = function() { - if (!scale || scale === 1) { - resolve(img); - } else { - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - canvas.width = img.width * scale; - canvas.height = img.height * scale; - ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - canvas.toBlob((blob) => { - const blobUrl = URL.createObjectURL(blob); - const scaledImg = new Image(); - scaledImg.onload = function() { - resolve(scaledImg); - }; - scaledImg.onerror = function() { - URL.revokeObjectURL(blobUrl); - reject(new Error(`Image load failed: ${url}`)); - }; - scaledImg.src = blobUrl; - }); - } - }; - img.onerror = function() { - reject(new Error(`Image load failed: ${url}`)); - }; - img.src = url; - }); -} function getComposedPath(event) { if (event.composedPath) return event.composedPath(); @@ -1619,6 +1713,75 @@ function playAndPause(option) { } }); } +const current = /* @__PURE__ */ new WeakMap(); +const assignments = /* @__PURE__ */ new WeakMap(); +const sources = /* @__PURE__ */ new WeakMap(); +function getSourceScope(owner) { + return sources.get(owner) || getScope(owner); +} +function captureSource(owner) { + const operation = current.get(owner); + const source = sources.get(owner); + return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); +} +function beginSource(owner) { + const previous = sources.get(owner); + const source = getScope(owner).child(); + const scope = source.child(); + sources.set(owner, source); + source.add(() => { + if (sources.get(owner) === source) + sources.delete(owner); + }); + const operation = { + scope, + assigned: false, + acceptingEvents: false, + active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation + }; + current.set(owner, operation); + scope.add(() => { + if (current.get(owner) === operation) + current.delete(owner); + operation.onAssigned = void 0; + operation.onError = void 0; + }); + previous?.dispose(); + return operation; +} +function takeAssignment(owner) { + const operation = assignments.get(owner); + assignments.delete(owner); + return operation || beginSource(owner); +} +function finishAssignment(operation) { + operation.assigned = true; + const callback = operation.onAssigned; + operation.onAssigned = void 0; + if (operation.active()) + callback?.(); +} +function assignUrl(owner, operation, url) { + assignments.set(owner, operation); + operation.acceptingEvents = true; + try { + owner.url = url; + } finally { + if (assignments.get(owner) === operation) { + assignments.delete(owner); + finishAssignment(operation); + } + } +} +function failSource(operation, error2) { + if (!operation.active()) + return; + if (operation.onError) + operation.onError(error2); + else + console.warn("Failed to initialize ArtPlayer source:", error2); + operation.scope.dispose(); +} function getPosFromEvent(art, event) { const { $progress } = art.template; const { left } = getRect($progress); @@ -1630,14 +1793,20 @@ function getPosFromEvent(art, event) { return { second, time: time2, width, percentage }; } function setCurrentTime(art, event, active2 = () => true) { + if (!active2()) + return; if (art.isRotate) { const percentage = (event.touches[0].clientY - art.top) / art.height; const second = percentage * art.duration; + if (!active2()) + return; art.emit("setBar", "played", percentage, event); if (active2()) art.seek = second; } else { const { second, percentage } = getPosFromEvent(art, event); + if (!active2()) + return; art.emit("setBar", "played", percentage, event); if (active2()) art.seek = second; @@ -1647,34 +1816,51 @@ function installProgressInteractions(art, $control) { const { $progress } = art.template; const $indicator = $control.querySelector(".art-progress-indicator"); const { on, proxy } = controlEvents(art, $control); + const scope = entryScope($control); + let action = 0; + const capture = () => { + const sourceActive = captureSource(art); + return () => !scope.closed && !isClosing(art) && sourceActive(); + }; + const captureAction = () => { + const revision = ++action; + const active2 = capture(); + return () => revision === action && active2(); + }; if (!isMobile) { - let isDragging = false; + let dragging; proxy($progress, "click", (event) => { if (event.target !== $indicator) { - setCurrentTime(art, event); + setCurrentTime(art, event, captureAction()); } }); proxy($progress, "mousemove", (event) => { + const active2 = capture(); const { percentage } = getPosFromEvent(art, event); - art.emit("setBar", "hover", percentage, event); + if (active2()) + art.emit("setBar", "hover", percentage, event); }); proxy($progress, "mouseleave", (event) => { art.emit("setBar", "hover", 0, event); }); proxy($progress, "mousedown", (event) => { - isDragging = event.button === 0; + dragging = event.button === 0 ? captureAction() : void 0; }); on("document:mousemove", (event) => { - if (isDragging) { + const active2 = dragging; + if (active2?.()) { const { second, percentage } = getPosFromEvent(art, event); + if (!active2() || dragging !== active2) + return; art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2() && dragging === active2) + art.seek = second; + } else { + dragging = void 0; } }); on("document:mouseup", () => { - if (isDragging) { - isDragging = false; - } + dragging = void 0; }); } } @@ -1814,7 +2000,7 @@ function screenshot$1(option) { const { icons } = art; appendElement($control, icons.screenshot); proxy($control, "click", () => { - art.screenshot(); + silencePromise(art.screenshot()); }); } }); @@ -2278,75 +2464,6 @@ function clickInit(art, events) { } }); } -const current = /* @__PURE__ */ new WeakMap(); -const assignments = /* @__PURE__ */ new WeakMap(); -const sources = /* @__PURE__ */ new WeakMap(); -function getSourceScope(owner) { - return sources.get(owner) || getScope(owner); -} -function captureSource(owner) { - const operation = current.get(owner); - const source = sources.get(owner); - return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); -} -function beginSource(owner) { - const previous = sources.get(owner); - const source = getScope(owner).child(); - const scope = source.child(); - sources.set(owner, source); - source.add(() => { - if (sources.get(owner) === source) - sources.delete(owner); - }); - const operation = { - scope, - assigned: false, - acceptingEvents: false, - active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation - }; - current.set(owner, operation); - scope.add(() => { - if (current.get(owner) === operation) - current.delete(owner); - operation.onAssigned = void 0; - operation.onError = void 0; - }); - previous?.dispose(); - return operation; -} -function takeAssignment(owner) { - const operation = assignments.get(owner); - assignments.delete(owner); - return operation || beginSource(owner); -} -function finishAssignment(operation) { - operation.assigned = true; - const callback = operation.onAssigned; - operation.onAssigned = void 0; - if (operation.active()) - callback?.(); -} -function assignUrl(owner, operation, url) { - assignments.set(owner, operation); - operation.acceptingEvents = true; - try { - owner.url = url; - } finally { - if (assignments.get(owner) === operation) { - assignments.delete(owner); - finishAssignment(operation); - } - } -} -function failSource(operation, error2) { - if (!operation.active()) - return; - if (operation.onError) - operation.onError(error2); - else - console.warn("Failed to initialize ArtPlayer source:", error2); - operation.scope.dispose(); -} function slideDirection(startX, startY, endX, endY) { const dy = startY - endY; const dx = endX - startX; @@ -3473,6 +3590,13 @@ function cssVarMix(art) { } }); } +const revisions = /* @__PURE__ */ new WeakMap(); +function positionRevision(art) { + return revisions.get(art) || 0; +} +function advancePosition(art) { + revisions.set(art, positionRevision(art) + 1); +} function currentTimeMix(art) { const { $video } = art.template; def(art, "currentTime", { @@ -3481,6 +3605,7 @@ function currentTimeMix(art) { const parsed = Number.parseFloat(time2); if (Number.isNaN(parsed)) return; + advancePosition(art); $video.currentTime = clamp(parsed, 0, art.duration); } }); @@ -4939,46 +5064,66 @@ function rectMix(art) { } }); } +function drawFrame(canvas, video) { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const context = canvas.getContext("2d"); + if (!context) + throw new TypeError("Canvas 2D context is unavailable"); + context.drawImage(video, 0, 0); +} +function captureBlobUrl(canvas, resolve, reject) { + canvas.toBlob((blob) => { + try { + if (!blob) + throw new Error("Unable to encode screenshot blob"); + resolve(URL.createObjectURL(blob)); + } catch (error2) { + reject(error2); + } + }); +} function screenshotMix(art) { - const { - notice, - template: { $video } - } = art; - const $canvas = createElement("canvas"); - def(art, "getDataURL", { - value: () => new Promise((resolve, reject) => { + const { notice, template: { $video } } = art; + const canvas = document.createElement("canvas"); + function capture(blob) { + const active2 = captureSource(art); + return new Promise((resolve, reject) => { + const fail = (error2) => { + try { + if (!isClosing(art) && active2()) + notice.show = error2; + } catch (noticeError) { + reject(noticeError); + return; + } + reject(error2); + }; try { - $canvas.width = $video.videoWidth; - $canvas.height = $video.videoHeight; - $canvas.getContext("2d").drawImage($video, 0, 0); - resolve($canvas.toDataURL("image/png")); - } catch (err) { - notice.show = err; - reject(err); + drawFrame(canvas, $video); + if (blob) { + captureBlobUrl(canvas, resolve, fail); + } else { + resolve(canvas.toDataURL("image/png")); + } + } catch (error2) { + fail(error2); } - }) - }); - def(art, "getBlobUrl", { - value: () => new Promise((resolve, reject) => { - try { - $canvas.width = $video.videoWidth; - $canvas.height = $video.videoHeight; - $canvas.getContext("2d").drawImage($video, 0, 0); - $canvas.toBlob((blob) => { - resolve(URL.createObjectURL(blob)); - }); - } catch (err) { - notice.show = err; - reject(err); - } - }) - }); + }); + } + def(art, "getDataURL", { value: () => capture(false) }); + def(art, "getBlobUrl", { value: () => capture(true) }); def(art, "screenshot", { value: async (name) => { + const active2 = captureSource(art); const dataUri = await art.getDataURL(); - const fileName = name || `artplayer_${secondToTime($video.currentTime)}`; - download(dataUri, `${fileName}.png`); - art.emit("screenshot", dataUri); + if (!isClosing(art) && active2()) { + const fileName = name || `artplayer_${secondToTime($video.currentTime)}`; + if (!isClosing(art) && active2()) + download(dataUri, `${fileName}.png`); + if (!isClosing(art) && active2()) + art.emit("screenshot", dataUri); + } return dataUri; } }); @@ -5061,6 +5206,48 @@ function listenSource(scope, art, name, callback, once = true) { }); return guarded; } +const POSITION_TOLERANCE = 0.05; +function positionRestoration(art, target, active2) { + let expected; + let observedSeek = false; + let corrected = false; + let manual = false; + let revision = positionRevision(art); + const manualPosition = () => manual || positionRevision(art) !== revision; + const seeking = () => !!art.template?.$video?.seeking; + return { + restore() { + if (!active2() || manualPosition()) + return; + const previousRevision = positionRevision(art); + art.currentTime = target; + revision = positionRevision(art); + if (revision > previousRevision + 1) + manual = true; + if (!active2()) + return; + expected = art.currentTime; + if (!active2() || manualPosition()) + return; + observedSeek = seeking(); + }, + manual() { + manual = true; + }, + ready() { + if (!active2() || seeking()) + return false; + const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; + if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { + corrected = true; + if (!active2()) + return false; + art.currentTime = expected; + } + return active2() && !seeking(); + } + }; +} function switchSource(art, url, currentTime) { return new Promise((resolve, reject) => { if (isClosing(art) || url === art.url) { @@ -5096,41 +5283,63 @@ function switchSource(art, url, currentTime) { if (!active2()) return; const readiness = scope.child(); + let canPlay = false; + let resuming = false; + let rateRestored = false; + const position = positionRestoration(art, currentTime, active2); + const resume = async () => { + art.aspectRatio = aspectRatio2; + if (!active2()) + return; + if (playing) { + try { + await art.play(); + } catch { + } + } + if (!active2()) + return; + art.notice.show = ""; + settle(); + }; + const resumeWhenReady = () => { + if (!active2() || resuming || !canPlay) + return; + try { + if (art.template?.$video?.seeking) + return; + if (!active2()) + return; + if (!rateRestored) { + rateRestored = true; + art.playbackRate = playbackRate2; + } + if (!position.ready() || !active2() || resuming) + return; + resuming = true; + readiness.dispose(); + void resume().catch(fail); + } catch (error2) { + fail(error2); + } + }; const handlers = { "video:error": fail, "video:loadedmetadata": () => { if (!active2()) return; try { - art.currentTime = currentTime; + position.restore(); } catch (error2) { fail(error2); } }, "video:canplay": () => { - if (!active2()) - return; - readiness.dispose(); - const resume = async () => { - art.playbackRate = playbackRate2; - if (!active2()) - return; - art.aspectRatio = aspectRatio2; - if (!active2()) - return; - if (playing) { - try { - await art.play(); - } catch { - } - } - if (!active2()) - return; - art.notice.show = ""; - settle(); - }; - void resume().catch(fail); - } + canPlay = true; + resumeWhenReady(); + }, + "video:seeked": resumeWhenReady, + "seek": position.manual }; const capture = scope.child(); const queued = []; @@ -5155,7 +5364,7 @@ function switchSource(art, url, currentTime) { } const dispatch = {}; for (const name of names) - dispatch[name] = listenSource(readiness, art, name, handlers[name]); + dispatch[name] = listenSource(readiness, art, name, handlers[name], name !== "video:seeked"); for (const [name, event] of queued) { if (!active2() || readiness.closed) break; @@ -5188,69 +5397,106 @@ function themeMix(art) { } }); } +function thumbnailLayout(option, geometry) { + const { number, column, width, height, scale } = option; + const { imageWidth, videoWidth, videoHeight, progressWidth, position } = geometry; + const columns = Number(column); + const previewWidth = Number(width) * Number(scale) || imageWidth / columns; + const previewHeight = Number(height) * Number(scale) || previewWidth / (videoWidth / videoHeight); + const index = Math.floor(position / (progressWidth / Number(number))); + const row = Math.floor(index / columns); + const cell = index % columns; + const left = position <= previewWidth / 2 ? 0 : position > progressWidth - previewWidth / 2 ? `${progressWidth - previewWidth}px` : `${position - previewWidth / 2}px`; + return { + height: `${previewHeight}px`, + width: `${previewWidth}px`, + backgroundPosition: `-${cell * previewWidth}px -${row * previewHeight}px`, + left + }; +} function thumbnailsMix(art) { - const { - option, - template: { $progress, $video } - } = art; - let timer = null; - let loding = false; - let image = null; + const { option, template: { $progress, $video } } = art; + let scope = getScope(art).child(); + let image; + let loading2 = false; + let control; + let hover; function reset() { - clearTimeout(timer); - timer = null; - loding = false; - image = null; + const previous = scope; + scope = getScope(art).child(); + image = void 0; + loading2 = false; + hover = void 0; + previous.dispose(); } - function showThumbnails(posWidth) { - const $thumbnails = art.controls?.thumbnails; - if (!$thumbnails) + function render() { + const current2 = hover; + const currentScope = scope; + if (!current2 || !image) return; - const { number, column, width, height, scale } = option.thumbnails; - const width2 = width * scale || image.naturalWidth / column; - const height2 = height * scale || width2 / ($video.videoWidth / $video.videoHeight); - const perWidth = $progress.clientWidth / number; - const perIndex = Math.floor(posWidth / perWidth); - const yIndex = Math.ceil(perIndex / column) - 1; - const xIndex = perIndex % column || column - 1; - setStyle($thumbnails, "backgroundImage", `url(${image.src})`); - setStyle($thumbnails, "height", `${height2}px`); - setStyle($thumbnails, "width", `${width2}px`); - setStyle($thumbnails, "backgroundPosition", `-${xIndex * width2}px -${yIndex * height2}px`); - if (posWidth <= width2 / 2) { - setStyle($thumbnails, "left", 0); - } else if (posWidth > $progress.clientWidth - width2 / 2) { - setStyle($thumbnails, "left", `${$progress.clientWidth - width2}px`); - } else { - setStyle($thumbnails, "left", `${posWidth - width2 / 2}px`); + const active2 = () => !isClosing(art) && !currentScope.closed && scope === currentScope && hover === current2 && current2.sourceActive() && art.controls?.thumbnails === current2.element; + if (!active2()) + return; + const position = $progress.clientWidth * current2.percentage; + if (!(position > 0 && position < $progress.clientWidth)) + return; + const styles = { + backgroundImage: `url(${image.src})`, + ...thumbnailLayout(option.thumbnails, { + imageWidth: image.naturalWidth, + videoWidth: $video.videoWidth, + videoHeight: $video.videoHeight, + progressWidth: $progress.clientWidth, + position + }) + }; + for (const [key, value] of Object.entries(styles)) { + if (!active2()) + return; + setStyle(current2.element, key, value); } } - art.on("setBar", async (type, percentage, event) => { - const $thumbnails = art.controls?.thumbnails; + eventSubscriptions(art)("setBar", (type, percentage, event) => { + const element = art.controls?.thumbnails; const { url, scale } = option.thumbnails; - if (!$thumbnails || !url) + if (isClosing(art) || !element || !url || !(type === "hover" || type === "played" && event && isMobile)) return; - const isMobileDragging = type === "played" && event && isMobile; - if (type === "hover" || isMobileDragging) { - if (!image && !loding) { - loding = true; - image = await loadImg(url, scale); - loding = false; - } - if (!image) + if (control !== element) { + const elementScope = entryScope(element); + if (elementScope.closed) return; - const width = $progress.clientWidth * percentage; - if (width > 0 && width < $progress.clientWidth) { - showThumbnails(width); - } + control = element; + elementScope.add(() => { + if (control === element) { + control = void 0; + reset(); + } + }); + } + hover = { percentage, element, sourceActive: captureSource(art) }; + if (image) { + render(); + } else if (!loading2) { + const currentScope = scope; + loading2 = true; + loadThumbnailImage(url, scale, currentScope).then((loaded) => { + if (scope !== currentScope || currentScope.closed) + return; + loading2 = false; + image = loaded; + render(); + }).catch((error2) => { + if (scope === currentScope && !currentScope.closed) { + loading2 = false; + console.warn("ArtPlayer thumbnail load failed:", error2); + } + }); } }); def(art, "thumbnails", { - get() { - return art.option.thumbnails; - }, - set(thumbnails) { - if (thumbnails.url && !art.option.isLive) { + get: () => art.option.thumbnails, + set: (thumbnails) => { + if (!isClosing(art) && thumbnails.url && !art.option.isLive && !isClosing(art)) { art.option.thumbnails = thumbnails; reset(); } @@ -5319,8 +5565,6 @@ function urlMix(art) { const result = typeCallback.call(art, $video, newUrl, art); void Promise.resolve(result).catch((error2) => failSource(operation, error2)); } else { - if (oldUrl) - URL.revokeObjectURL(oldUrl); if (!operation.active()) return; $video.src = newUrl; diff --git a/package.json b/package.json index 36ed14f41..2c75552aa 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "ci:build": "yarn build all && yarn build:i18n && yarn build:ts && yarn build:docs && yarn test:imports", "test:imports": "node --test test/esm.test.js test/i18n.test.js test/ssr.test.js", "typecheck": "node scripts/typecheck.mjs", - "test:unit": "node --test test/playback.test.js test/dash-control.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js", + "test:unit": "node --test test/playback.test.js test/dash-control.test.js test/public-behavior.test.js test/helpers.test.js test/chapter.test.js test/utils.test.js test/resource-scope.test.js test/instance-lifecycle.test.js test/options.test.js test/media-hosts.test.js test/plugins.test.js test/source.test.js test/playback-properties.test.js test/media-events.test.js test/template-resources.test.js test/core-vendor.test.js test/component-resources.test.js test/setting-model.test.js test/setting-layout.test.js test/setting-resources.test.js test/subtitle.test.js test/display-native.test.js test/display-video-fullscreen.test.js test/display-pip.test.js test/display-mini.test.js test/display-sizing.test.js test/display-orientation.test.js test/hotkey.test.js test/listener-registry.test.js test/global-events.test.js test/pointer-events.test.js test/gesture.test.js test/event-scheduling.test.js test/notice.test.js test/fast-forward.test.js test/auto-playback.test.js test/builtin-layers.test.js test/prompt-components.test.js test/screenshot.test.js test/thumbnails.test.js test/progress.test.js", "test": "yarn test:node && yarn test:baseline", "test:browser": "playwright test", "test:browser:install": "playwright install chromium firefox webkit", diff --git a/packages/artplayer/ARCHITECTURE.md b/packages/artplayer/ARCHITECTURE.md index 39b3b97bd..688873f97 100644 --- a/packages/artplayer/ARCHITECTURE.md +++ b/packages/artplayer/ARCHITECTURE.md @@ -4,6 +4,101 @@ ArtPlayer keeps its existing constructor, player mixins, plugins and DOM/CSS hoo The production entry is still `src/index.js`; this document marks actual migrated boundaries rather than describing the entire core as TypeScript. +## Screenshot capture (CORE-19) + +`src/player/screenshotMix.ts` installs the existing immutable getDataURL, +getBlobUrl and screenshot methods. `src/capture/frame.ts` owns synchronous frame +drawing and the asynchronous canvas Blob callback boundary. A capture still draws +before returning its Promise; moving drawing behind await would select a later +video frame. PNG format, extracted-method binding, default filename timing and +download-before-event ordering remain unchanged for live operations. + +The public getBlobUrl caller owns URL.revokeObjectURL. Player destruction must not +invalidate a returned URL that a consumer still uses. Asynchronous null Blob or +URL allocation failure now rejects the capture Promise instead of escaping the +callback and leaving it pending. Notice setter failures also reject. Destruction +and source replacement suppress stale notices and screenshot download/event +effects, while an already captured data string or Blob URL still settles normally. +The toolbar consumes its internal rejection after the capture reports a notice; +public calls continue to reject for callers to handle. + +Use test/screenshot.test.js, test/types/screenshot.ts and the browser screenshot +spec for capture changes. Browser checks decode real video frames, inspect PNG +pixels, and use a second hostname without CORS headers for native SecurityError. +Installed-package acceptance is recorded in refactor/changes/ for this task. + +## Thumbnail previews and image loading (CORE-19) + +`src/player/thumbnailsMix.ts` preserves the thumbnails property, configuration +object identity, live restrictions and control DOM. It owns one image cache scope +per configuration, links it to the current thumbnail control and removes its setBar +subscription on destruction. Replacement, control removal and destruction cancel +loading; obsolete completions cannot render. Loading failures release the pending +state so a later interaction may retry. Failures are reported with console.warn +instead of escaping an internal event callback as an unhandled rejection. + +The latest hover position wins while an image is pending. A source change prevents +rendering old hover coordinates but does not invalidate an unchanged sprite cache; +a new interaction may use that image. Each style write checks the active control, +configuration and source so reentrant DOM callbacks stop the remaining writes. + +`src/thumbnails/layout.ts` contains the sprite and preview geometry. Dimensions, +scale fallback, edge placement and excluded progress endpoints remain unchanged. +The old row/cell calculation was incorrect at exact column multiples and produced +invalid CSS at cell zero. The corrected zero-based crop matches +artplayer-tool-thumbnail's x/index-modulo-column and y/floor-index-over-column +generation. Tests explicitly distinguish this display fix from published behavior. + +`src/image/load.ts` implements both image consumers without duplicating decoding: +public utils.loadImg still returns Promise, and the caller owns +the src Blob URL of a scaled result. The internal loadThumbnailImage receives a +ResourceScope; cancellation fulfills with undefined, and its generated URLs remain +owned until replacement/removal/destroy. No caller-supplied image URL is revoked. +Every request clears load/error handlers; failed scaled decoding revokes its Blob. +Null canvas encoding and asynchronous allocation errors reject public calls. The +public helper is re-exported through utils/dom.js to keep the existing utils shape; +loadThumbnailImage is not added to the public utils barrel. + +Use test/thumbnails.test.js and test/types/thumbnails.ts for state, cancellation, +reentry and API types. The browser thumbnails spec uses the numbered +test/browser/media/thumbnail-grid.svg for crop checks and actual image decoding. +Transient retry uses a no-store 503 response; browser caching of malformed successful +responses is not claimed to be controlled by the player. Source-built checks are +intermediate evidence; use the task's final tarball/browser evidence for acceptance. + +## Progress and quality restoration (CORE-19) + +control/progress/interactions.ts captures the control entry, source and action for +each click or drag. Geometry and setBar callbacks can synchronously remove the +entry, destroy the player, start a new source or start a newer action. Check those +boundaries before emitting or seeking. A source change ends the old drag; a new +mousedown can start a new one. position.ts retains endpoint clamping and the live +progress event before seek, with an optional internal activity predicate. + +source/restore-position.ts owns the paused quality position restoration. Native +canplay may arrive while seeking; switch.ts waits for seek completion, restores +rate once and checks the accepted, clamped position. A demonstrated native seek +miss receives at most one correction, allowing 0.05 seconds for media clock +rounding. It does not loop until success. The seeked listener remains until the +correction finishes or the source operation is cancelled. Explicit public seek +supersedes automatic position restoration; reentrant completion cannot resume +twice. media/position-revision.ts also tracks legal public currentTime writes; +a consumer assigning currentTime directly during loading supersedes the automatic +restoration, including writes before metadata. Invalid NaN assignments remain no-ops. +Source cancellation still settles pending work and removes all listeners. +Use test/source.test.js, test/progress.test.js and the browser source and +progress-quality specs. Keep native media events in evidence when changing this +sequence; the original rate-interruption hypothesis was not sufficient to explain +the observed first-seek miss. + +urlMix.ts receives media URLs from consumers/adapters and does not revoke them on +replacement. Their creator owns release, including Blob media sources. Screenshot +and public scaled-image URLs similarly belong to callers; internal thumbnail and +subtitle URLs have explicit owned scopes. Real Blob-video decoding is separately +capability-tested: this Windows WebKit runtime rejects the local MP4 and WebM Blob +samples even without ArtPlayer. Do not turn URL readability checks into claims of +native decoding or Apple-device support; see refactor/environment-matrix.md. + ## Builtins and prompts (CORE-18) `src/notice.ts` owns the notice timer and DOM visibility. Its minimal host, private @@ -1001,7 +1096,7 @@ continuations. Direct assignment failures are reported with console.warn; switch callers receive the original rejection. `playMix.ts` captures the current source: its native result/rejection is preserved, while obsolete notice/event/mutex effects are suppressed. CORE-10 migrates playback properties and CORE-11 owns reconnect -generations; object URL ownership remains CORE-19 work. +generations; CORE-19 removes revocation of caller-owned media URLs on replacement. `test/source.test.js` checks cancellation, reentry, synchronous events and cleanup; `test/browser/source.spec.js` compares published/candidate real-media switching and diff --git a/packages/artplayer/dist/artplayer.js b/packages/artplayer/dist/artplayer.js index 4f492346d..12af87024 100644 --- a/packages/artplayer/dist/artplayer.js +++ b/packages/artplayer/dist/artplayer.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),l(()=>i.finalizers.dispose()),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function w(t,e){return{on:(r,n)=>{b(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const x=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),k=/^(?:(?!chrome|android).)*safari/i.test(x),$=/iPad|iPhone|iPod/i.test(x)&&!window.MSStream,E=$||x.includes("Macintosh")&&navigator.maxTouchPoints>=1,C=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(x)||E,T="undefined"!==typeof window&&"undefined"!==typeof document;function L(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function S(t,e=document){return e.querySelector(t)}function P(t,e){return t.classList.add(e)}function M(t,e){return t.classList.remove(e)}function z(t,e){return t.classList.contains(e)}function A(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function R(t,e,r){return t.style[e]=r,t}function O(t,e){for(const r in e)R(t,r,e[r]);return t}function I(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){I(t).forEach(t=>M(t,e)),P(t,e)}function N(t,e,r="top"){C||(t.setAttribute("aria-label",e),P(t,"hint--rounded"),P(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function W(t){return document.createElement(t)}function V(t="",e=""){const r=W("i");return P(r,"art-icon"),P(r,`art-icon-${t}`),A(r,e),r}function Y(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function B(t){return t.getBoundingClientRect()}function H(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:P,append:A,assToVtt:ut,capitalize:Q,clamp:J,createElement:W,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:j,getExt:K,getIcon:V,getRect:B,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:z,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:$,isIOS13:E,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:C,isSafari:k,loadImg:H,mergeDeep:ct,query:S,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:M,replaceElement:F,secondToTime:tt,setStyle:R,setStyleText:L,setStyles:O,siblings:I,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:Y,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:N,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:x,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return A(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Ct=new WeakSet;class Tt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return z(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?P(e,r):M(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=g(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){P(t,`art-${r}`),P(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):A(e,t),i.html&&A(t,i.html),i.style&&O(t,i.style),i.tooltip&&N(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{y(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Ct.has(e)){Ct.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Ct.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Tt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),C||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=w(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=S('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=B(e),{height:c,width:d}=B(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),O(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}function zt(t,e){const{$progress:r}=t.template,{left:n}=B(r),o=J((C?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function At(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=zt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Rt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=w(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?R(h,"left",0):o>e.clientWidth-a/2?R(h,"left",e.clientWidth-a+"px"):R(h,"left",o-a/2+"px")}r.indicator?A(u,r.indicator):R(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&C;if("loaded"===r&&R(c,"width",100*n+"%"),"hover"===r&&(R(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?R(h,"left",0):n>e.clientWidth-i/2?R(h,"left",e.clientWidth-i+"px"):R(h,"left",n-i/2+"px")}(a):f(a),0===n?M(o,"art-progress-hover"):P(o,"art-progress-hover")),"played"===r&&(R(d,"width",100*n+"%"),R(u,"left",100*n+"%")),m){P(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{M(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Ot(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Rt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=w(t,e);if(!C){let e=!1;i(r,"click",e=>{e.target!==n&&At(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=zt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=zt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function It(t){const{option:e}=t.art;e.isLive||t.add(Ot({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){R(a,"display","flex"),R(s,"display","none")}function c(){R(a,"display","none"),R(s,"display","flex")}N(a,i.get("Play")),N(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=B(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)R(i,"display","none"),R(a,"display","flex"),R(h,"top","100%"),R(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;R(i,"display","flex"),R(a,"display","none"),R(h,"top",100-t+"%"),R(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),C)R(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:C?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=w(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!C&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{N(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{N(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(N(t,i.get("Exit Web Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Web Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);R(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(N(t,i.get("Exit Fullscreen")),R(a,"display","none"),R(s,"display","inline-flex")):(N(t,i.get("Fullscreen")),R(a,"display","inline-flex"),R(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rNt.get(t).option.selector}),it(t,"$control_item",{get:()=>Nt.get(t).item}),it(t,"$control_value",{get:()=>Nt.get(t).value})),Nt.set(t,e)}function Ft(t,e){t.innerHTML=e}function Wt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;P(n,"art-control-selector");const l=document.createElement("div");P(l,"art-selector-value"),A(l,r.html),n.textContent="",A(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return _t.set(t,e),()=>{_t.get(t)===e&&_t.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Ft(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Vt extends Tt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;g(t,n);const{on:o}=w(t,n);o("mousemove",()=>{C||(this.show=!0)}),o("click",()=>{C?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(M(r,"art-hide-cursor"),P(r,"art-hover"),this.timer=Date.now()):(P(r,"art-hide-cursor"),M(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=w(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){It(this)}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Ft(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Yt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),h(t))return;(!C||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;C?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const Bt=new WeakMap,Ht=new WeakMap,jt=new WeakMap;function qt(t){return jt.get(t)||u(t)}function Ut(t){const e=Bt.get(t),r=jt.get(t);return()=>Bt.get(t)===e&&(!e||e.active())&&jt.get(t)===r&&(!r||!r.closed)}function Xt(t){const e=jt.get(t),r=u(t).child(),n=r.child();jt.set(t,r),r.add(()=>{jt.get(t)===r&&jt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&Bt.get(t)===o};return Bt.set(t,o),n.add(()=>{Bt.get(t)===o&&Bt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function Gt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Kt(t,e,r){Ht.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Ht.get(t)===e&&(Ht.delete(t),Gt(e))}}function Zt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),u(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(h(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:Ut(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{At(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Yt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(P(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!C||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=u(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||h(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),C||this.init()}init(){const t=this.art;if(h(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!h(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>V(r,e[r])})}}const me=new WeakMap;class ge extends Tt{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),C||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),h(this.art)||t.revision!==e)return;const r=u(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!h(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Tt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{R(i,"display","none"),R(s,"display",null),h(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,p(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),h(t)||n.proxy(e.$state,"click",()=>{h(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),u(t).add(()=>{t.off("destroy",e)}),u(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(h(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!h(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(P(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(h(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",h(this.art)||e.revision!==t||M(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else M(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ee(t,e){if(!$e(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return $e(r)?r:void 0}function Ce(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!$e(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Te(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Le(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function Se(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=qt(t),l=0;return{reset(){l=0,a?.dispose(),M(i,"art-error")},loadStart(){M(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=qt(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!h(t)&&!p.closed&&d===qt(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Pe(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Se(t);!function(t,e){Te(t,"video:canplay",()=>{e.reset(),Le(t,[["loading",!1]])}),Te(t,"video:canplay",()=>{Le(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Te(t,"video:ended",()=>{if(e.loop){const e=Ut(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Le(t,[["controls",!1],["mask",!1]],e)}else Le(t,[["controls",!0],["mask",!0]])})}(t),Te(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Te(t,"video:loadedmetadata",()=>{t.emit("resize"),C&&Le(t,[["loading",!1],["controls",!0],["mask",!0]])}),Te(t,"video:loadstart",()=>{e.loadStart(),Le(t,[["loading",!0],["mask",!1],["controls",!0]])}),Te(t,"video:pause",()=>{Le(t,[["controls",!0],["mask",!0]])}),Te(t,"video:play",()=>{Le(t,[["mask",!1]]),h(t)||R(r,"display","none")}),Te(t,"video:playing",()=>Le(t,[["mask",!1]])),Te(t,"video:progress",()=>{t.playing&&Le(t,[["loading",!1]])}),Te(t,"video:seeked",()=>Le(t,[["loading",!1],["mask",!0]])),Te(t,"video:seeking",()=>Le(t,[["loading",!0],["mask",!1]])),Te(t,"video:timeupdate",()=>Le(t,[["mask",!1]])),Te(t,"video:waiting",()=>Le(t,[["loading",!0],["mask",!1]]))}(t,e)}const Me=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],ze=(()=>{if("undefined"===typeof document)return!1;const t=Me[0],e={};for(const r of Me){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Ae={change:ze.fullscreenchange,error:ze.fullscreenerror},Re={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Re.off("change",o),r()};Re.on("change",o);const i=t[ze.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Re.isFullscreen)return void t();const r=()=>{Re.off("change",r),t()};Re.on("change",r);const n=document[ze.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Re.isFullscreen?Re.exit():Re.request(t,e),onchange(t){Re.on("change",t)},onerror(t){Re.on("error",t)},on(t,e){const r=Ae[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Ae[t];r&&document.removeEventListener(r,e,!1)},raw:ze};function Oe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Re,{isFullscreen:{get:()=>Boolean(document[ze.fullscreenElement])},element:{enumerable:!0,get:()=>document[ze.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[ze.fullscreenEnabled])}});const Ie=new WeakMap;function _e(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Ne(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ie.get(t);if(!n){n=new WeakMap,Ie.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),_e(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),_e(i))}function De(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&Ne(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){Ie.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&Ne(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Fe(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return Ie.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();f=!0,d=c;const s=De(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const We=new WeakSet;function Ve(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Ye(t){We.delete(t),t.removeEventListener("webkitbeginfullscreen",Be),t.removeEventListener("webkitpresentationmodechanged",Be)}function Be(t){if(We.has(this)&&Ve(this,"webkitbeginfullscreen"===t.type)){Ye(this);try{this.webkitExitFullscreen?.()}catch{}}}function He(t){We.add(t),t.addEventListener("webkitbeginfullscreen",Be),t.addEventListener("webkitpresentationmodechanged",Be)}function je(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=Ve(e),i=o,a=!1,s=0;const l=()=>Ve(e,n);function c(r){if(h(t)||(c=e,We.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&He(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(Ye(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,He(e)),l()&&e.webkitExitFullscreen()}}}function qe(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Re.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Oe(t,e.requestFullscreen,void 0),exit:()=>Oe(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Fe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",je(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function Ue(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Xe({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Ge(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Xe(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:Ue(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Ke(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function Ze(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function Je(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Ke(i.left,i.top,Ze(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function Qe(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Xe(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=Ue(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=Je(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Ke(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,Ze(o.element));if(h(t)||u!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const tr=new WeakSet,er=t=>"picture-in-picture"===t.webkitPresentationMode;function rr(t){tr.delete(t),t.removeEventListener("webkitpresentationmodechanged",nr),t.removeEventListener("enterpictureinpicture",nr)}function nr(){if(tr.has(this)&&er(this)){rr(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function or(t){tr.add(t),t.addEventListener("webkitpresentationmodechanged",nr),t.addEventListener("enterpictureinpicture",nr)}function ir(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=u(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&a||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||tr.has(e))return;const s=er(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||er(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&or(e),er(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&er(e),set(r){if(h(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(rr(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,or(e)),er(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||er(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function ar(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&_t.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}function sr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function lr(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const i=Xt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),u={"video:error":d,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){d(e)}},"video:canplay":()=>{if(!c())return;p.dispose();(async()=>{if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}})().catch(d)}},h=a.child(),f=[],m=Object.keys(u);for(const e of m)sr(h,t,e,t=>{i.acceptingEvents&&f.push([e,t])},!1);if(Kt(t,i,e),!c())return;if(t.notice.show="",!c())return;const g=()=>{if(h.dispose(),!e)return void l();const r={};for(const e of m)r[e]=sr(p,t,e,u[e]);for(const[t,e]of f){if(!c()||p.closed)break;r[t](e)}f.length=0};i.assigned?g():i.onAssigned=g}catch(p){d(p)}})}function cr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",async(o,s,l)=>{const c=t.controls?.thumbnails,{url:d,scale:p}=e.thumbnails;if(!c||!d)return;if("hover"===o||"played"===o&&l&&C){if(a||i||(i=!0,a=await H(d,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-u/2?R(i,"left",r.clientWidth-u+"px"):R(i,"left",o-u/2+"px")}(o)}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function dr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=Ht.get(t);return Ht.delete(t),e||Xt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;sr(l,t,"video:canplay",()=>{c=!d}),sr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Zt(o,t))}else{if(i&&URL.revokeObjectURL(i),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||sr(o.scope,t,"video:canplay",e)}}catch(i){Zt(o,i)}finally{Gt(o)}}})}class pr{constructor(t){dr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=Ut(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),function(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=J(n,0,t.duration))}})}(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>lr(t,e,0);it(t,"switchQuality",{value:e=>lr(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ee({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,h(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=W("canvas");it(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),it(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),it(t,"screenshot",{value:async e=>{const n=await t.getDataURL();return Z(n,`${e||`artplayer_${tt(r.currentTime)}`}.png`),t.emit("screenshot",n),n}})}(t),qe(t),Ge(t),ir(t),function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!$e(o))return;const i=B(e),a=Ee(i,o.width/o.height);a&&!h(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>B(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",Qe(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){R(e,"backgroundImage",`url(${t})`)}})}(t),Ce(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),ar(t),cr(t),Pe(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&R(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const ur=new WeakMap,hr="art-auto-orientation-fullscreen";function fr(t){if(ur.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const mr="art-auto-orientation",gr=["width","height","transform-origin","transform"];function vr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return $e(t)&&$e(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(mr);r.classList.remove(mr),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=gr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(mr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{h(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(hr),t&&(t.cancelled=!0,fr(t),t.settled&&ur.get(t.orientation)===t&&ur.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&ur.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,ur.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&ur.get(a)===s,c=e=>{s.settled=!0;const o=l();ur.get(a)===s&&ur.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(hr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(hr):(fr(s),ur.get(a)===s&&ur.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function yr(t){return t.get("times")||{}}function br(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||h(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=v(a);let p,u=0;const f=()=>{const r=++u;if(p?.dispose(),d.closed||h(t)||u!==r)return;const f=d.child();p=f;const m=()=>p===f&&!f.closed&&!h(t);f.add(()=>{p===f&&(p=void 0,R(a,"display","none"))});const g=qt(t).add(()=>{f.dispose()});f.add(()=>{g()});const v=yr(n)[t.option.id||t.option.url];if(!m())return;if(R(a,"display","none"),!m()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!m())return;if(R(a,"display","flex"),!m())return;const y=`${e.get("Last Seen")} ${tt(v)}`;if(!m())return;if(s.textContent=y,!m())return;const b=e.get("Jump Play");if(!m())return;if(l.textContent=b,!m())return;const w=(e,r)=>{const n=t.events.proxy(e,"click",()=>{m()&&r()});f.add(()=>{t.events.remove(n)})};if(w(c,()=>{R(a,"display","none")}),!m())return;if(w(l,()=>{t.seek=v,m()&&(G(t.play()),m()&&(R(i,"display","none"),m()&&R(a,"display","none")))}),!m())return;let x=()=>{},k=!1;const $=()=>{!k&&m()&&(k=!0,x(),Pt(f,()=>{m()&&R(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{b(t,a,"ready",f),b(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=yr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;h(t)||(o.length>i&&delete n[o[0]],n[a]=s,h(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return yr(e)},clear:()=>e.del("times"),delete(t){const r=yr(e);return delete r[t],e.set("times",r),r}}}function wr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||h(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:qt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||M(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||h(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||h(t))return;t.playbackRate=r,e!==i||i.scope.closed||h(t)||P(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function xr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=wr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return z(r,"art-fast-forward")}}}function kr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return z(n,"art-lock")}function i(){h(t)||(P(n,"art-lock"),h(t)||(t.isLock=!0,h(t)||t.emit("lock",!0)))}function a(){h(t)||(M(n,"art-lock"),h(t)||(t.isLock=!1,h(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=v(e);if(n.closed||h(t))return;const o=ft(e,r.lock);if(n.closed||h(t))return;const i=ft(e,r.unlock);n.closed||h(t)||(R(o,"display","none"),b(t,e,"lock",e=>{h(t)||(R(o,"display",e?"inline-flex":"none"),n.closed||h(t)||R(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function $r(t){return oe(t)("control",e=>{e?M(t.template.$player,"art-mini-progress-bar"):P(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Er{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add($r),!h(t.art)&&e.lock&&C&&t.add(kr),h(t.art)||!e.autoPlayback||e.isLive||t.add(br),!h(t.art)&&e.autoOrientation&&C&&t.add(vr),!h(t.art)&&e.fastForward&&C&&!e.isLive&&t.add(xr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Cr=new WeakMap;function Tr(t){return!t.closed&&!Cr.get(t)}function Lr(t){Cr.set(t,(Cr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Cr.get(t)||1)-1;r?Cr.set(t,r):Cr.delete(t)}}const Sr=new WeakMap,Pr=new WeakMap,Mr=["$parent","$parents","$option","$events","$formatted"];function zr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Sr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Sr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function Ar(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Rr(t){const e=Sr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Or(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>Vr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),Wr.set(r,o),Dr.set(e,r),Fr.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function qr(t,e,r,n,o,i){const a=i||Br(e);if(!Tr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(Tr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Tr(a)||h(t)?t.events.remove(s):(Rr(e).events.push(s),i&&i!==Dr.get(e)&&i.add(()=>{const r=Rr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Ur(t,e,r,n){const o=Br(e);if(!Tr(o)||h(t))return;const i=(...e)=>{if(Tr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Xr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/a.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||C||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const Gr=new WeakMap;function Kr(t){Gr.delete(t)}const Zr=new WeakMap;function Jr(t,e){e?Zr.set(t,e):Zr.delete(t)}function Qr(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=Zr.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),Jr(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const tn=new WeakMap;async function en(t,e,r,n,o,i,a,s){try{const l=Br(e),c=Br(i),d=(tn.get(i)||0)+1;tn.set(i,d);const p=()=>Tr(l)&&Tr(c)&&!h(t.art)&&tn.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function rn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const nn=new WeakMap;function on(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function an(t){nn.get(t)?.()}function sn(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);Kr(r),an(r);const n=Qr(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?rn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=jr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Lr(_r(t)))}catch(l){try{on([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,on([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,on([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Nr(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{on([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&nn.get(r)===m;for(const u of d.items)nn.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)nn.get(t)===m&&nn.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const ln=new WeakMap;function cn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",A(r,t)}})}function dn(t,e,r=!1){const n=function(t){const e=nn.get(t);return()=>!e||nn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Dr.get(e);(!n||Tr(n)||n.closed)&&Hr(t,e);const o=r.child();return Dr.set(e,o),Fr.set(e,r),Wr.set(o,Rr(e).events),o.add(()=>{Vr(t,Wr.get(o))}),o}(t.art,e,_r(o)),d=()=>Tr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(Jr(e),P(p,"art-setting-item"),R(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=A(p,'
'),u=A(p,'
'),f=document.createElement("div");switch(P(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;A(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;A(f,t)}else A(f,s.check)}if(A(n,f),!d())return;cn(e,"icon",f);const m=document.createElement("div");P(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;A(m,g),A(n,m),cn(e,"html",m);const v=document.createElement("div");P(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(A(v,y),A(u,v),cn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=A(t,s.switchOn),n=A(t,s.switchOff),o=e.switch;if(!d())return;R(o?n:r,"display","none"),A(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;Jr(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(R(n,"display","none"),R(r,"display",null)):(R(n,"display",null),R(r,"display","none"))}});break}case"range":{const t=document.createElement("div");P(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",A(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}P(r,"art-setting-range"),A(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;Jr(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");P(t,"art-setting-item-right-icon"),A(t,s.arrowRight),A(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Br(e),a=(t,r,n)=>qr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>en(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>en(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return en(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&P(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>en(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):A(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function pn(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!Tr(_r(r)))return;const n=(ln.get(t)||0)+1;ln.set(t,n);const o=()=>ln.get(t)===n&&!h(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&_(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!_r(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Ir.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;P(r,"art-setting-panel"),A(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Pr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Ur(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Ur(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Or(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&_(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Pr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nRr(t).parent},$parents:{get:()=>Rr(t).parents},$option:{get:()=>Rr(t).option},$events:{get:()=>Rr(t).events},$formatted:{get:()=>!0}}),Sr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Or(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Xr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Nr(n)}catch(i){r.push(i)}}try{Hr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{Kr(t),an(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return sn(this,t)}add(t,e=this.option){if(h(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};Gr.set(t,e);const r=()=>Gr.get(t)===e;return{current:r,finish(){r()&&Gr.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");R(i,"height",`${o}px`),P(i,"art-setting-item"),P(i,"art-setting-item-back");const a=A(i,'
'),s=document.createElement("div");P(s,"art-setting-item-left-icon"),A(s,n),A(a,s),A(a,e.$parent.html),qr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),_r(r)),A(r,i)}(this,t)}createItem(t,e=!1){dn(this,t,e)}render(t=this.option){pn(this,t)}}class fn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const mn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class gn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const vn=new WeakMap;function yn(t){return vn.get(t)}function bn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const wn=Tt;class xn extends wn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return vn.set(t,n),r.add(()=>{bn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?O(r,t):R(r,t,e)}update(){!function(t){const e=yn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=yn(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=yn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&bn(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=yn(this),r=function(t){const e=t.request,r=new gn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const kn=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class $n{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=S(e.container),X(this.$container,`No container element found by ${e.container}`)),X(Y(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=d.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=p(t);o.rollback=r,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,rn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return kn}query(t){return S(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=$n.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&P(this.$player,"art-backdrop"),C&&P(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":P(this.$player,"art-destroy")}}const En=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Cn{on(t,e,r){const n=this.e||(this.e={});let o=En(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(En(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=En(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new $n(this),this.events=new ae(this),this.storage=new fn(this),this.icons=new fe(this),this.i18n=new ue(this),this.notice=new ke(this),this.player=new pr(this),this.layers=new ve(this),this.controls=new Vt(this),this.contextmenu=new Lt(this),this.subtitle=new xn(this),this.info=new ge(this),this.loading=new ye(this),this.hotkey=new de(this),this.mask=new be(this),this.setting=new hn(this),this.plugins=new Er(this),u(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Sn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Sn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&Ln.push(this)}catch(r){try{f(this,Ln,!0,Sn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Ln}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return Cn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return $n.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:k?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){f(this,Ln,t,Sn.REMOVE_SRC_WHEN_DESTROY)}}return Sn.STYLE=mn,Sn.DEBUG=!1,Sn.CONTEXTMENU=!0,Sn.NOTICE_TIME=2e3,Sn.SETTING_WIDTH=250,Sn.SETTING_ITEM_WIDTH=200,Sn.SETTING_ITEM_HEIGHT=35,Sn.RESIZE_TIME=200,Sn.SCROLL_TIME=200,Sn.SCROLL_GAP=50,Sn.AUTO_PLAYBACK_MAX=10,Sn.AUTO_PLAYBACK_MIN=5,Sn.AUTO_PLAYBACK_TIMEOUT=3e3,Sn.RECONNECT_TIME_MAX=5,Sn.RECONNECT_SLEEP_TIME=1e3,Sn.CONTROL_HIDE_TIME=3e3,Sn.DBCLICK_TIME=300,Sn.DBCLICK_FULLSCREEN=!0,Sn.MOBILE_DBCLICK_PLAY=!0,Sn.MOBILE_CLICK_PLAY=!1,Sn.AUTO_ORIENTATION_TIME=200,Sn.INFO_LOOP_TIME=1e3,Sn.FAST_FORWARD_VALUE=3,Sn.FAST_FORWARD_TIME=1e3,Sn.TOUCH_MOVE_RATIO=.5,Sn.VOLUME_STEP=.1,Sn.SEEK_STEP=5,Sn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Sn.ASPECT_RATIO=["default","4:3","16:9"],Sn.FLIP=["normal","horizontal","vertical"],Sn.FULLSCREEN_WEB_IN_BODY=!0,Sn.LOG_VERSION=!0,Sn.USE_RAF=!1,Sn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=Sn,L("artplayer-style",mn),setTimeout(()=>{Sn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Sn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Sn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new l,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof s?t.push(...e.errors):t.push(e)}if(t.length)throw new s(t)}}const c=new WeakMap,d=new WeakMap;function p(t){const e=c.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function u(t){return p(t).scope}function h(t){const e=p(t);return e.destroying||e.scope.closed}function f(t,e,r,n,o=!1){const i=p(t);if(i.destroying||i.scope.closed)return;i.destroying=!0;const a=[],l=t=>{try{t()}catch(e){a.push(...e instanceof s?e.errors:[e])}};n&&t.template?.$video&&l(()=>t.reset()),l(()=>i.scope.dispose()),l(()=>t.template?.destroy(r));const c=e.indexOf(t);-1!==c&&e.splice(c,1),t.isDestroy=!0,o||(i.releaseContainer?.(),i.releaseContainer=void 0),l(()=>t.emit("destroy")),l(()=>i.finalizers.dispose()),o&&i.rollback&&l(i.rollback),i.rollback=void 0,i.releaseContainer?.(),i.releaseContainer=void 0;for(const s of a.slice(1))console.warn("Additional ArtPlayer cleanup failure:",s);if(a.length)throw a[0]}const m=new WeakMap;function g(t,e){const r=u(t).child();return m.set(e,r),r}function v(t){const e=m.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function y(t){m.get(t)?.dispose()}function b(t,e,r,n){const o=v(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function w(t,e){return{on:(r,n)=>{b(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=v(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const x=globalThis?.CUSTOM_USER_AGENT??("undefined"!==typeof navigator?navigator.userAgent:""),k=/^(?:(?!chrome|android).)*safari/i.test(x),$=/iPad|iPhone|iPod/i.test(x)&&!window.MSStream,E=$||x.includes("Macintosh")&&navigator.maxTouchPoints>=1,C=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(x)||E,T="undefined"!==typeof window&&"undefined"!==typeof document;function L(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new l;let a=!1,s=()=>{};function c(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function d(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;p(n,()=>{if(!e||1===e)return void d(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;p(l,()=>d(l)),i.closed||(l.src=e)}catch(e){c(e)}}))}),i.closed||(n.src=t)}catch(u){c(u)}function p(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){c(u)}},e.onerror=()=>c(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}function S(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function P(t,e=document){return e.querySelector(t)}function M(t,e){return t.classList.add(e)}function z(t,e){return t.classList.remove(e)}function A(t,e){return t.classList.contains(e)}function R(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function O(t,e,r){return t.style[e]=r,t}function I(t,e){for(const r in e)O(t,r,e[r]);return t}function N(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function _(t,e){N(t).forEach(t=>z(t,e)),M(t,e)}function W(t,e,r="top"){C||(t.setAttribute("aria-label",e),M(t,"hint--rounded"),M(t,`hint--${r}`))}function D(t,e){return j(t).includes(e)}function F(t,e){return e.parentNode.replaceChild(t,e),t}function V(t){return document.createElement(t)}function Y(t="",e=""){const r=V("i");return M(r,"art-icon"),M(r,`art-icon-${t}`),R(r,e),r}function B(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function H(t){return t.getBoundingClientRect()}function j(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function q(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class U extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function X(t,e){if(!t)throw new U(e);return t}function G(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function K(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function Z(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function J(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function Q(t){return t.charAt(0).toUpperCase()+t.slice(1)}function tt(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const et={"&":"&","<":"<",">":">","'":"'",'"':"""},rt={"&":"&","<":"<",">":">","'":"'",""":'"'},nt=/(&|<|>|'|")/g;function ot(t){return t.replace(/[&<>'"]/g,t=>et[t]||t)}const it=Object.defineProperty,{hasOwnProperty:at}=Object.prototype;function st(t,e){return at.call(t,e)}function lt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function ct(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?ct(o,i):i,it(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function dt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function pt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function ut(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const ht=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:U,addClass:M,append:R,assToVtt:ut,capitalize:Q,clamp:J,createElement:V,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:it,download:Z,errorHandle:X,escape:ot,get:lt,getComposedPath:j,getExt:K,getIcon:Y,getRect:H,getSafeAreaInsets:q,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:st,hasClass:A,includeFromEvent:D,inverseClass:_,isBrowser:T,isIOS:$,isIOS13:E,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:C,isSafari:k,loadImg:function(t,e){return L(t,e,void 0)},mergeDeep:ct,query:P,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:z,replaceElement:F,secondToTime:tt,setStyle:O,setStyleText:S,setStyles:I,siblings:N,silencePromise:G,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:dt,supportsFlex:B,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:W,unescape:function(t){return t.replace(nt,t=>rt[t]||t)},userAgent:x,vttToBlob:pt},Symbol.toStringTag,{value:"Module"}));function ft(t,e){return R(t,e)}function mt(t,e){return e.querySelector(t)}const gt="array",vt="boolean",yt="string",bt="number",wt="object",xt="function";function kt(t,e,r){return X(e===yt||e===bt||t instanceof Element,`${r.join(".")} require '${yt}' or 'Element' type`)}const $t={html:kt,disable:`?${vt}`,name:`?${yt}`,index:`?${bt}`,style:`?${wt}`,click:`?${xt}`,mounted:`?${xt}`,tooltip:`?${yt}|${bt}`,width:`?${bt}`,selector:`?${gt}`,onSelect:`?${xt}`,switch:`?${vt}`,onSwitch:`?${xt}`,range:`?${gt}`,onRange:`?${xt}`,onChange:`?${xt}`},Et={id:yt,container:kt,url:yt,poster:yt,type:yt,theme:yt,lang:yt,volume:bt,isLive:vt,muted:vt,autoplay:vt,autoSize:vt,autoMini:vt,loop:vt,flip:vt,playbackRate:vt,aspectRatio:vt,screenshot:vt,setting:vt,hotkey:vt,pip:vt,mutex:vt,backdrop:vt,fullscreen:vt,fullscreenWeb:vt,subtitleOffset:vt,miniProgressBar:vt,useSSR:vt,playsInline:vt,lock:vt,gesture:vt,fastForward:vt,autoPlayback:vt,autoOrientation:vt,airplay:vt,proxy:`?${xt}`,plugins:[xt],layers:[$t],contextmenu:[$t],settings:[$t],controls:[{...$t,position:(t,e,r)=>{const n=["top","left","right"];return X("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}}],quality:[{default:`?${vt}`,html:yt,url:yt}],highlight:[{time:bt,text:yt}],thumbnails:{url:yt,number:bt,column:bt,width:bt,height:bt,scale:bt},subtitle:{url:yt,name:yt,type:yt,style:wt,escape:vt,encoding:yt,onVttLoad:xt},moreVideoAttr:wt,i18n:wt,icons:wt,cssVar:wt,customType:wt},Ct=new WeakSet;class Tt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return A(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?M(e,r):z(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t;if(h(this.art))return;if(e.html=e.html||"",o(e,$t),!this.$parent||!this.name||e.disable)return;const r=e.name||`${this.name}${this.id}`,n=this.cache;X(!n.has(r),`Can't add an existing [${r}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=g(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,r);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){M(t,`art-${r}`),M(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):R(e,t),i.html&&R(t,i.html),i.style&&I(t,i.style),i.tooltip&&W(t,i.tooltip)}(i,this.$parent,this.name,r,this.id,e),a.closed)return;if(e.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),e.click.call(this.art,this,t))});s.push(t)}if(e.selector&&["left","right"].includes(e.position)&&this.selector(e,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,r,i),c=!0,n.set(r,{$ref:i,events:s,option:e}),e.mounted&&e.mounted.call(this.art,i),i}catch(d){try{y(i)}catch(p){console.warn("ArtPlayer component cleanup failed:",p)}throw n.get(r)?.$ref===i&&n.delete(r),c&&this[r]===i&&(l?Object.defineProperty(this,r,l):delete this[r]),i.remove(),d}}remove(t){X(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Ct.has(e)){Ct.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{y(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Ct.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Lt extends Tt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,g(t,this.$parent),C||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=w(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return{...t,html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="1"]',t);n&&_(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&_(r,"art-current")})}}}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return{...t,html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="default"]',t);n&&_(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(Q(t))}`).join("");return{...t,html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=w(e,t),n=P('[data-value="normal"]',t);n&&_(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&_(r,"art-current")})}}}}({name:"flip",index:30})),this.add(function(t){return e=>({...t,html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return{...t,html:`ArtPlayer ${i}`}}({name:"version",index:50})),this.add(function(t){return e=>({...t,html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=H(e),{height:c,width:d}=H(r);let p=n-s,u=o-l;n+d>s+a&&(p=a-d),o+c>l+i&&(u=i-c),I(r,{top:`${u}px`,left:`${p}px`})}),o(e,"click",t=>{D(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function St(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||s?.aborted)return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{s?.removeEventListener("abort",l)}}),s?.addEventListener("abort",l,{once:!0}),l}function Pt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Mt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const zt=new WeakMap,At=new WeakMap,Rt=new WeakMap;function Ot(t){return Rt.get(t)||u(t)}function It(t){const e=zt.get(t),r=Rt.get(t);return()=>zt.get(t)===e&&(!e||e.active())&&Rt.get(t)===r&&(!r||!r.closed)}function Nt(t){const e=Rt.get(t),r=u(t).child(),n=r.child();Rt.set(t,r),r.add(()=>{Rt.get(t)===r&&Rt.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!h(t)&&!n.closed&&zt.get(t)===o};return zt.set(t,o),n.add(()=>{zt.get(t)===o&&zt.delete(t),o.onAssigned=void 0,o.onError=void 0}),e?.dispose(),o}function _t(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&e?.()}function Wt(t,e,r){At.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{At.get(t)===e&&(At.delete(t),_t(e))}}function Dt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Ft(t,e){const{$progress:r}=t.template,{left:n}=H(r),o=J((C?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:tt(i),width:o,percentage:J(o/r.clientWidth,0,1)}}function Vt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Ft(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Yt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=v(e),{on:a}=w(t,e);let s=()=>{};const l=mt(".art-progress-hover",e),c=mt(".art-progress-loaded",e),d=mt(".art-progress-played",e),p=mt(".art-progress-highlight",e),u=mt(".art-progress-indicator",e),h=mt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Ft(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?O(h,"left",0):o>e.clientWidth-a/2?O(h,"left",e.clientWidth-a+"px"):O(h,"left",o-a/2+"px")}r.indicator?R(u,r.indicator):O(u,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&C;if("loaded"===r&&O(c,"width",100*n+"%"),"hover"===r&&(O(l,"width",100*n+"%"),D(a,p)?function(r){const{width:n}=Ft(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=o??"";const i=h.clientWidth;n<=i/2?O(h,"left",0):n>e.clientWidth-i/2?O(h,"left",e.clientWidth-i+"px"):O(h,"left",n-i/2+"px")}(a):f(a),0===n?z(o,"art-progress-hover"):M(o,"art-progress-hover")),"played"===r&&(O(d,"width",100*n+"%"),O(u,"left",100*n+"%")),m){M(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:tt(n*t.duration)}),s(),s=Pt(i,()=>{z(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){p.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Bt(t){return e=>({...t,html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Yt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=w(t,e),a=v(e);let s=0;const l=()=>{const e=It(t);return()=>!a.closed&&!h(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!C){let e;i(r,"click",e=>{e.target!==n&&Vt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Ft(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(n?.()){const{second:o,percentage:i}=Ft(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function Ht(t){const{option:e}=t.art;e.isLive||t.add(Bt({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.play),s=ft(t,o.pause);function l(){O(a,"display","flex"),O(s,"display","none")}function c(){O(a,"display","none"),O(s,"display","flex")}W(a,i.get("Play")),W(s,i.get("Pause")),n(a,"click",()=>{G(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>({...t,mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o}=e,i=ft(t,o.volume),a=ft(t,o.volumeClose),s=ft(t,'
'),l=ft(s,'
'),c=ft(l,'
'),d=ft(l,'
'),p=ft(d,'
'),u=ft(p,'
'),h=ft(d,'
');function f(t){const{top:e,height:r}=H(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)O(i,"display","none"),O(a,"display","flex"),O(h,"top","100%"),O(u,"top","100%"),c.textContent="0";else{const t=100*e.volume;O(i,"display","flex"),O(a,"display","none"),O(h,"top",100-t+"%"),O(u,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),C)O(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>({...t,style:C?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=w(e,t);function n(){const r=`${tt(e.currentTime)} / ${tt(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!u(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!C&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.screenshot),r(t,"click",()=>{G(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{W(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e;ft(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{W(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=w(e,t),{icons:n}=e;ft(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenWebOn),s=ft(t,o.fullscreenWebOff);O(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(W(t,i.get("Exit Web Fullscreen")),O(a,"display","none"),O(s,"display","inline-flex")):(W(t,i.get("Web Fullscreen")),O(a,"display","inline-flex"),O(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>({...t,tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=w(e,t),{icons:o,i18n:i}=e,a=ft(t,o.fullscreenOn),s=ft(t,o.fullscreenOff);O(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(W(t,i.get("Exit Fullscreen")),O(a,"display","none"),O(s,"display","inline-flex")):(W(t,i.get("Fullscreen")),O(a,"display","inline-flex"),O(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rqt.get(t).option.selector}),it(t,"$control_item",{get:()=>qt.get(t).item}),it(t,"$control_value",{get:()=>qt.get(t).value})),qt.set(t,e)}function Xt(t,e){t.innerHTML=e}function Gt(t,e,r,n,o){const{proxy:i}=t.events,a=v(n),s=r.selector;M(n,"art-control-selector");const l=document.createElement("div");M(l,"art-selector-value"),R(l,r.html),n.textContent="",R(n,l);const c=ft(n,'
');for(let u=0;u{if(a.closed)return;const o=j(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++d,c=()=>!a.closed&&s===d,p=a.add(function(t,e){return jt.set(t,e),()=>{jt.get(t)===e&&jt.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=await r.onSelect.call(t,i,i.$control_item,n);c()&&Xt(l,e)}}catch(u){console.warn("ArtPlayer selector failed:",u)}finally{p()}});o.push(p)}class Kt extends Tt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;g(t,n);const{on:o}=w(t,n);o("mousemove",()=>{C||(this.show=!0)}),o("click",()=>{C?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=D(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(z(r,"art-hide-cursor"),M(r,"art-hover"),this.timer=Date.now()):(M(r,"art-hide-cursor"),z(r,"art-hover"))}),this.init(),u(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=v(e),{on:i}=w(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){Ht(this)}add(t){if(h(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:X(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Xt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Zt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{if(h(t))return;const n=D(r,e);t.isInput=n&&"INPUT"===r.target?.tagName,t.isFocus=n,t.emit(n?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),u(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(h(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),h(t))return;(!C||!t.isLock&&i)&&G(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),h(t))return;C?!t.isLock&&s&&G(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function Jt(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!h(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),u(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(h(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:It(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Vt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=J((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),p=J(i.time+t.duration*d*l,0,t.duration);t.seek=p,n(i)&&(t.emit("setBar","played",J(p/t.duration,0,1),o),n(i)&&(t.notice.show=`${tt(p)} / ${tt(t.duration)}`))},cancel:r}}const Qt=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],te=["resize","scroll","orientationchange"];const ee=new WeakMap;function re(t){const e=ee.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function ne(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=ne(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=re(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(o?.capture),once:Boolean(o?.once),passive:o?.passive,signal:o?.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||c?.aborted)return()=>{};let d=!0;function p(r=!1){(d||r)&&(e.removeEventListener(i,n,l),c?.removeEventListener("abort",u),d=!1,t.destroyEvents.delete(u))}function u(){p()}t.destroyEvents.add(u);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?p(!0):c?.aborted?u():c?.addEventListener("abort",u,{once:!0})}catch(h){try{p(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return u}function oe(t){return(e,r)=>{if(h(t))return;const n=(...e)=>{if(!h(t))return r(...e)};t.on(e,n),u(t).add(()=>{t.off(e,n)})}}function ie(t){if(!t.constructor.USE_RAF)return;const e=u(t);let r=()=>{};const n=()=>{h(t)||(t.playing&&t.emit("raf"),h(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),oe(t)("destroy",()=>r())}class ae{constructor(t){this.destroyEvents=new Set,function(t,e){ee.set(t,{scope:u(e),cleaning:!1})}(this,t),u(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Zt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{h(t)||(M(r,"art-hover"),t.emit("hover",!0,e))},e=>{h(t)||(z(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{h(t)||t.emit("mousemove",e)})}(t,this),function(t,e){const{option:r,constructor:n}=t,o=oe(t);o("resize",()=>{const{aspectRatio:e,notice:n}=t;"standard"===t.state&&r.autoSize&&t.autoSize(),h(t)||(t.aspectRatio=e,h(t)||(n.show=""))});const i=u(t);let a=()=>{};const s=()=>{h(t)||(a(),a=Pt(i,()=>t.emit("resize"),n.RESIZE_TIME))};o("window:orientationchange",s),o("window:resize",s);const l=t.template.$player.ownerDocument.defaultView?.screen?.orientation;"function"===typeof l?.addEventListener&&e.proxy(l,"change",s)}(t,this),function(t,e){if(!C||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=Jt(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=u(t),a=oe(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=o?.innerHeight||n.documentElement.clientHeight,a=o?.innerWidth||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),h(t)||(s=!0,Pt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;u(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){if(h(t))return;const a=++n,s={disposers:[]},l=()=>a!==n||h(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,a=i.window||n.ownerDocument?.defaultView||window,c=(n,o,i)=>{for(const a of o){if(l())return;s.disposers.push(e.proxy(n,a,e=>{r!==s||h(t)||t.emit(`${i}:${a}`,e)}))}};c(o,Qt,"document"),c(a,te,"window")}catch(d){throw o(s),d}if(l())return void o(s);const c=r;r=s,o(c)}i(),e.bindGlobalEvents=i}(t,this),ie(t)}proxy(t,e,r,n={}){return Array.isArray(e),ne(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=re(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function se(t){if(t&&1===t.nodeType)return t}function le(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const ce=new WeakMap;class de{constructor(t){this.art=t,this.keys={},ce.set(this,{subscribed:!1}),C||this.init()}init(){const t=this.art;if(h(t))return;const e=ce.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{G(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!h(t)){if(t.isFocus&&function(t,e){if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const r=function(t,e){const r=t.target;return 9===r?.nodeType?r:r?.ownerDocument||t.view?.document||e}(t,e);let n=se(r.activeElement);for(;n?.shadowRoot?.activeElement;)n=se(n.shadowRoot.activeElement);if(n&&le(n))return!1;const o=se(t.composedPath?.()[0])||se(t.target);return!o||!le(o)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const pe={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",pe);class ue{constructor(t){this.art=t,this.languages={"zh-cn":pe},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=st(this.languages,t)&&this.languages[t]||{}}get(t){return st(this.language,t)&&this.language[t]||t}update(t){this.languages=ct(this.languages,t),this.init()}}const he={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class fe{constructor(t){const e={...he,...t.option.icons};for(const r in e)it(this,r,{get:()=>Y(r,e[r])})}}const me=new WeakMap;class ge extends Tt{constructor(t){super(t),this.name="info",me.set(this,{revision:0}),C||this.init()}init(){const t=me.get(this),e=++t.revision;if(t.scope?.dispose(),h(this.art)||t.revision!==e)return;const r=u(this.art).child();t.scope=r,r.add(()=>{t.scope===r&&(t.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!h(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const p=Array.from(s.querySelectorAll("[data-video]")),u=()=>e.dispose();t.on("destroy",u),e.add(()=>{t.off("destroy",u)});const h=()=>{try{for(const t of p){if(!n())return;const e=Reflect.get(c,t.dataset.video??"undefined");if(!n())return;const r="number"===typeof e?e.toFixed(2):e;if(!n())return;if(t.textContent!==r){const e=null==r?null:`${r}`;if(!n())return;t.textContent=e}}n()&&Pt(e,h,a.INFO_LOOP_TIME)}catch(t){o(t)}};n()&&h()}catch(i){o(i)}}(this.art,r,()=>{this.show=!1})}}class ve extends Tt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{O(i,"display","none"),O(s,"display",null),h(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,p(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),h(t)||n.proxy(e.$state,"click",()=>{h(t)||G(t.play())})}}const we=new WeakMap;function xe(t){const e=we.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class ke{constructor(t){this.art=t,this.timer=null,we.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),u(t).add(()=>{t.off("destroy",e)}),u(t).add(()=>{this.destroy()})}destroy(){xe(this)}set show(t){if(h(this.art))return;const e=we.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){xe(this);const i=e.revision,a=()=>!h(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(M(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(h(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",h(this.art)||e.revision!==t||z(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else z(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function $e({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ee(t,e){if(!$e(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return $e(r)?r:void 0}function Ce(t){const{$container:e,$video:r}=t.template;it(t,"autoHeight",{value(){if(h(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!$e(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||h(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}const Te=new WeakMap;function Le(t){return Te.get(t)||0}function Se(t){const{$video:e}=t.template;it(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){Te.set(t,Le(t)+1)}(t),e.currentTime=J(n,0,t.duration))}})}function Pe(t,e,r,n=!1){const o=e=>{h(t)||r(e)};t[n?"once":"on"](e,o),u(t).add(()=>{t.off(e,o)})}function Me(t,e,r){for(const[n,o]of e){if(h(t)||r&&!r())return;t[n].show=o}}function ze(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=Ot(t),l=0;return{reset(){l=0,a?.dispose(),z(i,"art-error")},loadStart(){z(i,"art-error")},schedule(c){(async c=>{if(h(t))return;const d=Ot(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const p=d.child();a=p,p.add(()=>{a===p&&(a=void 0)});const u=()=>!h(t)&&!p.closed&&d===Ot(t),f=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Ae(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{h(t)||t.emit(`video:${e.type}`,e)})}(t);const e=ze(t);!function(t,e){Pe(t,"video:canplay",()=>{e.reset(),Me(t,[["loading",!1]])}),Pe(t,"video:canplay",()=>{Me(t,[["loading",!1],["controls",!0],["mask",!0]]),h(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Pe(t,"video:ended",()=>{if(e.loop){const e=It(t);if(t.seek=0,h(t)||!e())return;G(t.play()),e()&&Me(t,[["controls",!1],["mask",!1]],e)}else Me(t,[["controls",!0],["mask",!0]])})}(t),Pe(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Pe(t,"video:loadedmetadata",()=>{t.emit("resize"),C&&Me(t,[["loading",!1],["controls",!0],["mask",!0]])}),Pe(t,"video:loadstart",()=>{e.loadStart(),Me(t,[["loading",!0],["mask",!1],["controls",!0]])}),Pe(t,"video:pause",()=>{Me(t,[["controls",!0],["mask",!0]])}),Pe(t,"video:play",()=>{Me(t,[["mask",!1]]),h(t)||O(r,"display","none")}),Pe(t,"video:playing",()=>Me(t,[["mask",!1]])),Pe(t,"video:progress",()=>{t.playing&&Me(t,[["loading",!1]])}),Pe(t,"video:seeked",()=>Me(t,[["loading",!1],["mask",!0]])),Pe(t,"video:seeking",()=>Me(t,[["loading",!0],["mask",!1]])),Pe(t,"video:timeupdate",()=>Me(t,[["mask",!1]])),Pe(t,"video:waiting",()=>Me(t,[["loading",!0],["mask",!1]]))}(t,e)}const Re=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Oe=(()=>{if("undefined"===typeof document)return!1;const t=Re[0],e={};for(const r of Re){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Ie={change:Oe.fullscreenchange,error:Oe.fullscreenerror},Ne={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ne.off("change",o),r()};Ne.on("change",o);const i=t[Oe.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ne.isFullscreen)return void t();const r=()=>{Ne.off("change",r),t()};Ne.on("change",r);const n=document[Oe.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ne.isFullscreen?Ne.exit():Ne.request(t,e),onchange(t){Ne.on("change",t)},onerror(t){Ne.on("error",t)},on(t,e){const r=Ie[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Ie[t];r&&document.removeEventListener(r,e,!1)},raw:Oe};function _e(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Ne,{isFullscreen:{get:()=>Boolean(document[Oe.fullscreenElement])},element:{enumerable:!0,get:()=>document[Oe.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Oe.fullscreenEnabled])}});const We=new WeakMap;function De(t){try{Promise.resolve(t()).catch(()=>{})}catch{}}function Fe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=We.get(t);if(!n){n=new WeakMap,We.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),De(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),De(i))}function Ve(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,p=!1,u=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!p&&r&&Fe(t))});const m=()=>{d&&!p&&(r?t.element===t.target:o())&&f()};if(St(i,t.document,t.changeEvent,m),St(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(u=!0,d&&!p&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){We.get(t.document)?.delete(t.target)}(t);const e=r?t.request():t.exit();p=Boolean(e&&"function"===typeof e.then),d=!0,c&&!p&&r&&Fe(t),p?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):u?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ye(t,e){const r=u(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,p=!1,f=!1;function m(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch{}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),m()}),St(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){return We.get(t.document)?.has(t.target)??!1}(e))return;if(r&&p)return void m();if(r===s||h(t))return;s=r;const o=l,a=()=>h(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),St(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(f||void 0!==a||i()))&&!h(t)&&t.emit("fullscreenError",r)}),{get:()=>!h(t)&&i(),set(n){if(h(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?p=!1:d&&(p=!0),a?.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();f=!0,d=c;const s=Ve(e,r,c,()=>{!h(t)&&c||m()},()=>!i());f=!1,l===o?a=s:s.cancel();const u=s.promise.catch(e=>{throw h(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return u.catch(()=>{}),u}}}const Be=new WeakSet;function He(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function je(t){Be.delete(t),t.removeEventListener("webkitbeginfullscreen",qe),t.removeEventListener("webkitpresentationmodechanged",qe)}function qe(t){if(Be.has(this)&&He(this,"webkitbeginfullscreen"===t.type)){je(this);try{this.webkitExitFullscreen?.()}catch{}}}function Ue(t){Be.add(t),t.addEventListener("webkitbeginfullscreen",qe),t.addEventListener("webkitpresentationmodechanged",qe)}function Xe(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=He(e),i=o,a=!1,s=0;const l=()=>He(e,n);function c(r){if(h(t)||(c=e,Be.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const p=s,u=()=>h(t)||l()!==d||p!==s&&i!==d;t.emit("fullscreen",d),u()||(d&&(t.state="fullscreen"),u()||t.emit("resize"))}r.add(()=>{s++,i=!1,a&&Ue(e),l()&&e.webkitExitFullscreen?.()}),St(r,e,"webkitbeginfullscreen",()=>c(!0)),St(r,e,"webkitendfullscreen",()=>c(!1)),St(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!h(t)&&l(),set(r){if(h(t))return;const n=++s;if(i=Boolean(r),r){if(je(e),t.state="fullscreen",h(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,Ue(e)),l()&&e.webkitExitFullscreen()}}}function Ge(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(h(t))return;const i=function(t){const e=Ne.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>_e(t,e.requestFullscreen,void 0),exit:()=>_e(r,e.exitFullscreen)}}(o);i?it(t,"fullscreen",Ye(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?it(t,"fullscreen",Xe(t)):it(t,"fullscreen",{get:()=>!1,set(){h(t)||(r.show=e.get("Fullscreen Not Supported"))}}),it(t,"fullscreen",lt(t,"fullscreen"))};t.once("video:loadedmetadata",i),u(t).add(()=>{t.off("video:loadedmetadata",i)})}function Ke(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function Ze({node:t,parent:e,next:r}){if(!e)return void t.parentNode?.removeChild(t);const n=r?.parentNode===e?r:null;t.parentNode===e&&t.nextSibling===n||e.insertBefore(t,n)}function Je(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(Ze(t.placement),r()))}return u(t).add(()=>{n+=1;const t=r;if(r=void 0,t)try{o(t,()=>!0)}catch(i){try{e.parentNode!==t.placement.parent&&e.parentNode?.removeChild(e)}catch(a){throw new s([i,a])}throw i}}),i=>{if(h(t))return;const a=++n,s=()=>a===n&&!h(t);if(i){r||(r={placement:Ke(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);it(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function Qe(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function tr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function er(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),St(o,e,"click",n),St(o,l,"click",()=>{G(t.play())}),St(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const p=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};St(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=Qe(i.left,i.top,tr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:p,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function rr(t){const{$player:e,$video:r}=t.template,n=u(t).child();let o,i,a=0,s=!1,l=!1;const c=()=>!h(t)&&e.classList.contains("art-mini");function d(){if(i){const e=i,r=a;i=void 0;try{Ze(e)}catch(t){throw r!==a||i||(i=e),t}}}function p(){if(h(t))return;const r=++a;l=!1,d(),h(t)||r!==a||(o?.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(h(t))return;const u=++a;if(s)l=!0;else if(t.state="mini",!h(t)&&u===a){i??(i=Ke(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=er(t,n,c,p)}finally{s=!1}}if(l)return l=!1,void f();if(!o||h(t))return;if(u!==a)return void(c()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),h(t)||u!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:{...Qe(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r),reset:!0}}(t.storage.get("left"),e,tr(o.element));if(h(t)||u!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),h(t)||u!==a)return;t.storage.set("left",i.left)}h(t)||u!==a||t.emit("mini",!0)}catch(m){const r=l;throw l=!1,h(t)||u!==a&&!r||(d(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),m}}}return n.add(()=>{a++;try{d()}finally{o?.cancelDrag(),e.classList.remove("art-mini")}}),{get:c,set(t){t?f():p()}}}const nr=new WeakSet,or=t=>"picture-in-picture"===t.webkitPresentationMode;function ir(t){nr.delete(t),t.removeEventListener("webkitpresentationmodechanged",ar),t.removeEventListener("enterpictureinpicture",ar)}function ar(){if(nr.has(this)&&or(this)){ir(this);try{this.webkitSetPresentationMode?.("inline")}catch{}}}function sr(t){nr.add(t),t.addEventListener("webkitpresentationmodechanged",ar),t.addEventListener("enterpictureinpicture",ar)}function lr(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?it(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=u(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch{}}function p(e,r,n){e.then(()=>{!r||!h(t)&&a||d()},e=>{h(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),St(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!h(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),St(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!h(t)&&o()?e:null,set(n){if(h(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",h(t)||c!==i)return;s=!0;try{p(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&p(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?it(t,"pip",function(t){const{$video:e}=t.template,r=u(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(h(t)||nr.has(e))return;const s=or(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),h(t)||i!==l||or(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&sr(e),or(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])St(r,e,l,()=>s());return{get:()=>!h(t)&&or(e),set(r){if(h(t))return;const n=++i,l=a;if(r){if(!1===e.webkitSupportsPresentationMode?.("picture-in-picture"))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(ir(e),t.state="pip",h(t)||i!==n)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(c){throw n===i&&(o=!1),c}}else o&&(o=!1,sr(e)),or(e)&&e.webkitSetPresentationMode("inline");h(t)||n!==i||l!==a||or(e)!==Boolean(r)||s(!0)}}}(t)):it(t,"pip",{get:()=>!1,set(){h(t)||(r.show=e.get("PIP Not Supported"))}})}function cr(t){it(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:i?.html||"",selector:e,async onSelect(e,r,i){const a=function(t){return t&&jt.get(t)||(()=>!0)}(i);if(await t.switchQuality(e.url),!h(t)&&a()){const r=`${o.get("Switch Video")}: ${e.html}`;!h(t)&&a()&&(n.show=r)}return e.html}})}})}function dr(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=It(t);return new Promise((a,s)=>{const l=r=>{try{!h(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}it(t,"getDataURL",{value:()=>o(!1)}),it(t,"getBlobUrl",{value:()=>o(!0)}),it(t,"screenshot",{value:async e=>{const n=It(t),o=await t.getDataURL();if(!h(t)&&n()){const i=e||`artplayer_${tt(r.currentTime)}`;!h(t)&&n()&&Z(o,`${i}.png`),!h(t)&&n()&&t.emit("screenshot",o)}return o}})}function pr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function ur(t,e,r){return new Promise((n,o)=>{if(h(t)||e===t.url)return void n();const i=Nt(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),d=t=>l(!0,t);i.onError=d;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let u=!1,h=!1,f=!1;const m=function(t,e,r){let n,o=!1,i=!1,a=!1,s=Le(t);const l=()=>a||Le(t)!==s,c=()=>!!t.template?.$video?.seeking;return{restore(){if(!r()||l())return;const i=Le(t);t.currentTime=e,s=Le(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),g=async()=>{if(t.aspectRatio=o,c()){if(n)try{await t.play()}catch{}c()&&(t.notice.show="",l())}},v=()=>{if(c()&&!h&&u)try{if(t.template?.$video?.seeking)return;if(!c())return;if(f||(f=!0,t.playbackRate=s),!m.ready()||!c()||h)return;h=!0,p.dispose(),g().catch(d)}catch(e){d(e)}},y={"video:error":d,"video:loadedmetadata":()=>{if(c())try{m.restore()}catch(t){d(t)}},"video:canplay":()=>{u=!0,v()},"video:seeked":v,seek:m.manual},b=a.child(),w=[],x=Object.keys(y);for(const e of x)pr(b,t,e,t=>{i.acceptingEvents&&w.push([e,t])},!1);if(Wt(t,i,e),!c())return;if(t.notice.show="",!c())return;const k=()=>{if(b.dispose(),!e)return void l();const r={};for(const e of x)r[e]=pr(p,t,e,y[e],"video:seeked"!==e);for(const[t,e]of w){if(!c()||p.closed)break;r[t](e)}w.length=0};i.assigned?k():i.onAssigned=k}catch(p){d(p)}})}function hr(t,e){const{number:r,column:n,width:o,height:i,scale:a}=t,{imageWidth:s,videoWidth:l,videoHeight:c,progressWidth:d,position:p}=e,u=Number(n),h=Number(o)*Number(a)||s/u,f=Number(i)*Number(a)||h/(l/c),m=Math.floor(p/(d/Number(r)));return{height:`${f}px`,width:`${h}px`,backgroundPosition:`-${m%u*h}px -${Math.floor(m/u)*f}px`,left:p<=h/2?0:p>d-h/2?d-h+"px":p-h/2+"px"}}function fr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=u(t).child(),l=!1;function c(){const e=s;s=u(t).child(),o=void 0,l=!1,a=void 0,e.dispose()}function d(){const i=a,l=s;if(!i||!o)return;const c=()=>!h(t)&&!l.closed&&s===l&&a===i&&i.sourceActive()&&t.controls?.thumbnails===i.element;if(!c())return;const d=r.clientWidth*i.percentage;if(!(d>0&&d{const u=t.controls?.thumbnails,{url:f,scale:m}=e.thumbnails;if(!h(t)&&u&&f&&("hover"===r||"played"===r&&p&&C)){if(i!==u){const t=v(u);if(t.closed)return;i=u,t.add(()=>{i===u&&(i=void 0,c())})}if(a={percentage:n,element:u,sourceActive:It(t)},o)d();else if(!l){const t=s;l=!0,function(t,e,r){return L(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(l=!1,o=e,d())}).catch(e=>{s!==t||t.closed||(l=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),it(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{h(t)||!e.url||t.option.isLive||h(t)||(t.option.thumbnails=e,c())}})}function mr(t){const{option:e,template:{$video:r}}=t;it(t,"url",{get:()=>r.src,async set(n){if(h(t))return;const o=function(t){const e=At.get(t);return At.delete(t),e||Nt(t)}(t);o.acceptingEvents=!1;try{if(!n)return void(await Mt(o.scope)&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||K(n),s=e.customType[a];if(a&&s){if(!(await Mt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;pr(l,t,"video:canplay",()=>{c=!d}),pr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Dt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||pr(o.scope,t,"video:canplay",e)}}catch(i){Dt(o,i)}finally{_t(o)}}})}class gr{constructor(t){mr(t),function(t){const{template:{$video:e}}=t;it(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;it(t,"play",{async value(){const a=It(t),s=await i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;it(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${tt(t.currentTime)} / ${tt(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;it(t,"forward",{set(e){r.seek=t.currentTime+e}}),it(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;it(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=J(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),it(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),Se(t),function(t){it(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>ur(t,e,0);it(t,"switchQuality",{value:e=>ur(t,e,t.currentTime)}),it(t,"switchUrl",{value:e}),it(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;it(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;it(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!h(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ee({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(h(t))return;"width"===r?.axis?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,h(t)||t.emit("aspectRatio",i)}}})}(t),dr(t),Ge(t),Je(t),lr(t),function(t){const{$video:e}=t.template,r=t;it(t,"loaded",{get:()=>r.loadedTime/e.duration}),it(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){it(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;it(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;it(t,"autoSize",{value(){if(h(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!$e(o))return;const i=H(e),a=Ee(i,o.width/o.height);a&&!h(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;it(t,"rect",{get:()=>H(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}it(t,"x",{get:()=>e.left+window.pageXOffset}),it(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;it(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){h(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(Q(o))}`,h(t)||t.emit("flip",o))}})}(t),function(t){it(t,"mini",rr(t))}(t),function(t){const{template:{$poster:e}}=t;it(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch{return""}},set(t){O(e,"backgroundImage",`url(${t})`)}})}(t),Ce(t),function(t){const{$player:e}=t.template;it(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){it(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){it(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];it(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;nn.$track?.offset||0,set(o){const{cues:i}=t.subtitle;if(!n.$track||0===i.length)return;const a=J(o,-10,10);n.$track.offset=a;for(let e=0;e{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,it(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),cr(t),fr(t),Ae(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=J(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=J(i,0,1)),e.poster&&O(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const vr=new WeakMap,yr="art-auto-orientation-fullscreen";function br(t){if(vr.get(t.orientation)===t)try{t.orientation.unlock()}catch{}}const wr="art-auto-orientation",xr=["width","height","transform-origin","transform"];function kr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return $e(t)&&$e(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=u(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(wr);r.classList.remove(wr),n&&(t.isRotate=!1,h(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=q();if(h(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;o??(o=xr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(wr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{h(t)||(r?o?s(!1):e()&&(i(),i=Pt(n,()=>{o||s(!0)},Number(t.constructor.AUTO_ORIENTATION_TIME??0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(yr),t&&(t.cancelled=!0,br(t),t.settled&&vr.get(t.orientation)===t&&vr.delete(t.orientation))}return u(t).add(o),i=>{if(h(t))return;if(!i)return void o();if(n&&!n.cancelled&&vr.get(n.orientation)===n)return;const a=r.ownerDocument.defaultView?.screen?.orientation;if("function"!==typeof a?.lock||"function"!==typeof a.unlock||!e())return;const s={orientation:a,cancelled:!1,settled:!1};n=s,vr.set(a,s);const l=()=>!h(t)&&!s.cancelled&&n===s&&vr.get(a)===s,c=e=>{s.settled=!0;const o=l();vr.get(a)===s&&vr.delete(a),n===s&&(n=void 0),o&&(r.classList.remove(yr),t.notice.show=e)};try{const t=a.lock(a.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{s.settled=!0,l()?r.classList.add(yr):(br(s),vr.get(a)===s&&vr.delete(a))}).catch(c)}catch(d){c(d)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),u(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function $r(t){return t.get("times")||{}}function Er(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||h(t))return()=>{};const s=mt(".art-auto-playback-last",a),l=mt(".art-auto-playback-jump",a),c=mt(".art-auto-playback-close",a);ft(c,r.close);const d=v(a);let p,u=0;const f=()=>{const r=++u;if(p?.dispose(),d.closed||h(t)||u!==r)return;const f=d.child();p=f;const m=()=>p===f&&!f.closed&&!h(t);f.add(()=>{p===f&&(p=void 0,O(a,"display","none"))});const g=Ot(t).add(()=>{f.dispose()});f.add(()=>{g()});const v=$r(n)[t.option.id||t.option.url];if(!m())return;if(O(a,"display","none"),!m()||!v||!(v>=o.AUTO_PLAYBACK_MIN))return;if(!m())return;if(O(a,"display","flex"),!m())return;const y=`${e.get("Last Seen")} ${tt(v)}`;if(!m())return;if(s.textContent=y,!m())return;const b=e.get("Jump Play");if(!m())return;if(l.textContent=b,!m())return;const w=(e,r)=>{const n=t.events.proxy(e,"click",()=>{m()&&r()});f.add(()=>{t.events.remove(n)})};if(w(c,()=>{O(a,"display","none")}),!m())return;if(w(l,()=>{t.seek=v,m()&&(G(t.play()),m()&&(O(i,"display","none"),m()&&O(a,"display","none")))}),!m())return;let x=()=>{},k=!1;const $=()=>{!k&&m()&&(k=!0,x(),Pt(f,()=>{m()&&O(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",$),x=f.add(()=>{t.off("video:timeupdate",$)}),k&&x()};return()=>{b(t,a,"ready",f),b(t,a,"restart",f)}}(t);return function(t){const{storage:e,constructor:r}=t;oe(t)("video:timeupdate",()=>{if(!t.playing)return;const n=$r(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;h(t)||(o.length>i&&delete n[o[0]],n[a]=s,h(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return $r(e)},clear:()=>e.del("times"),delete(t){const r=$r(e);return delete r[t],e.set("times",r),r}}}function Cr(t){let e,r=0;return{start:n=>{const o=++r;if(e?.scope.dispose(),o!==r||h(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:Ot(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{e?.active||z(t.template.$player,"art-fast-forward")}}),Pt(i.scope,()=>{if(e!==i||h(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||h(t))return;t.playbackRate=r,e!==i||i.scope.closed||h(t)||M(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,e?.scope.dispose()}}}function Tr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Cr(t),i=oe(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return A(r,"art-fast-forward")}}}function Lr(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return A(n,"art-lock")}function i(){h(t)||(M(n,"art-lock"),h(t)||(t.isLock=!0,h(t)||t.emit("lock",!0)))}function a(){h(t)||(z(n,"art-lock"),h(t)||(t.isLock=!1,h(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=v(e);if(n.closed||h(t))return;const o=ft(e,r.lock);if(n.closed||h(t))return;const i=ft(e,r.unlock);n.closed||h(t)||(O(o,"display","none"),b(t,e,"lock",e=>{h(t)||(O(o,"display",e?"inline-flex":"none"),n.closed||h(t)||O(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Sr(t){return oe(t)("control",e=>{e?z(t.template.$player,"art-mini-progress-bar"):M(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Pr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){h(t.art)||!e.miniProgressBar||e.isLive||t.add(Sr),!h(t.art)&&e.lock&&C&&t.add(Lr),h(t.art)||!e.autoPlayback||e.isLive||t.add(Er),!h(t.art)&&e.autoOrientation&&C&&t.add(kr),!h(t.art)&&e.fastForward&&C&&!e.isLive&&t.add(Tr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){X(!h(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(h(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(h(t.art))return t;let o=n;const i=st(t,o);if(h(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return h(t.art)||(X(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),h(t.art)||it(t,o,{value:r})),t}(this,t,e)}}const Mr=new WeakMap;function zr(t){return!t.closed&&!Mr.get(t)}function Ar(t){Mr.set(t,(Mr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Mr.get(t)||1)-1;r?Mr.set(t,r):Mr.delete(t)}}const Rr=new WeakMap,Or=new WeakMap,Ir=["$parent","$parents","$option","$events","$formatted"];function Nr(t){const e=new Set;let r=t;for(;r&&!e.has(r);){e.add(r);const t=Rr.get(r);if(!t||!t.owner.active||t.owner.scope?.closed||!t.option.includes(r))return!1;if(!t.parent)return t.owner.root===t.option;if(Rr.get(t.parent)?.owner!==t.owner)return!1;r=t.parent}return!1}function _r(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Wr(t){const e=Rr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Dr(t,e){for(let r=0;r{d&&d!==r&&d.dispose()},()=>qr(t,o)])try{e()}catch(p){p instanceof s?c.push(...p.errors):c.push(p)}if(r.closed||h(t)||(o.push(...i.splice(0)),jr.set(r,o),Br.set(e,r),Hr.set(e,n)),a(),c.length)throw new s(c)},dispose(){if(l){l=!1;try{r.dispose()}finally{a()}}}}}function Zr(t,e,r,n,o,i){const a=i||Xr(e);if(!zr(a)||h(t))return;const s=t.proxy(r,n,e=>{if(zr(a)&&!h(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!zr(a)||h(t)?t.events.remove(s):(Wr(e).events.push(s),i&&i!==Br.get(e)&&i.add(()=>{const r=Wr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function Jr(t,e,r,n){const o=Xr(e);if(!zr(o)||h(t))return;const i=(...e)=>{if(zr(o)&&!h(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function Qr(t){const{art:e,active:r}=t,{controls:n,constructor:{SETTING_WIDTH:o,SETTING_ITEM_HEIGHT:i},template:{$player:a,$setting:s,$bottom:l}}=e;if(!n.setting||!t.show||!r)return;const c=a.getBoundingClientRect(),d=n.setting.getBoundingClientRect(),p=c.width/a.offsetWidth||1,u=(d.left-c.left+d.width/2)/p-a.clientLeft,h=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:a.clientWidth,containerHeight:a.clientHeight,requestedWidth:r[0]?.$parent?.width||o,rows:r.length+(r===t.option?0:1),rowHeight:i,controlCenter:u,bottom:Number.parseFloat(getComputedStyle(s).bottom)||0,padding:Number.parseFloat(getComputedStyle(l).paddingLeft)||0});s.style.height=`${h.height}px`,s.style.width=`${h.width}px`,e.isRotate||C||(u+h.width/2>a.clientWidth?(s.style.left="",s.style.right=""):(s.style.left=`${h.left}px`,s.style.right="auto"))}const tn=new WeakMap;function en(t){tn.delete(t)}const rn=new WeakMap;function nn(t,e){e?rn.set(t,e):rn.delete(t)}function on(t){const e=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),r=[],n=rn.get(t),o=n?.();for(const i of["html","icon","tooltip"]){const t=e.get(i)?.value;t instanceof Node&&r.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{for(const r of Reflect.ownKeys(t))!e.has(r)&&Object.getOwnPropertyDescriptor(t,r)?.configurable&&Reflect.deleteProperty(t,r);for(const[r,n]of e)Object.defineProperty(t,r,n);o?.(),nn(t,n);for(const{node:t,parent:e,next:n}of r)e?e.insertBefore(t,n?.parentNode===e?n:null):t.parentNode?.removeChild(t)}}const an=new WeakMap;async function sn(t,e,r,n,o,i,a,s){try{const l=Xr(e),c=Xr(i),d=(an.get(i)||0)+1;an.set(i,d);const p=()=>zr(l)&&zr(c)&&!h(t.art)&&an.get(i)===d;if(s?.(),!p())return;const u=await o.call(t.art,e,r,n);p()&&Reflect.set(i,a,u)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}}function ln(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const cn=new WeakMap;function dn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof s?e.push(...r.errors):e.push(r)}if(e.length)throw new s(e)}function pn(t){cn.get(t)?.()}function un(t,e){const r=t.find(e.name);if(h(t.art))return r||e;if(!r)return t.add(e);en(r),pn(r);const n=on(r),o=r.$item,i=o?.parentNode,a=o?.nextSibling,s=o?ln(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=Kr(t.art,e);r&&i.push(r)}for(const t of n)a.push(Ar(Vr(t)))}catch(l){try{dn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,dn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,dn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Yr(t)),...a]))}}}(t,r);let p=!0,f=!1;const m=()=>{if(!p)return;p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);if(h(t.art))return void d.dispose();const e=r.$item;try{dn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>s?.(),()=>{i&&o&&i.insertBefore(o,a?.parentNode===i?a:null)},()=>t.format(),()=>{if(f){t.active=l,l&&t.cache.has(l)&&_(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(u){console.warn("ArtPlayer setting restore failed:",u)}},g=()=>p&&!h(t.art)&&cn.get(r)===m;for(const u of d.items)cn.set(u,m);const v=u(t.art).add(()=>{p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!o?.enumerable||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,g),!g())return r;if(t.format(),!g())return r;if(t.createItem(r,!0),!g())return r;if(f=!0,t.render(),!g())return r;p=!1;for(const t of d.items)cn.get(t)===m&&cn.delete(t);return d.dispose(),r}catch(y){throw g()&&m(),y}finally{v()}}const hn=new WeakMap;function fn(t,e,r){it(t,`$${e}`,{configurable:!0,get:()=>r}),it(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",R(r,t)}})}function mn(t,e,r=!1){const n=function(t){const e=cn.get(t);return()=>!e||cn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const o=t.cache.get(e.$option),i=e.$item;let a="selector";st(e,"switch")&&(a="switch"),st(e,"range")&&(a="range"),st(e,"onClick")&&(a="button");const{icons:s,constructor:l}=t.art;if(!n())return;const c=function(t,e,r=u(t)){const n=Br.get(e);(!n||zr(n)||n.closed)&&Gr(t,e);const o=r.child();return Br.set(e,o),Hr.set(e,r),jr.set(o,Wr(e).events),o.add(()=>{qr(t,jr.get(o))}),o}(t.art,e,Vr(o)),d=()=>zr(c)&&!h(t.art)&&n();if(!d())return;const p=document.createElement("div");try{if(nn(e),M(p,"art-setting-item"),O(p,"height",`${l.SETTING_ITEM_HEIGHT}px`),p.dataset.name=e.name||"",p.dataset.value=String(e.value||""),!d())return;const n=R(p,'
'),u=R(p,'
'),f=document.createElement("div");switch(M(f,"art-setting-item-left-icon"),a){case"button":case"switch":case"range":{const t=e.icon||s.config;if(!d())return;R(f,t);break}case"selector":if(e.selector?.length){const t=e.icon||s.config;if(!d())return;R(f,t)}else R(f,s.check)}if(R(n,f),!d())return;fn(e,"icon",f);const m=document.createElement("div");M(m,"art-setting-item-left-text");const g=e.html||"";if(!d())return;R(m,g),R(n,m),fn(e,"html",m);const v=document.createElement("div");M(v,"art-setting-item-right-tooltip");const y=e.tooltip||"";if(!d())return;switch(R(v,y),R(u,v),fn(e,"tooltip",v),a){case"switch":{const t=document.createElement("div");M(t,"art-setting-item-right-icon");const r=R(t,s.switchOn),n=R(t,s.switchOff),o=e.switch;if(!d())return;O(o?n:r,"display","none"),R(u,t),it(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!d())return;nn(e,()=>{const t=i;return()=>{i=t}}),it(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(O(n,"display","none"),O(r,"display",null)):(O(n,"display",null),O(r,"display","none"))}});break}case"range":{const t=document.createElement("div");M(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",R(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!d())return;Reflect.set(r,i,String(t))}M(r,"art-setting-range"),R(u,t),it(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!d())return;nn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),it(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(e.selector?.length){const t=document.createElement("div");M(t,"art-setting-item-right-icon"),R(t,s.arrowRight),R(u,t)}}if(!d())return;if(function(t,e,r,n){const{art:o}=t,i=Xr(e),a=(t,r,n)=>Zr(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>sn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>sn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{if(e.selector?.length)t.render(e.selector);else{if(e.$parent?.onSelect)return sn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&M(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>sn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,p,a),!d())return;it(e,"$item",{configurable:!0,get:()=>p}),r&&i?.parentNode?i.replaceWith(p):R(o,p),e.mounted&&d()&&Pt(c,()=>{if(!h(t.art))try{const r=e.mounted?.call(t.art,p,e);Promise.resolve(r).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(r){console.warn("ArtPlayer setting mounted failed:",r)}},0)}catch(f){try{c.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw p.remove(),f}}function gn(t,e=t.option){if(h(t.art))return;const r=t.cache.get(e);if(r&&!zr(Vr(r)))return;const n=(hn.get(t)||0)+1;hn.set(t,n);const o=()=>hn.get(t)===n&&!h(t.art),i=t.active,a=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),s=()=>{t.active=i,i&&t.cache.has(i)&&_(t.cache.get(i),"art-current");for(const[e,r,n]of a)t.$parent.style.setProperty(e,r,n)};if(t.active=e,r)try{_(r,"art-current"),t.resize()}catch(l){throw o()&&t.cache.get(e)===r&&!Vr(r).closed&&s(),l}else{const r=document.createElement("div");t.cache.set(e,r);const n=function(t,e,r){const n=u(t.art).child();return Fr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,r),i=()=>!n.closed&&!h(t.art)&&t.cache.get(e)===r,a=[];try{if(!i())return;M(r,"art-setting-panel"),R(t.$parent,r),_(r,"art-current"),e[0]?.$parent&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Or.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=u(e).child(),n=(t,n)=>{if(r.closed||h(e))return;const o=(...t)=>{if(!r.closed&&!h(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=D(r,e.controls.setting),o=D(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||h(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(Q(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),Jr(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{Jr(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Dr(e,t)}check(t){!function(t,e){e?.$parent&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&_(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Or.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{for(let n=0;nWr(t).parent},$parents:{get:()=>Wr(t).parents},$option:{get:()=>Wr(t).option},$events:{get:()=>Wr(t).events},$formatted:{get:()=>!0}}),Rr.set(t,{parent:r,parents:n,option:o,events:a?.events||[],owner:i}),p.generated&&(t.name=e)}for(const p of a)p.generated||o.push(p.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Dr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){Qr(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Yr(n)}catch(i){r.push(i)}}try{Gr(t.art,e)}catch(i){i instanceof s?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new s(r)}(this,t)}remove(t){const e=this.find(t);X(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{en(t),pn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>n?.remove(),()=>this.render()])try{a()}catch(i){i instanceof s?o.push(...i.errors):o.push(i)}if(o.length)throw new s(o)}update(t){return un(this,t)}add(t,e=this.option){if(h(this.art))return t;let r=!1;this.traverse(e=>{r||(r=e===t)});const n=e.length,o=r?void 0:function(t){const e={};tn.set(t,e);const r=()=>tn.get(t)===e;return{current:r,finish(){r()&&tn.delete(t)}}}(t);let i=!1;try{e.push(t),this.format(),i=!0,this.createItem(t),this.render()}catch(a){if(h(this.art)||o&&!o.current())throw a;if(e[n]===t&&e.splice(n,1),!r&&i){try{this.inactivate(t)}catch(s){console.warn("ArtPlayer setting cleanup failed:",s)}t.$item?.remove()}throw a}finally{o?.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");O(i,"height",`${o}px`),M(i,"art-setting-item"),M(i,"art-setting-item-back");const a=R(i,'
'),s=document.createElement("div");M(s,"art-setting-item-left-icon"),R(s,n),R(a,s),R(a,e.$parent.html),Zr(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Vr(r)),R(r,i)}(this,t)}createItem(t,e=!1){mn(this,t,e)}render(t=this.option){gn(this,t)}}class bn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch{return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch{this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch{delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch{this.settings={}}}}const wn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class xn{constructor(t){this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope)?.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}async run(t){if(this.active)try{return await Promise.race([t(),this.cancelled])}finally{this.cancel()}}}const kn=new WeakMap;function $n(t){return kn.get(t)}function En(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const Cn=Tt;class Tn extends Cn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=u(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return kn.set(t,n),r.add(()=>{En(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){return this.art.template.$video?.textTracks?.[0]}get activeCues(){return Array.from(this.textTrack?.activeCues||[])}get cues(){return Array.from(this.textTrack?.cues||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?I(r,t):O(r,t,e)}update(){!function(t){const e=$n(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?ot(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}async switch(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i={...o.subtitle,...e,url:t},a=$n(this),s=a.revision+1,l=await this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),l}createTrack(t,e){!function(t,e,r){const n=$n(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),p=n.scope.child();p.add(()=>{d.onload=null,d.onerror=null});let u=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{p.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{p.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},p.closed||n.trackRevision!==o)return void p.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{p.closed||a.$track!==d||t.update()}):()=>{};if(p.add(()=>{i.events.remove(c)}),p.closed||n.trackRevision!==o)return p.dispose(),void d.remove();const h=n.track;n.track=p,t.destroyEvent=c,s.onload=null,s.onerror=null,u=!0;try{h?.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&En(n)}}catch(h){if(u)throw h;if(p.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,c?.parentNode===l?c:null),h}}(this,t,e)}async init(t){const e=$n(this),r=function(t){const e=t.request,r=new xn(t.scope);return t.request=r,t.revision+=1,e?.cancel(),r}(e),{notice:n,template:{$subtitle:i}}=this.art;return r.run(async()=>{if(!this.textTrack)return null;if(o(t,Et.subtitle),!t.url)return;let a;this.option=t,this.style(t.style);try{if(!r.active)return;const n=await fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const o=await n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||K(e.url)){case"srt":return{vtt:e.onVttLoad(dt(r))};case"ass":return{vtt:e.onVttLoad(ut(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(o,t);if(!r.active)return;const l=void 0===s?t.url:a=pt(s.vtt);if(!r.active)return;i.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return a&&(e.ownedURL=a,a=void 0),l}catch(s){if(!r.active)return;throw i.innerHTML="",n.show=s,s}finally{a&&(e.scope.closed||this.url!==a?URL.revokeObjectURL(a):e.ownedURL=a)}})}}const Ln=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${i}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Sn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=P(e.container),X(this.$container,`No container element found by ${e.container}`)),X(B(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();X("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),X(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=d.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=p(t);o.rollback=r,d.set(e,t),o.releaseContainer=()=>{d.get(e)===t&&d.delete(e)}}(t,this.$container,ln(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return Ln}query(t){return P(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Sn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){X(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),F(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&M(this.$player,"art-backdrop"),C&&M(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":M(this.$player,"art-destroy")}}const Pn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Mn{on(t,e,r){const n=this.e||(this.e={});let o=Pn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Pn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Pn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Sn(this),this.events=new ae(this),this.storage=new bn(this),this.icons=new fe(this),this.i18n=new ue(this),this.notice=new ke(this),this.player=new gr(this),this.layers=new ve(this),this.controls=new Kt(this),this.contextmenu=new Lt(this),this.subtitle=new Tn(this),this.info=new ge(this),this.loading=new ye(this),this.hotkey=new de(this),this.mask=new be(this),this.setting=new yn(this),this.plugins=new Pr(this),u(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Rn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Rn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=p(t);return e.rollback=void 0,!e.scope.closed})(this)&&An.push(this)}catch(r){try{f(this,An,!0,Rn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return An}static get version(){return i}static get config(){return a}static get utils(){return ht}static get scheme(){return Et}static get Emitter(){return Mn}static get validator(){return o}static get kindOf(){return o.kindOf}static get html(){return Sn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:k?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:navigator?.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){f(this,An,t,Rn.REMOVE_SRC_WHEN_DESTROY)}}return Rn.STYLE=wn,Rn.DEBUG=!1,Rn.CONTEXTMENU=!0,Rn.NOTICE_TIME=2e3,Rn.SETTING_WIDTH=250,Rn.SETTING_ITEM_WIDTH=200,Rn.SETTING_ITEM_HEIGHT=35,Rn.RESIZE_TIME=200,Rn.SCROLL_TIME=200,Rn.SCROLL_GAP=50,Rn.AUTO_PLAYBACK_MAX=10,Rn.AUTO_PLAYBACK_MIN=5,Rn.AUTO_PLAYBACK_TIMEOUT=3e3,Rn.RECONNECT_TIME_MAX=5,Rn.RECONNECT_SLEEP_TIME=1e3,Rn.CONTROL_HIDE_TIME=3e3,Rn.DBCLICK_TIME=300,Rn.DBCLICK_FULLSCREEN=!0,Rn.MOBILE_DBCLICK_PLAY=!0,Rn.MOBILE_CLICK_PLAY=!1,Rn.AUTO_ORIENTATION_TIME=200,Rn.INFO_LOOP_TIME=1e3,Rn.FAST_FORWARD_VALUE=3,Rn.FAST_FORWARD_TIME=1e3,Rn.TOUCH_MOVE_RATIO=.5,Rn.VOLUME_STEP=.1,Rn.SEEK_STEP=5,Rn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Rn.ASPECT_RATIO=["default","4:3","16:9"],Rn.FLIP=["normal","horizontal","vertical"],Rn.FULLSCREEN_WEB_IN_BODY=!0,Rn.LOG_VERSION=!0,Rn.USE_RAF=!1,Rn.REMOVE_SRC_WHEN_DESTROY=!0,T&&(window.Artplayer=Rn,S("artplayer-style",wn),setTimeout(()=>{Rn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Rn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Rn}); diff --git a/packages/artplayer/dist/artplayer.legacy.js b/packages/artplayer/dist/artplayer.legacy.js index fed1f19f9..d43f073d0 100644 --- a/packages/artplayer/dist/artplayer.legacy.js +++ b/packages/artplayer/dist/artplayer.legacy.js @@ -67,4 +67,4 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function C(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const T=new WeakMap;function L(t,e){const r=$(t).child();return T.set(e,r),r}function S(t){const e=T.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=T.get(t))||e.dispose()}function M(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function z(t,e){return{on:(r,n)=>{M(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const A=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",O=/^(?:(?!chrome|android).)*safari/i.test(A),R=/iPad|iPhone|iPod/i.test(A)&&!window.MSStream,I=R||A.includes("Macintosh")&&navigator.maxTouchPoints>=1,_=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(A)||I,N="undefined"!==typeof window&&"undefined"!==typeof document;function D(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function F(t,e=document){return e.querySelector(t)}function W(t,e){return t.classList.add(e)}function V(t,e){return t.classList.remove(e)}function Y(t,e){return t.classList.contains(e)}function B(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function H(t,e){for(const r in e)j(t,r,e[r]);return t}function q(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function U(t,e){q(t).forEach(t=>V(t,e)),W(t,e)}function X(t,e,r="top"){_||(t.setAttribute("aria-label",e),W(t,"hint--rounded"),W(t,`hint--${r}`))}function G(t,e){return rt(t).includes(e)}function K(t,e){return e.parentNode.replaceChild(t,e),t}function Z(t){return document.createElement(t)}function J(t="",e=""){const r=Z("i");return W(r,"art-icon"),W(r,`art-icon-${t}`),B(r,e),r}function Q(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function tt(t){return t.getBoundingClientRect()}function et(t,e){return new Promise((r,n)=>{const o=new Image;o.onload=function(){if(e&&1!==e){const i=document.createElement("canvas"),a=i.getContext("2d");i.width=o.width*e,i.height=o.height*e,a.drawImage(o,0,0,i.width,i.height),i.toBlob(e=>{const o=URL.createObjectURL(e),i=new Image;i.onload=function(){r(i)},i.onerror=function(){URL.revokeObjectURL(o),n(new Error(`Image load failed: ${t}`))},i.src=o})}else r(o)},o.onerror=function(){n(new Error(`Image load failed: ${t}`))},o.src=t})}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:W,append:B,assToVtt:$t,capitalize:dt,clamp:ct,createElement:Z,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:rt,getExt:st,getIcon:J,getRect:tt,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:Y,includeFromEvent:G,inverseClass:U,isBrowser:N,isIOS:R,isIOS13:I,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:_,isSafari:O,loadImg:et,mergeDeep:wt,query:F,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:V,replaceElement:K,secondToTime:ut,setStyle:j,setStyleText:D,setStyles:H,siblings:q,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:Q,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:X,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:A,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Ct(t,e){return B(t,e)}function Tt(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[c(l({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},_t=new WeakSet;class Nt{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return Y(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?W(e,r):V(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){W(t,`art-${r}`),W(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):B(e,t),i.html&&B(t,i.html),i.style&&H(t,i.style),i.tooltip&&X(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{P(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!_t.has(e)){_t.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{_t.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Dt extends Nt{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),_||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=z(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return c(l({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="1"]',t);n&&U(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&U(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return c(l({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="default"]',t);n&&U(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return c(l({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="normal"]',t);n&&U(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&U(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=tt(e),{height:c,width:d}=tt(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),H(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{G(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Ft(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Wt(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}function Yt(t,e){const{$progress:r}=t.template,{left:n}=tt(r),o=ct((_?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Bt(t,e,r=()=>!0){if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Yt(t,e);t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function jt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=z(t,e);let s=()=>{};const l=Tt(".art-progress-hover",e),c=Tt(".art-progress-loaded",e),d=Tt(".art-progress-played",e),u=Tt(".art-progress-highlight",e),p=Tt(".art-progress-indicator",e),h=Tt(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Yt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?B(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&_;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),G(a,u)?function(r){const{width:n}=Yt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?V(o,"art-progress-hover"):W(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){W(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Wt(i,()=>{V(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function Ht(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{jt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=z(t,e);if(!_){let e=!1;i(r,"click",e=>{e.target!==n&&Bt(t,e)}),i(r,"mousemove",e=>{const{percentage:r}=Yt(t,e);t.emit("setBar","hover",r,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button}),o("document:mousemove",r=>{if(e){const{second:e,percentage:n}=Yt(t,r);t.emit("setBar","played",n,r),t.seek=e}}),o("document:mouseup",()=>{e&&(e=!1)})}}(e,t)}})}function qt(t){const{option:e}=t.art;e.isLive||t.add(Ht({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.play),s=Ct(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}X(a,i.get("Play")),X(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o}=e,i=Ct(t,o.volume),a=Ct(t,o.volumeClose),s=Ct(t,'
'),l=Ct(s,'
'),c=Ct(l,'
'),d=Ct(l,'
'),u=Ct(d,'
'),p=Ct(u,'
'),h=Ct(d,'
');function f(t){const{top:e,height:r}=tt(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),_)j(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>c(l({},t),{style:_?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=z(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!_&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Ct(t,n.screenshot),r(t,"click",()=>{e.screenshot()})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Ct(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{X(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Ct(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{X(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Ct(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.fullscreenWebOn),s=Ct(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(X(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Ct(t,o.fullscreenOn),s=Ct(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(X(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(X(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rXt.get(t).option.selector}),gt(t,"$control_item",{get:()=>Xt.get(t).item}),gt(t,"$control_value",{get:()=>Xt.get(t).value})),Xt.set(t,e)}function Kt(t,e){t.innerHTML=e}function Zt(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;W(n,"art-control-selector");const l=document.createElement("div");W(l,"art-selector-value"),B(l,r.html),n.textContent="",B(n,l);const c=Ct(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return Ut.set(t,e),()=>{Ut.get(t)===e&&Ut.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&Kt(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class Jt extends Nt{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;L(t,n);const{on:o}=z(t,n);o("mousemove",()=>{_||(this.show=!0)}),o("click",()=>{_?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=G(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(V(r,"art-hide-cursor"),W(r,"art-hover"),this.timer=Date.now()):(W(r,"art-hide-cursor"),V(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=z(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){qt(this)}add(t){if(E(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){Kt(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function Qt(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=G(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),E(t))return;(!_||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;_?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}const te=new WeakMap,ee=new WeakMap,re=new WeakMap;function ne(t){return re.get(t)||$(t)}function oe(t){const e=te.get(t),r=re.get(t);return()=>te.get(t)===e&&(!e||e.active())&&re.get(t)===r&&(!r||!r.closed)}function ie(t){const e=re.get(t),r=$(t).child(),n=r.child();re.set(t,r),r.add(()=>{re.get(t)===r&&re.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&te.get(t)===o};return te.set(t,o),n.add(()=>{te.get(t)===o&&te.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function ae(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function se(t,e,r){ee.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{ee.get(t)===e&&(ee.delete(t),ae(e))}}function le(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),$(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(E(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:oe(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Bt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),Qt(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(W(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Wt(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!_||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=$(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),E(t)||(s=!0,Wt(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||E(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),_||this.init()}init(){const t=this.art;if(E(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!E(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Ce{constructor(t){const e=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>J(r,e[r])})}}const Te=new WeakMap;class Le extends Nt{constructor(t){super(t),this.name="info",Te.set(this,{revision:0}),_||this.init()}init(){var t;const e=Te.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),E(this.art)||e.revision!==r)return;const n=$(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!E(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Wt(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends Nt{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{j(i,"display","none"),j(s,"display",null),E(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,k(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),E(t)||n.proxy(e.$state,"click",()=>{E(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),$(t).add(()=>{t.off("destroy",e)}),$(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(E(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!E(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(W(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(E(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",E(this.art)||e.revision!==t||V(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else V(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ie(t,e){if(!Re(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Re(r)?r:void 0}function _e(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Re(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}function Ne(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function De(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function Fe(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=ne(t),l=0;return{reset(){l=0,null==a||a.dispose(),V(i,"art-error")},loadStart(){V(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=ne(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===ne(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function We(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Fe(t);!function(t,e){Ne(t,"video:canplay",()=>{e.reset(),De(t,[["loading",!1]])}),Ne(t,"video:canplay",()=>{De(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Ne(t,"video:ended",()=>{if(e.loop){const e=oe(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&De(t,[["controls",!1],["mask",!1]],e)}else De(t,[["controls",!0],["mask",!0]])})}(t),Ne(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Ne(t,"video:loadedmetadata",()=>{t.emit("resize"),_&&De(t,[["loading",!1],["controls",!0],["mask",!0]])}),Ne(t,"video:loadstart",()=>{e.loadStart(),De(t,[["loading",!0],["mask",!1],["controls",!0]])}),Ne(t,"video:pause",()=>{De(t,[["controls",!0],["mask",!0]])}),Ne(t,"video:play",()=>{De(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Ne(t,"video:playing",()=>De(t,[["mask",!1]])),Ne(t,"video:progress",()=>{t.playing&&De(t,[["loading",!1]])}),Ne(t,"video:seeked",()=>De(t,[["loading",!1],["mask",!0]])),Ne(t,"video:seeking",()=>De(t,[["loading",!0],["mask",!1]])),Ne(t,"video:timeupdate",()=>De(t,[["mask",!1]])),Ne(t,"video:waiting",()=>De(t,[["loading",!0],["mask",!1]]))}(t,e)}const Ve=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],Ye=(()=>{if("undefined"===typeof document)return!1;const t=Ve[0],e={};for(const r of Ve){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),Be={change:Ye.fullscreenchange,error:Ye.fullscreenerror},je={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{je.off("change",o),r()};je.on("change",o);const i=t[Ye.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!je.isFullscreen)return void t();const r=()=>{je.off("change",r),t()};je.on("change",r);const n=document[Ye.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>je.isFullscreen?je.exit():je.request(t,e),onchange(t){je.on("change",t)},onerror(t){je.on("error",t)},on(t,e){const r=Be[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=Be[t];r&&document.removeEventListener(r,e,!1)},raw:Ye};function He(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(je,{isFullscreen:{get:()=>Boolean(document[Ye.fullscreenElement])},element:{enumerable:!0,get:()=>document[Ye.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[Ye.fullscreenEnabled])}});const qe=new WeakMap;function Ue(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Xe(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=qe.get(t);if(!n){n=new WeakMap,qe.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ue(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ue(i))}function Ge(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Xe(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Ft(i,t.document,t.changeEvent,m),Ft(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=qe.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Xe(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Ke(t,e){const r=$(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Ft(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=qe.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Ft(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Ge(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const Ze=new WeakSet;function Je(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function Qe(t){Ze.delete(t),t.removeEventListener("webkitbeginfullscreen",tr),t.removeEventListener("webkitpresentationmodechanged",tr)}function tr(t){var e;if(Ze.has(this)&&Je(this,"webkitbeginfullscreen"===t.type)){Qe(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function er(t){Ze.add(t),t.addEventListener("webkitbeginfullscreen",tr),t.addEventListener("webkitpresentationmodechanged",tr)}function rr(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=Je(e),i=o,a=!1,s=0;const l=()=>Je(e,n);function c(r){if(E(t)||(c=e,Ze.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>E(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&er(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Ft(r,e,"webkitbeginfullscreen",()=>c(!0)),Ft(r,e,"webkitendfullscreen",()=>c(!1)),Ft(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(Qe(e),t.state="fullscreen",E(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,er(e)),l()&&e.webkitExitFullscreen()}}}function nr(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=je.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>He(t,e.requestFullscreen,void 0),exit:()=>He(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Ke(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",rr(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function or(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function ir({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function ar(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(ir(t.placement),r()))}return $(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:or(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function sr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function lr(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function cr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Ft(o,e,"click",n),Ft(o,l,"click",()=>{at(t.play())}),Ft(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Ft(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=sr(i.left,i.top,lr(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function dr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{ir(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=or(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=cr(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:c(l({},sr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,lr(o.element));if(E(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const ur=new WeakSet,pr=t=>"picture-in-picture"===t.webkitPresentationMode;function hr(t){ur.delete(t),t.removeEventListener("webkitpresentationmodechanged",fr),t.removeEventListener("enterpictureinpicture",fr)}function fr(){var t;if(ur.has(this)&&pr(this)){hr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function mr(t){ur.add(t),t.addEventListener("webkitpresentationmodechanged",fr),t.addEventListener("enterpictureinpicture",fr)}function gr(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=$(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Ft(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Ft(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||ur.has(e))return;const s=pr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||pr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&mr(e),pr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Ft(r,e,l,()=>s());return{get:()=>!E(t)&&pr(e),set(r){var n;if(E(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(hr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,mr(e)),pr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||pr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function vr(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return d(this,null,function*(){const r=function(t){return t&&Ut.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function yr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function br(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=ie(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child(),h={"video:error":u,"video:loadedmetadata":()=>{if(c())try{t.currentTime=r}catch(e){u(e)}},"video:canplay":()=>{if(!c())return;p.dispose();d(null,null,function*(){if(t.playbackRate=s,c()&&(t.aspectRatio=o,c())){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}).catch(u)}},f=a.child(),m=[],g=Object.keys(h);for(const e of g)yr(f,t,e,t=>{i.acceptingEvents&&m.push([e,t])},!1);if(se(t,i,e),!c())return;if(t.notice.show="",!c())return;const v=()=>{if(f.dispose(),!e)return void l();const r={};for(const e of g)r[e]=yr(p,t,e,h[e]);for(const[t,e]of m){if(!c()||p.closed)break;r[t](e)}m.length=0};i.assigned?v():i.onAssigned=v}catch(p){u(p)}})}function wr(t){const{option:e,template:{$progress:r,$video:n}}=t;let o=null,i=!1,a=null;t.on("setBar",(o,s,l)=>d(null,null,function*(){var c;const d=null==(c=t.controls)?void 0:c.thumbnails,{url:u,scale:p}=e.thumbnails;if(!d||!u)return;if("hover"===o||"played"===o&&l&&_){if(a||i||(i=!0,a=yield et(u,p),i=!1),!a)return;const o=r.clientWidth*s;o>0&&or.clientWidth-h/2?j(s,"left",r.clientWidth-h+"px"):j(s,"left",o-h/2+"px")}(o)}})),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set(e){e.url&&!t.option.isLive&&(t.option.thumbnails=e,clearTimeout(o),o=null,i=!1,a=null)}})}function xr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=ee.get(t);return ee.delete(t),e||ie(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;yr(l,t,"video:canplay",()=>{c=!d}),yr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>le(o,t))}else{if(i&&URL.revokeObjectURL(i),!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||yr(o.scope,t,"video:canplay",e)}}catch(i){le(o,i)}finally{ae(o)}})}})}class kr{constructor(t){xr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=oe(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),function(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(e.currentTime=ct(n,0,t.duration))}})}(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>br(t,e,0);gt(t,"switchQuality",{value:e=>br(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ie({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,E(t)||t.emit("aspectRatio",i)}}})}(t),function(t){const{notice:e,template:{$video:r}}=t,n=Z("canvas");gt(t,"getDataURL",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),t(n.toDataURL("image/png"))}catch(i){e.show=i,o(i)}})}),gt(t,"getBlobUrl",{value:()=>new Promise((t,o)=>{try{n.width=r.videoWidth,n.height=r.videoHeight,n.getContext("2d").drawImage(r,0,0),n.toBlob(e=>{t(URL.createObjectURL(e))})}catch(i){e.show=i,o(i)}})}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=yield t.getDataURL();return lt(n,`${e||`artplayer_${ut(r.currentTime)}`}.png`),t.emit("screenshot",n),n})})}(t),nr(t),ar(t),gr(t),function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Re(o))return;const i=tt(e),a=Ie(i,o.width/o.height);a&&!E(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>tt(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",dr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),_e(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),vr(t),wr(t),We(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const $r=new WeakMap,Er="art-auto-orientation-fullscreen";function Cr(t){if($r.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Tr="art-auto-orientation",Lr=["width","height","transform-origin","transform"];function Sr(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Re(t)&&Re(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Tr);r.classList.remove(Tr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=Lr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Tr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Wt(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Er),t&&(t.cancelled=!0,Cr(t),t.settled&&$r.get(t.orientation)===t&&$r.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(t))return;if(!i)return void o();if(n&&!n.cancelled&&$r.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,$r.set(l,c);const d=()=>!E(t)&&!c.cancelled&&n===c&&$r.get(l)===c,u=e=>{c.settled=!0;const o=d();$r.get(l)===c&&$r.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(Er),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(Er):(Cr(c),$r.get(l)===c&&$r.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Pr(t){return t.get("times")||{}}function Mr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||E(t))return()=>{};const s=Tt(".art-auto-playback-last",a),l=Tt(".art-auto-playback-jump",a),c=Tt(".art-auto-playback-close",a);Ct(c,r.close);const d=S(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||E(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!E(t);h.add(()=>{u===h&&(u=void 0,j(a,"display","none"))});const m=ne(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Pr(n)[t.option.id||t.option.url];if(!f())return;if(j(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(j(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{j(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(j(i,"display","none"),f()&&j(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Wt(h,()=>{f()&&j(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{M(t,a,"ready",h),M(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Pr(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;E(t)||(o.length>i&&delete n[o[0]],n[a]=s,E(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Pr(e)},clear:()=>e.del("times"),delete(t){const r=Pr(e);return delete r[t],e.set("times",r),r}}}function zr(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||E(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:ne(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||V(t.template.$player,"art-fast-forward")}}),Wt(i.scope,()=>{if(e!==i||E(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||E(t))return;t.playbackRate=r,e!==i||i.scope.closed||E(t)||W(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Ar(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=zr(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return Y(r,"art-fast-forward")}}}function Or(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return Y(n,"art-lock")}function i(){E(t)||(W(n,"art-lock"),E(t)||(t.isLock=!0,E(t)||t.emit("lock",!0)))}function a(){E(t)||(V(n,"art-lock"),E(t)||(t.isLock=!1,E(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=S(e);if(n.closed||E(t))return;const o=Ct(e,r.lock);if(n.closed||E(t))return;const i=Ct(e,r.unlock);n.closed||E(t)||(j(o,"display","none"),M(t,e,"lock",e=>{E(t)||(j(o,"display",e?"inline-flex":"none"),n.closed||E(t)||j(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Rr(t){return me(t)("control",e=>{e?V(t.template.$player,"art-mini-progress-bar"):W(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Ir{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Rr),!E(t.art)&&e.lock&&_&&t.add(Or),E(t.art)||!e.autoPlayback||e.isLive||t.add(Mr),!E(t.art)&&e.autoOrientation&&_&&t.add(Sr),!E(t.art)&&e.fastForward&&_&&!e.isLive&&t.add(Ar)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const _r=new WeakMap;function Nr(t){return!t.closed&&!_r.get(t)}function Dr(t){_r.set(t,(_r.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(_r.get(t)||1)-1;r?_r.set(t,r):_r.delete(t)}}const Fr=new WeakMap,Wr=new WeakMap,Vr=["$parent","$parents","$option","$events","$formatted"];function Yr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Fr.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Fr.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Br(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function jr(t){const e=Fr.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Hr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>Jr(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),Zr.set(r,o),Gr.set(e,r),Kr.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function nn(t,e,r,n,o,i){const a=i||tn(e);if(!Nr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Nr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Nr(a)||E(t)?t.events.remove(s):(jr(e).events.push(s),i&&i!==Gr.get(e)&&i.add(()=>{const r=jr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function on(t,e,r,n){const o=tn(e);if(!Nr(o)||E(t))return;const i=(...e)=>{if(Nr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function an(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||_||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const sn=new WeakMap;function ln(t){sn.delete(t)}const cn=new WeakMap;function dn(t,e){e?cn.set(t,e):cn.delete(t)}function un(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=cn.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),dn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const pn=new WeakMap;function hn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=tn(e),c=tn(i),d=(pn.get(i)||0)+1;pn.set(i,d);const u=()=>Nr(l)&&Nr(c)&&!E(t.art)&&pn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function fn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const mn=new WeakMap;function gn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function vn(t){var e;null==(e=mn.get(t))||e()}function yn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);ln(r),vn(r);const n=un(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?fn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=rn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Dr(Ur(t)))}catch(l){try{gn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,gn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,gn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Xr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{gn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&U(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!E(t.art)&&mn.get(r)===h;for(const v of d.items)mn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)mn.get(t)===h&&mn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const bn=new WeakMap;function wn(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",B(r,t)}})}function xn(t,e,r=!1){var n,o;const i=function(t){const e=mn.get(t);return()=>!e||mn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Gr.get(e);(!n||Nr(n)||n.closed)&&en(t,e);const o=r.child();return Gr.set(e,o),Kr.set(e,r),Zr.set(o,jr(e).events),o.add(()=>{Jr(t,Zr.get(o))}),o}(t.art,e,Ur(a)),p=()=>Nr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(dn(e),W(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=B(h,'
'),f=B(h,'
'),m=document.createElement("div");switch(W(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;B(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;B(m,t)}else B(m,c.check)}if(B(i,m),!p())return;wn(e,"icon",m);const g=document.createElement("div");W(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;B(g,v),B(i,g),wn(e,"html",g);const y=document.createElement("div");W(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(B(y,b),B(f,y),wn(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=B(t,c.switchOn),n=B(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),B(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;dn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");W(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",B(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}W(r,"art-setting-range"),B(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;dn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");W(t,"art-setting-item-right-icon"),B(t,c.arrowRight),B(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=tn(e),a=(t,r,n)=>nn(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>hn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>hn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return hn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&W(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>hn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):B(a,h),e.mounted&&p()&&Wt(u,()=>{var r;if(!E(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function kn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Nr(Ur(n)))return;const o=(bn.get(t)||0)+1;bn.set(t,o);const i=()=>bn.get(t)===o&&!E(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&U(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{U(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Ur(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return qr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;W(n,"art-setting-panel"),B(t.$parent,n),U(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Wr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=G(r,e.controls.setting),o=G(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),on(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{on(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Hr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&U(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Wr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;ojr(t).parent},$parents:{get:()=>jr(t).parents},$option:{get:()=>jr(t).option},$events:{get:()=>jr(t).events},$formatted:{get:()=>!0}}),Fr.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Hr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){an(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Xr(n)}catch(i){r.push(i)}}try{en(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{ln(t),vn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return yn(this,t)}add(t,e=this.option){var r;if(E(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};sn.set(t,e);const r=()=>sn.get(t)===e;return{current:r,finish(){r()&&sn.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");j(i,"height",`${o}px`),W(i,"art-setting-item"),W(i,"art-setting-item-back");const a=B(i,'
'),s=document.createElement("div");W(s,"art-setting-item-left-icon"),B(s,n),B(a,s),B(a,e.$parent.html),nn(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Ur(r)),B(r,i)}(this,t)}createItem(t,e=!1){xn(this,t,e)}render(t=this.option){kn(this,t)}}class Cn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const Tn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class Ln{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const Sn=new WeakMap;function Pn(t){return Sn.get(t)}function Mn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const zn=Nt;class An extends zn{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return Sn.set(t,n),r.add(()=>{Mn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?H(r,t):j(r,t,e)}update(){!function(t){const e=Pn(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=Pn(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=Pn(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Mn(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return d(this,null,function*(){const e=Pn(this),r=function(t){const e=t.request,r=new Ln(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const On=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${g}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Rn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=F(e.container),it(this.$container,`No container element found by ${e.container}`)),it(Q(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,fn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return On}query(t){return F(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Rn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),K(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&W(this.$player,"art-backdrop"),_&&W(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":W(this.$player,"art-destroy")}}const In=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class _n{on(t,e,r){const n=this.e||(this.e={});let o=In(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(In(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=In(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Rn(this),this.events=new ve(this),this.storage=new Cn(this),this.icons=new Ce(this),this.i18n=new $e(this),this.notice=new Oe(this),this.player=new kr(this),this.layers=new Se(this),this.controls=new Jt(this),this.contextmenu=new Dt(this),this.subtitle=new An(this),this.info=new Le(this),this.loading=new Pe(this),this.hotkey=new xe(this),this.mask=new Me(this),this.setting=new En(this),this.plugins=new Ir(this),$(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Fn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Fn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Dn.push(this)}catch(r){try{C(this,Dn,!0,Fn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Dn}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return _n}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Rn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:O?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){C(this,Dn,t,Fn.REMOVE_SRC_WHEN_DESTROY)}}return Fn.STYLE=Tn,Fn.DEBUG=!1,Fn.CONTEXTMENU=!0,Fn.NOTICE_TIME=2e3,Fn.SETTING_WIDTH=250,Fn.SETTING_ITEM_WIDTH=200,Fn.SETTING_ITEM_HEIGHT=35,Fn.RESIZE_TIME=200,Fn.SCROLL_TIME=200,Fn.SCROLL_GAP=50,Fn.AUTO_PLAYBACK_MAX=10,Fn.AUTO_PLAYBACK_MIN=5,Fn.AUTO_PLAYBACK_TIMEOUT=3e3,Fn.RECONNECT_TIME_MAX=5,Fn.RECONNECT_SLEEP_TIME=1e3,Fn.CONTROL_HIDE_TIME=3e3,Fn.DBCLICK_TIME=300,Fn.DBCLICK_FULLSCREEN=!0,Fn.MOBILE_DBCLICK_PLAY=!0,Fn.MOBILE_CLICK_PLAY=!1,Fn.AUTO_ORIENTATION_TIME=200,Fn.INFO_LOOP_TIME=1e3,Fn.FAST_FORWARD_VALUE=3,Fn.FAST_FORWARD_TIME=1e3,Fn.TOUCH_MOVE_RATIO=.5,Fn.VOLUME_STEP=.1,Fn.SEEK_STEP=5,Fn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Fn.ASPECT_RATIO=["default","4:3","16:9"],Fn.FLIP=["normal","horizontal","vertical"],Fn.FULLSCREEN_WEB_IN_BODY=!0,Fn.LOG_VERSION=!0,Fn.USE_RAF=!1,Fn.REMOVE_SRC_WHEN_DESTROY=!0,N&&(window.Artplayer=Fn,D("artplayer-style",Tn),setTimeout(()=>{Fn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Fn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Fn}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t,e=Object.defineProperty,r=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(t,r,n)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n,l=(t,e)=>{for(var r in e||(e={}))i.call(e,r)&&s(t,r,e[r]);if(o)for(var r of o(e))a.call(e,r)&&s(t,r,e[r]);return t},c=(t,e)=>r(t,n(e)),d=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function u(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var p,h={exports:{}};var f=(p||(p=1,h.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2{e&&(e=!1,this.cleanups.delete(r),t())};return this.closed?r():this.cleanups.add(r),r}child(){const t=new b,e=this.add(()=>{t.dispose()});return t.add(()=>{e()}),t}dispose(){if(this.closed)return;this.disposed=!0;const t=[];for(const r of Array.from(this.cleanups).reverse())try{r()}catch(e){e instanceof y?t.push(...e.errors):t.push(e)}if(t.length)throw new y(t)}}const w=new WeakMap,x=new WeakMap;function k(t){const e=w.get(t);if(!e)throw new Error("ArtPlayer lifecycle has not been initialized");return e}function $(t){return k(t).scope}function E(t){const e=k(t);return e.destroying||e.scope.closed}function T(t,e,r,n,o=!1){var i,a,s;const l=k(t);if(l.destroying||l.scope.closed)return;l.destroying=!0;const c=[],d=t=>{try{t()}catch(e){c.push(...e instanceof y?e.errors:[e])}};n&&(null==(i=t.template)?void 0:i.$video)&&d(()=>t.reset()),d(()=>l.scope.dispose()),d(()=>{var e;return null==(e=t.template)?void 0:e.destroy(r)});const u=e.indexOf(t);-1!==u&&e.splice(u,1),t.isDestroy=!0,o||(null==(a=l.releaseContainer)||a.call(l),l.releaseContainer=void 0),d(()=>t.emit("destroy")),d(()=>l.finalizers.dispose()),o&&l.rollback&&d(l.rollback),l.rollback=void 0,null==(s=l.releaseContainer)||s.call(l),l.releaseContainer=void 0;for(const p of c.slice(1))console.warn("Additional ArtPlayer cleanup failure:",p);if(c.length)throw c[0]}const C=new WeakMap;function L(t,e){const r=$(t).child();return C.set(e,r),r}function S(t){const e=C.get(t);if(!e)throw new Error("ArtPlayer component has not been registered");return e}function P(t){var e;null==(e=C.get(t))||e.dispose()}function M(t,e,r,n){const o=S(e);if(o.closed)return;const i=(...t)=>{if(!o.closed)return n(...t)};t.on(r,i),o.add(()=>{t.off(r,i)})}function z(t,e){return{on:(r,n)=>{M(t,e,r,n)},proxy:(r,n,o)=>function(t,e,r,n,o){const i=S(e);if(i.closed)return()=>{};const a=t.events.proxy(r,n,t=>{if(!i.closed)return o(t)});return i.add(()=>{t.events.remove(a)})}(t,e,r,n,o)}}const A=null!=(t=null==globalThis?void 0:globalThis.CUSTOM_USER_AGENT)?t:"undefined"!==typeof navigator?navigator.userAgent:"",O=/^(?:(?!chrome|android).)*safari/i.test(A),R=/iPad|iPhone|iPod/i.test(A)&&!window.MSStream,I=R||A.includes("Macintosh")&&navigator.maxTouchPoints>=1,N=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(A)||I,_="undefined"!==typeof window&&"undefined"!==typeof document;function W(t,e,r){return new Promise((n,o)=>{const i=r?r.child():new b;let a=!1,s=()=>{};function l(t){if(!a){a=!0;try{i.dispose()}catch(e){console.warn("Additional image cleanup failure:",e)}try{s()}catch(e){console.warn("Additional image cleanup failure:",e)}o(t)}}function c(t){if(!a&&!i.closed){a=!0;try{i.dispose(),n(t)}catch(e){try{s()}finally{o(e)}}}}if(i.add(()=>{if(!a){a=!0;try{s()}finally{n(void 0)}}}),!i.closed)try{const n=new Image;d(n,()=>{if(!e||1===e)return void c(n);const t=document.createElement("canvas"),o=t.getContext("2d");if(t.width=n.width*e,t.height=n.height*e,!o)throw new TypeError("Canvas 2D context is unavailable");a||i.closed||(o.drawImage(n,0,0,t.width,t.height),a||i.closed||t.toBlob(t=>{if(!a&&!i.closed)try{if(!t)throw new Error("Unable to encode thumbnail image");const e=URL.createObjectURL(t);let n=!1;const o=()=>{n||(n=!0,URL.revokeObjectURL(e))};if(s=r?r.add(o):o,a||i.closed)return void s();const l=new Image;d(l,()=>c(l)),i.closed||(l.src=e)}catch(e){l(e)}}))}),i.closed||(n.src=t)}catch(u){l(u)}function d(e,r){e.onload=()=>{if(!a&&!i.closed)try{r()}catch(u){l(u)}},e.onerror=()=>l(new Error(`Image load failed: ${t}`)),i.add(()=>{e.onload=null,e.onerror=null,a||e.removeAttribute("src")})}})}function D(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}function F(t,e=document){return e.querySelector(t)}function V(t,e){return t.classList.add(e)}function Y(t,e){return t.classList.remove(e)}function B(t,e){return t.classList.contains(e)}function H(t,e){return e instanceof Element?t.appendChild(e):t.insertAdjacentHTML("beforeend",String(e)),t.lastElementChild||t.lastChild}function j(t,e,r){return t.style[e]=r,t}function q(t,e){for(const r in e)j(t,r,e[r]);return t}function U(t){return Array.from(t.parentElement.children).filter(e=>e!==t)}function X(t,e){U(t).forEach(t=>Y(t,e)),V(t,e)}function G(t,e,r="top"){N||(t.setAttribute("aria-label",e),V(t,"hint--rounded"),V(t,`hint--${r}`))}function K(t,e){return rt(t).includes(e)}function Z(t,e){return e.parentNode.replaceChild(t,e),t}function J(t){return document.createElement(t)}function Q(t="",e=""){const r=J("i");return V(r,"art-icon"),V(r,`art-icon-${t}`),H(r,e),r}function tt(){const t=document.createElement("div");return t.style.display="flex","flex"===t.style.display}function et(t){return t.getBoundingClientRect()}function rt(t){if(t.composedPath)return t.composedPath();const e=[];let r=t.target;for(;r;)e.push(r),r=r.parentNode;return e.includes(window)||void 0===window||e.push(window),e}function nt(){const t=document.createElement("div");t.style.cssText="position:fixed;top:env(safe-area-inset-top,0px);right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);left:env(safe-area-inset-left,0px);pointer-events:none;visibility:hidden;",document.body.appendChild(t);const e=getComputedStyle(t),r={top:Number.parseFloat(e.top)||0,right:Number.parseFloat(e.right)||0,bottom:Number.parseFloat(e.bottom)||0,left:Number.parseFloat(e.left)||0};return t.remove(),r}class ot extends Error{constructor(t,e){super(t),"captureStackTrace"in Error&&"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,e||this.constructor),this.name="ArtPlayerError"}}function it(t,e){if(!t)throw new ot(e);return t}function at(t){const e=t;return e&&"function"===typeof e.catch?e.catch(()=>{}):t}function st(t){const e=t.search(/[?#]/),r=(e<0?t:t.slice(0,e)).trim().toLowerCase();return r.slice(r.lastIndexOf(".")+1)}function lt(t,e){const r=document.createElement("a");r.style.display="none",r.href=t,r.download=e,document.body.appendChild(r);try{r.click()}finally{r.remove()}}function ct(t,e,r){return Math.max(Math.min(t,Math.max(e,r)),Math.min(e,r))}function dt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function ut(t){if(!t)return"00:00";const e=Math.floor(t/3600),r=Math.floor((t-3600*e)/60),n=Math.floor(t-3600*e-60*r);return(e>0?[e,r,n]:[r,n]).map(t=>t<10?`0${t}`:String(t)).join(":")}const pt={"&":"&","<":"<",">":">","'":"'",'"':"""},ht={"&":"&","<":"<",">":">","'":"'",""":'"'},ft=/(&|<|>|'|")/g;function mt(t){return t.replace(/[&<>'"]/g,t=>pt[t]||t)}const gt=Object.defineProperty,{hasOwnProperty:vt}=Object.prototype;function yt(t,e){return vt.call(t,e)}function bt(t,e){return Object.getOwnPropertyDescriptor(t,e)}function wt(...t){const e=t=>!!t&&"object"===typeof t&&!Array.isArray(t);return t.reduce((t,r)=>(Object.keys(r).forEach(n=>{const o=t[n],i=r[n];let a;a=Array.isArray(o)&&Array.isArray(i)?o.concat(...i):e(o)&&e(i)?wt(o,i):i,gt(t,n,{value:a,enumerable:!0,configurable:!0,writable:!0})}),t),{})}function xt(t){return"WEBVTT \r\n\r\n".concat((e=t,e.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g,(t,e,r)=>{let n=r.slice(0,3);return 1===r.length&&(n=`${r}00`),2===r.length&&(n=`${r}0`),`${e},${n}`})).replace(/\{\\([ibu])\}/g,"").replace(/\{\\([ibu])1\}/g,"<$1>").replace(/\{([ibu])\}/g,"<$1>").replace(/\{\/([ibu])\}/g,"").replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g,"$1.$2").replace(/\{[\s\S]*?\}/g,"").concat("\r\n\r\n"));var e}function kt(t){return URL.createObjectURL(new Blob([t],{type:"text/vtt"}))}function $t(t){const e=new RegExp("Dialogue:\\s\\d,(\\d+:\\d\\d:\\d\\d.\\d\\d),(\\d+:\\d\\d:\\d\\d.\\d\\d),([^,]*),([^,]*),(?:[^,]*,){4}([\\s\\S]*)$","i");function r(t=""){return t.split(/[:.]/).map((t,e,r)=>{if(e===r.length-1){if(1===t.length)return`.${t}00`;if(2===t.length)return`.${t}0`}else if(1===t.length)return(0===e?"0":":0")+t;return 0===e?t:e===r.length-1?`.${t}`:`:${t}`}).join("")}return`WEBVTT\n\n${t.split(/\r?\n/).map(t=>{const n=t.match(e);if(!n)return null;const[,o="",i="",,,a=""]=n;return{start:r(o.trim()),end:r(i.trim()),text:a.replace(/\{[\s\S]*?\}/g,"").replace(/(\\N)/g,"\n").trim().split(/\r?\n/).map(t=>t.trim()).join("\n")}}).filter(t=>t).map((t,e)=>t?`${e+1}\n${t.start} --\x3e ${t.end}\n${t.text}`:"").filter(t=>t.trim()).join("\n\n")}`}const Et=Object.freeze(Object.defineProperty({__proto__:null,ArtPlayerError:ot,addClass:V,append:H,assToVtt:$t,capitalize:dt,clamp:ct,createElement:J,debounce:function(t,e){let r;return function(...n){clearTimeout(r),r=setTimeout(()=>(r=void 0,t.apply(this,n)),e)}},def:gt,download:lt,errorHandle:it,escape:mt,get:bt,getComposedPath:rt,getExt:st,getIcon:Q,getRect:et,getSafeAreaInsets:nt,getStyle:function(t,e,r=!0){const n=window.getComputedStyle(t,null).getPropertyValue(e);return r?Number.parseFloat(n):n},has:yt,hasClass:B,includeFromEvent:K,inverseClass:X,isBrowser:_,isIOS:R,isIOS13:I,isInViewport:function(t,e=0){const r=t.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth,i=r.top-e<=n&&r.top+r.height+e>=0,a=r.left-e<=o+e&&r.left+r.width+e>=0;return i&&a},isMobile:N,isSafari:O,loadImg:function(t,e){return W(t,e,void 0)},mergeDeep:wt,query:F,queryAll:function(t,e=document){return Array.from(e.querySelectorAll(t))},remove:function(t){return t.parentNode.removeChild(t)},removeClass:Y,replaceElement:Z,secondToTime:ut,setStyle:j,setStyleText:D,setStyles:q,siblings:U,silencePromise:at,sleep:function(t=0){return new Promise(e=>setTimeout(e,t))},srtToVtt:xt,supportsFlex:tt,throttle:function(t,e){let r=!1;return function(...n){r||(t.apply(this,n),r=!0,setTimeout(()=>{r=!1},e))}},tooltip:G,unescape:function(t){return t.replace(ft,t=>ht[t]||t)},userAgent:A,vttToBlob:kt},Symbol.toStringTag,{value:"Module"}));function Tt(t,e){return H(t,e)}function Ct(t,e){return e.querySelector(t)}const Lt="array",St="boolean",Pt="string",Mt="number",zt="object",At="function";function Ot(t,e,r){return it(e===Pt||e===Mt||t instanceof Element,`${r.join(".")} require '${Pt}' or 'Element' type`)}const Rt={html:Ot,disable:`?${St}`,name:`?${Pt}`,index:`?${Mt}`,style:`?${zt}`,click:`?${At}`,mounted:`?${At}`,tooltip:`?${Pt}|${Mt}`,width:`?${Mt}`,selector:`?${Lt}`,onSelect:`?${At}`,switch:`?${St}`,onSwitch:`?${At}`,range:`?${Lt}`,onRange:`?${At}`,onChange:`?${At}`},It={id:Pt,container:Ot,url:Pt,poster:Pt,type:Pt,theme:Pt,lang:Pt,volume:Mt,isLive:St,muted:St,autoplay:St,autoSize:St,autoMini:St,loop:St,flip:St,playbackRate:St,aspectRatio:St,screenshot:St,setting:St,hotkey:St,pip:St,mutex:St,backdrop:St,fullscreen:St,fullscreenWeb:St,subtitleOffset:St,miniProgressBar:St,useSSR:St,playsInline:St,lock:St,gesture:St,fastForward:St,autoPlayback:St,autoOrientation:St,airplay:St,proxy:`?${At}`,plugins:[At],layers:[Rt],contextmenu:[Rt],settings:[Rt],controls:[c(l({},Rt),{position:(t,e,r)=>{const n=["top","left","right"];return it("string"===typeof t&&n.includes(t),`${r.join(".")} only accept ${n.toString()} as parameters`)}})],quality:[{default:`?${St}`,html:Pt,url:Pt}],highlight:[{time:Mt,text:Pt}],thumbnails:{url:Pt,number:Mt,column:Mt,width:Mt,height:Mt,scale:Mt},subtitle:{url:Pt,name:Pt,type:Pt,style:zt,escape:St,encoding:Pt,onVttLoad:At},moreVideoAttr:zt,i18n:zt,icons:zt,cssVar:zt,customType:zt},Nt=new WeakSet;class _t{constructor(t){this.id=0,this.art=t,this.cache=new Map,this.add=this.add.bind(this),this.remove=this.remove.bind(this),this.update=this.update.bind(this)}get show(){return B(this.art.template.$player,`art-${this.name}-show`)}set show(t){const{$player:e}=this.art.template,r=`art-${this.name}-show`;t?V(e,r):Y(e,r),this.art.emit(this.name,t)}toggle(){this.show=!this.show}add(t){var e;if(E(this.art))return;const r="function"===typeof t?t(this.art):t;if(E(this.art))return;if(r.html=r.html||"",m(r,Rt),!this.$parent||!this.name||r.disable)return;const n=r.name||`${this.name}${this.id}`,o=this.cache;it(!o.has(n),`Can't add an existing [${n}] to the [${this.name}]`),this.id+=1;const i=document.createElement("div"),a=L(this.art,i),s=[],l=Object.getOwnPropertyDescriptor(this,n);let c=!1;a.add(()=>{for(const t of s)this.art.events.remove(t)});try{if(a.closed)return;if(function(t,e,r,n,o,i){V(t,`art-${r}`),V(t,`art-${r}-${n}`);const a=Array.from(e.children);t.dataset.index=String(i.index||o);const s=a.find(e=>Number(e.dataset.index)>=Number(t.dataset.index));s?s.insertAdjacentElement("beforebegin",t):H(e,t),i.html&&H(t,i.html),i.style&&q(t,i.style),i.tooltip&&G(t,i.tooltip)}(i,this.$parent,this.name,n,this.id,r),a.closed)return;if(r.click){const t=this.art.events.proxy(i,"click",t=>{a.closed||(t.preventDefault(),r.click.call(this.art,this,t))});s.push(t)}if(r.selector&&["left","right"].includes(r.position)&&this.selector(r,i,s),a.closed)return;return function(t,e,r){const n=t;"__proto__"===e?Object.defineProperty(n,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[e]=r}(this,n,i),c=!0,o.set(n,{$ref:i,events:s,option:r}),r.mounted&&r.mounted.call(this.art,i),i}catch(d){try{P(i)}catch(u){console.warn("ArtPlayer component cleanup failed:",u)}throw(null==(e=o.get(n))?void 0:e.$ref)===i&&o.delete(n),c&&this[n]===i&&(l?Object.defineProperty(this,n,l):delete this[n]),i.remove(),d}}remove(t){it(this.cache.has(t),`Can't find [${t}] from the [${this.name}]`);const e=this.cache.get(t);if(!Nt.has(e)){Nt.add(e);try{e.option.beforeUnmount&&e.option.beforeUnmount.call(this.art,e.$ref);try{P(e.$ref)}finally{this.cache.get(t)===e&&(this.cache.delete(t),delete this[t]),e.$ref.remove()}}finally{Nt.delete(e)}}}update(t){if(this.cache.has(t.name)){const e=this.cache.get(t.name);t=Object.assign(e.option,t),this.remove(t.name)}return this.add(t)}}class Wt extends _t{constructor(t){super(t),this.name="contextmenu",this.$parent=t.template.$contextmenu,L(t,this.$parent),N||this.init()}init(){const{option:t,template:{$player:e,$contextmenu:r}}=this.art,{on:n,proxy:o}=z(this.art,r);t.playbackRate&&this.add(function(t){return e=>{const{i18n:r,constructor:{PLAYBACK_RATE:n}}=e,o=n.map(t=>`${1===t?r.get("Normal"):t.toFixed(1)}`).join("");return c(l({},t),{html:`${r.get("Play Speed")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.playbackRate=Number(n),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="1"]',t);n&&X(n,"art-current"),r("video:ratechange",()=>{const r=Array.from(t.querySelectorAll("span")).find(t=>Number(t.dataset.value)===e.playbackRate);r&&X(r,"art-current")})}})}}({name:"playbackRate",index:10})),t.aspectRatio&&this.add(function(t){return e=>{const{i18n:r,constructor:{ASPECT_RATIO:n}}=e,o=n.map(t=>`${"default"===t?r.get("Default"):t}`).join("");return c(l({},t),{html:`${r.get("Aspect Ratio")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.aspectRatio=n,t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="default"]',t);n&&X(n,"art-current"),r("aspectRatio",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&X(r,"art-current")})}})}}({name:"aspectRatio",index:20})),t.flip&&this.add(function(t){return e=>{const{i18n:r,constructor:{FLIP:n}}=e,o=n.map(t=>`${r.get(dt(t))}`).join("");return c(l({},t),{html:`${r.get("Video Flip")}: ${o}`,click:(t,r)=>{const n=r.target instanceof HTMLElement?r.target.dataset.value:void 0;n&&(e.flip=n.toLowerCase(),t.show=!1)},mounted:t=>{const{on:r}=z(e,t),n=F('[data-value="normal"]',t);n&&X(n,"art-current"),r("flip",e=>{const r=Array.from(t.querySelectorAll("span")).find(t=>t.dataset.value===e);r&&X(r,"art-current")})}})}}({name:"flip",index:30})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Video Info"),click:t=>{e.info.show=!0,t.show=!1}})}({name:"info",index:40})),this.add(function(t){return c(l({},t),{html:`ArtPlayer ${g}`})}({name:"version",index:50})),this.add(function(t){return e=>c(l({},t),{html:e.i18n.get("Close"),click:t=>{t.show=!1}})}({name:"close",index:60}));for(let i=0;i{if(!this.art.constructor.CONTEXTMENU)return;t.preventDefault(),this.show=!0;const n=t.clientX,o=t.clientY,{height:i,width:a,left:s,top:l}=et(e),{height:c,width:d}=et(r);let u=n-s,p=o-l;n+d>s+a&&(u=a-d),o+c>l+i&&(p=i-c),q(r,{top:`${p}px`,left:`${u}px`})}),o(e,"click",t=>{K(t,r)||(this.show=!1)}),n("blur",()=>{this.show=!1})}}function Dt(t,e,r,n,o={}){const{capture:i=!1,once:a=!1,signal:s}=o;if(t.closed||(null==s?void 0:s.aborted))return()=>{};let l=()=>{};function c(e){a&&l(),t.closed||("function"===typeof n?n.call(this,e):n.handleEvent(e))}return e.addEventListener(r,c,o),l=t.add(()=>{try{e.removeEventListener(r,c,i)}finally{null==s||s.removeEventListener("abort",l)}}),null==s||s.addEventListener("abort",l,{once:!0}),l}function Ft(t,e,r){if(t.closed)return()=>{};let n=!0,o=()=>{};const i=setTimeout(()=>{n&&(o(),t.closed||e())},r);return o=t.add(()=>{n=!1,clearTimeout(i)}),o}function Vt(t,e=0){return t.closed?Promise.resolve(!1):new Promise(r=>{let n=!1,o=()=>{};const i=setTimeout(()=>{n=!0,o(),r(!0)},e);o=t.add(()=>{clearTimeout(i),n||r(!1)})})}const Yt=new WeakMap,Bt=new WeakMap,Ht=new WeakMap;function jt(t){return Ht.get(t)||$(t)}function qt(t){const e=Yt.get(t),r=Ht.get(t);return()=>Yt.get(t)===e&&(!e||e.active())&&Ht.get(t)===r&&(!r||!r.closed)}function Ut(t){const e=Ht.get(t),r=$(t).child(),n=r.child();Ht.set(t,r),r.add(()=>{Ht.get(t)===r&&Ht.delete(t)});const o={scope:n,assigned:!1,acceptingEvents:!1,active:()=>!E(t)&&!n.closed&&Yt.get(t)===o};return Yt.set(t,o),n.add(()=>{Yt.get(t)===o&&Yt.delete(t),o.onAssigned=void 0,o.onError=void 0}),null==e||e.dispose(),o}function Xt(t){t.assigned=!0;const e=t.onAssigned;t.onAssigned=void 0,t.active()&&(null==e||e())}function Gt(t,e,r){Bt.set(t,e),e.acceptingEvents=!0;try{t.url=r}finally{Bt.get(t)===e&&(Bt.delete(t),Xt(e))}}function Kt(t,e){t.active()&&(t.onError?t.onError(e):console.warn("Failed to initialize ArtPlayer source:",e),t.scope.dispose())}function Zt(t,e){const{$progress:r}=t.template,{left:n}=et(r),o=ct((N?e.touches[0].clientX:e.clientX)-n,0,r.clientWidth),i=o/r.clientWidth*t.duration;return{second:i,time:ut(i),width:o,percentage:ct(o/r.clientWidth,0,1)}}function Jt(t,e,r=()=>!0){if(r())if(t.isRotate){const n=(e.touches[0].clientY-t.top)/t.height,o=n*t.duration;if(!r())return;t.emit("setBar","played",n,e),r()&&(t.seek=o)}else{const{second:n,percentage:o}=Zt(t,e);if(!r())return;t.emit("setBar","played",o,e),r()&&(t.seek=n)}}function Qt(t,e){const{icons:r,option:n}=t,{$player:o}=t.template,i=S(e),{on:a}=z(t,e);let s=()=>{};const l=Ct(".art-progress-hover",e),c=Ct(".art-progress-loaded",e),d=Ct(".art-progress-played",e),u=Ct(".art-progress-highlight",e),p=Ct(".art-progress-indicator",e),h=Ct(".art-progress-tip",e);function f(r,n){const{width:o,time:i}=n||Zt(t,r);h.textContent=i||"00:00";const a=h.clientWidth;o<=a/2?j(h,"left",0):o>e.clientWidth-a/2?j(h,"left",e.clientWidth-a+"px"):j(h,"left",o-a/2+"px")}r.indicator?H(p,r.indicator):j(p,"backgroundColor","var(--art-theme)"),a("setBar",function(r,n,a){const m="played"===r&&a&&N;if("loaded"===r&&j(c,"width",100*n+"%"),"hover"===r&&(j(l,"width",100*n+"%"),K(a,u)?function(r){const{width:n}=Zt(t,r),o=r.target instanceof HTMLElement?r.target.dataset.text:void 0;h.textContent=null!=o?o:"";const i=h.clientWidth;n<=i/2?j(h,"left",0):n>e.clientWidth-i/2?j(h,"left",e.clientWidth-i+"px"):j(h,"left",n-i/2+"px")}(a):f(a),0===n?Y(o,"art-progress-hover"):V(o,"art-progress-hover")),"played"===r&&(j(d,"width",100*n+"%"),j(p,"left",100*n+"%")),m){V(o,"art-progress-hover");f(a,{width:e.clientWidth*n,time:ut(n*t.duration)}),s(),s=Ft(i,()=>{Y(o,"art-progress-hover")},500)}}),a("video:loadedmetadata",function(){u.textContent="";for(let e=0;e{t.emit("setBar","played",t.played),t.emit("setBar","loaded",t.loaded)}):(a("video:timeupdate",()=>{t.emit("setBar","played",t.played)}),a("video:progress",()=>{t.emit("setBar","loaded",t.loaded)}),a("video:ended",()=>{t.emit("setBar","played",1)})),t.emit("setBar","loaded",t.loaded||0)}function te(t){return e=>c(l({},t),{html:'\n
\n
\n
\n
\n
\n
\n
00:00
\n
\n ',mounted:t=>{Qt(e,t),function(t,e){const{$progress:r}=t.template,n=e.querySelector(".art-progress-indicator"),{on:o,proxy:i}=z(t,e),a=S(e);let s=0;const l=()=>{const e=qt(t);return()=>!a.closed&&!E(t)&&e()},c=()=>{const t=++s,e=l();return()=>t===s&&e()};if(!N){let e;i(r,"click",e=>{e.target!==n&&Jt(t,e,c())}),i(r,"mousemove",e=>{const r=l(),{percentage:n}=Zt(t,e);r()&&t.emit("setBar","hover",n,e)}),i(r,"mouseleave",e=>{t.emit("setBar","hover",0,e)}),i(r,"mousedown",t=>{e=0===t.button?c():void 0}),o("document:mousemove",r=>{const n=e;if(null==n?void 0:n()){const{second:o,percentage:i}=Zt(t,r);if(!n()||e!==n)return;t.emit("setBar","played",i,r),n()&&e===n&&(t.seek=o)}else e=void 0}),o("document:mouseup",()=>{e=void 0})}}(e,t)}})}function ee(t){const{option:e}=t.art;e.isLive||t.add(te({name:"progress",position:"top",index:10})),t.add({name:"thumbnails",position:"top",index:20}),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.play),s=Tt(t,o.pause);function l(){j(a,"display","flex"),j(s,"display","none")}function c(){j(a,"display","none"),j(s,"display","flex")}G(a,i.get("Play")),G(s,i.get("Pause")),n(a,"click",()=>{at(e.play())}),n(s,"click",()=>{e.pause()}),e.playing?c():l(),r("video:playing",()=>{c()}),r("video:pause",()=>{l()})}})}({name:"playAndPause",position:"left",index:10})),t.add(function(t){return e=>c(l({},t),{mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o}=e,i=Tt(t,o.volume),a=Tt(t,o.volumeClose),s=Tt(t,'
'),l=Tt(s,'
'),c=Tt(l,'
'),d=Tt(l,'
'),u=Tt(d,'
'),p=Tt(u,'
'),h=Tt(d,'
');function f(t){const{top:e,height:r}=et(d);return 1-(t.clientY-e)/r}function m(){if(e.muted||0===e.volume)j(i,"display","none"),j(a,"display","flex"),j(h,"top","100%"),j(p,"top","100%"),c.textContent="0";else{const t=100*e.volume;j(i,"display","flex"),j(a,"display","none"),j(h,"top",100-t+"%"),j(p,"top",100-t+"%"),c.textContent=String(Math.floor(t))}}if(m(),r("video:volumechange",m),n(i,"click",()=>{e.muted=!0}),n(a,"click",()=>{e.muted=!1}),N)j(s,"display","none");else{let t=!1;n(d,"mousedown",r=>{t=0===r.button,e.volume=f(r)}),r("document:mousemove",r=>{t&&(e.muted=!1,e.volume=f(r))}),r("document:mouseup",()=>{t&&(t=!1)})}}})}({name:"volume",position:"left",index:20})),e.isLive||t.add(function(t){return e=>c(l({},t),{style:N?{fontSize:"12px",padding:"0 5px"}:{cursor:"auto",padding:"0 10px"},mounted:t=>{const{on:r}=z(e,t);function n(){const r=`${ut(e.currentTime)} / ${ut(e.duration)}`;r!==t.textContent&&(t.textContent=r)}n();const o=["video:loadedmetadata","video:timeupdate","video:progress"];for(let e=0;e{r&&!$(t.art).closed&&(t.art.quality=e.quality)}).catch(t=>{console.warn("ArtPlayer quality initialization failed:",t)}),e.screenshot&&!N&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Screenshot"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Tt(t,n.screenshot),r(t,"click",()=>{at(e.screenshot())})}})}({name:"screenshot",position:"right",index:20})),e.setting&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Show Setting"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Tt(t,o.setting),n(t,"click",()=>{e.setting.toggle(),e.setting.resize()}),r("setting",e=>{G(t,i.get(e?"Hide Setting":"Show Setting"))})}})}({name:"setting",position:"right",index:30})),e.pip&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("PIP Mode"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e;Tt(t,o.pip),n(t,"click",()=>{e.pip=!e.pip}),r("pip",e=>{G(t,i.get(e?"Exit PIP Mode":"PIP Mode"))})}})}({name:"pip",position:"right",index:40})),e.airplay&&"WebKitPlaybackTargetAvailabilityEvent"in window&&window.WebKitPlaybackTargetAvailabilityEvent&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("AirPlay"),mounted:t=>{const{proxy:r}=z(e,t),{icons:n}=e;Tt(t,n.airplay),r(t,"click",()=>e.airplay())}})}({name:"airplay",position:"right",index:50})),e.fullscreenWeb&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Web Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenWebOn),s=Tt(t,o.fullscreenWebOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreenWeb=!e.fullscreenWeb}),r("fullscreenWeb",e=>{e?(G(t,i.get("Exit Web Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(G(t,i.get("Web Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreenWeb",position:"right",index:60})),e.fullscreen&&t.add(function(t){return e=>c(l({},t),{tooltip:e.i18n.get("Fullscreen"),mounted:t=>{const{on:r,proxy:n}=z(e,t),{icons:o,i18n:i}=e,a=Tt(t,o.fullscreenOn),s=Tt(t,o.fullscreenOff);j(s,"display","none"),n(t,"click",()=>{e.fullscreen=!e.fullscreen}),r("fullscreen",e=>{e?(G(t,i.get("Exit Fullscreen")),j(a,"display","none"),j(s,"display","inline-flex")):(G(t,i.get("Fullscreen")),j(a,"display","inline-flex"),j(s,"display","none"))})}})}({name:"fullscreen",position:"right",index:70}));for(let r=0;rne.get(t).option.selector}),gt(t,"$control_item",{get:()=>ne.get(t).item}),gt(t,"$control_value",{get:()=>ne.get(t).value})),ne.set(t,e)}function ie(t,e){t.innerHTML=e}function ae(t,e,r,n,o){const{proxy:i}=t.events,a=S(n),s=r.selector;V(n,"art-control-selector");const l=document.createElement("div");V(l,"art-selector-value"),H(l,r.html),n.textContent="",H(n,l);const c=Tt(n,'
');for(let d=0;dd(null,null,function*(){if(a.closed)return;const o=rt(n),i=r.selector.find(t=>o.includes(t.$control_item));if(!i)return;const s=++u,c=()=>!a.closed&&s===u,d=a.add(function(t,e){return re.set(t,e),()=>{re.get(t)===e&&re.delete(t)}}(n,c));try{if(e(i),a.closed)return;if(r.onSelect){const e=yield r.onSelect.call(t,i,i.$control_item,n);c()&&ie(l,e)}}catch(p){console.warn("ArtPlayer selector failed:",p)}finally{d()}}));o.push(p)}class se extends _t{constructor(t){super(t),this.isHover=!1,this.name="control",this.timer=Date.now();const{constructor:e}=t,{$player:r,$bottom:n}=this.art.template;L(t,n);const{on:o}=z(t,n);o("mousemove",()=>{N||(this.show=!0)}),o("click",()=>{N?this.toggle():this.show=!0}),o("document:mousemove",t=>{this.isHover=K(t,n)}),o("video:timeupdate",()=>{!t.setting.show&&!this.isHover&&!t.isInput&&t.playing&&this.show&&Date.now()-this.timer>=e.CONTROL_HIDE_TIME&&(this.show=!1)}),o("control",t=>{t?(Y(r,"art-hide-cursor"),V(r,"art-hover"),this.timer=Date.now()):(V(r,"art-hide-cursor"),Y(r,"art-hover"))}),this.init(),$(t).closed||function(t){const{$bottom:e,$controls:r,$player:n}=t.template,o=S(e),{on:i}=z(t,e),a=()=>{if(o.closed)return;const t=r.offsetHeight;t>0&&n.style.getPropertyValue("--art-controls-height")!==`${t}px`&&n.style.setProperty("--art-controls-height",`${t}px`)};if(i("resize",a),"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(a);t.observe(r),o.add(()=>{t.disconnect()})}else if("undefined"!==typeof MutationObserver){const t=new MutationObserver(a);t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o.add(()=>{t.disconnect()})}a()}(t)}init(){ee(this)}add(t){if(E(this.art))return;const e="function"===typeof t?t(this.art):t,{$progress:r,$controlsLeft:n,$controlsRight:o}=this.art.template;switch(e.position){case"top":this.$parent=r;break;case"left":this.$parent=n;break;case"right":this.$parent=o;break;default:it(!1,"Control option.position must one of 'top', 'left', 'right'")}super.add(e)}check(t){!function(t){if(t){ie(t.$control_value,t.html);for(let e=0;ethis.check(t),t,e,r)}}function le(t,e){const{constructor:r,template:{$video:n}}=t;!function(t){const{$player:e}=t.template,r=r=>{var n;if(E(t))return;const o=K(r,e);t.isInput=o&&"INPUT"===(null==(n=r.target)?void 0:n.tagName),t.isFocus=o,t.emit(o?"focus":"blur",r)};t.on("document:click",r),t.on("document:contextmenu",r),$(t).add(()=>{t.off("document:click",r),t.off("document:contextmenu",r)})}(t);let o=[];e.proxy(n,"click",e=>{if(E(t))return;const n=Date.now();o.push(n);const{MOBILE_CLICK_PLAY:i,DBCLICK_TIME:a,MOBILE_DBCLICK_PLAY:s,DBCLICK_FULLSCREEN:l}=r,c=o.filter(t=>n-t<=a);switch(c.length){case 1:if(t.emit("click",e),E(t))return;(!N||!t.isLock&&i)&&at(t.toggle()),o=c;break;case 2:if(t.emit("dblclick",e),E(t))return;N?!t.isLock&&s&&at(t.toggle()):l&&(t.fullscreen=!t.fullscreen),o=[];break;default:o=[]}})}function ce(t){let e;const r=()=>{e=void 0},n=r=>e===r&&!E(t)&&!t.isLock&&!t.option.isLive&&t.isRotate===r.rotated&&r.sourceActive(),o=t=>{t&&r()};t.on("document:touchend",r),t.on("document:touchcancel",r),t.on("lock",o),$(t).add(()=>{r(),t.off("document:touchend",r),t.off("document:touchcancel",r),t.off("lock",o)});return{start:(o,i)=>{r();const a=i.touches[0];if(E(t)||t.isLock||t.option.isLive||1!==i.touches.length||!a)return;if(![a.pageX,a.pageY,a.clientX,a.clientY,t.currentTime].every(Number.isFinite))return;const s={target:o,identifier:a.identifier,x:a.pageX,y:a.pageY,time:t.currentTime,rotated:t.isRotate,sourceActive:qt(t)};if(e=s,o===t.template.$progress){const o=t.isRotate?t.height:t.template.$progress.clientWidth;if(!Number.isFinite(o)||o<=0||!Number.isFinite(t.duration)||t.duration<=0)return void r();try{Jt(t,i,()=>n(s))}catch(l){throw e===s&&r(),l}n(s)&&(s.time=t.currentTime)}},move:o=>{const i=e,a=o.touches[0];if(!i)return;if(!n(i)||1!==o.touches.length||!a||a.identifier!==i.identifier)return void r();const s=i.rotated?t.height:t.width,l=i.target===t.template.$video?t.constructor.TOUCH_MOVE_RATIO:1;if(![a.pageX,a.pageY,s,t.duration,l].every(Number.isFinite)||s<=0||t.duration<=0)return void r();const c=function(t,e,r,n){const o=e-n,i=r-t;if(Math.abs(i)<2&&Math.abs(o)<2)return 0;const a=180*Math.atan2(o,i)/Math.PI;return a>=-45&&a<45?4:a>=45&&a<135?1:a>=-135&&a<-45?2:a>=135&&a<=180||a>=-180&&a<-135?3:0}(i.x,i.y,a.pageX,a.pageY);if(!(i.rotated?1===c||2===c:3===c||4===c))return;const d=ct((i.rotated?a.pageY-i.y:a.pageX-i.x)/s,-1,1),u=ct(i.time+t.duration*d*l,0,t.duration);t.seek=u,n(i)&&(t.emit("setBar","played",ct(u/t.duration,0,1),o),n(i)&&(t.notice.show=`${ut(u)} / ${ut(t.duration)}`))},cancel:r}}const de=["click","mouseup","keydown","touchend","touchcancel","touchmove","mousemove","pointerup","contextmenu","pointermove","visibilitychange","webkitfullscreenchange"],ue=["resize","scroll","orientationchange"];const pe=new WeakMap;function he(t){const e=pe.get(t);if(!e)throw new Error("ArtPlayer event registry has not been initialized");return e}function fe(t,e,r,n,o={}){if(Array.isArray(r)){const i=[];try{return r.map(r=>{const a=fe(t,e,r,n,o);return i.push(a),a})}catch(h){for(const t of i.reverse())try{t()}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}}const i=r,a=he(t);if(a.scope.closed||a.cleaning)return()=>{};const s="boolean"===typeof o?o:{capture:Boolean(null==o?void 0:o.capture),once:Boolean(null==o?void 0:o.once),passive:null==o?void 0:o.passive,signal:null==o?void 0:o.signal},l="boolean"===typeof s?s:s.capture,c="boolean"===typeof s?void 0:s.signal;if(a.scope.closed||a.cleaning||(null==c?void 0:c.aborted))return()=>{};let d=!0;function u(r=!1){(d||r)&&(e.removeEventListener(i,n,l),null==c||c.removeEventListener("abort",p),d=!1,t.destroyEvents.delete(p))}function p(){u()}t.destroyEvents.add(p);try{e.addEventListener(i,n,s),!d||a.scope.closed||a.cleaning?u(!0):(null==c?void 0:c.aborted)?p():null==c||c.addEventListener("abort",p,{once:!0})}catch(h){try{u(!0)}catch(f){console.warn("Failed to roll back event listener:",f)}throw h}return p}function me(t){return(e,r)=>{if(E(t))return;const n=(...e)=>{if(!E(t))return r(...e)};t.on(e,n),$(t).add(()=>{t.off(e,n)})}}function ge(t){if(!t.constructor.USE_RAF)return;const e=$(t);let r=()=>{};const n=()=>{E(t)||(t.playing&&t.emit("raf"),E(t)||(r=function(t,e){if(t.closed)return()=>{};let r=!0,n=()=>{};const o=requestAnimationFrame(o=>{r&&(n(),t.closed||e(o))});return n=t.add(()=>{r=!1,cancelAnimationFrame(o)}),n}(e,n)))};n(),me(t)("destroy",()=>r())}class ve{constructor(t){this.destroyEvents=new Set,function(t,e){pe.set(t,{scope:$(e),cleaning:!1})}(this,t),$(t).add(()=>{this.destroy()}),this.proxy=this.proxy.bind(this),this.hover=this.hover.bind(this),le(t,this),function(t,e){const{$player:r}=t.template;e.hover(r,e=>{E(t)||(V(r,"art-hover"),t.emit("hover",!0,e))},e=>{E(t)||(Y(r,"art-hover"),t.emit("hover",!1,e))})}(t,this),function(t,e){const{$player:r}=t.template;e.proxy(r,"mousemove",e=>{E(t)||t.emit("mousemove",e)})}(t,this),function(t,e){var r,n;const{option:o,constructor:i}=t,a=me(t);a("resize",()=>{const{aspectRatio:e,notice:r}=t;"standard"===t.state&&o.autoSize&&t.autoSize(),E(t)||(t.aspectRatio=e,E(t)||(r.show=""))});const s=$(t);let l=()=>{};const c=()=>{E(t)||(l(),l=Ft(s,()=>t.emit("resize"),i.RESIZE_TIME))};a("window:orientationchange",c),a("window:resize",c);const d=null==(n=null==(r=t.template.$player.ownerDocument.defaultView)?void 0:r.screen)?void 0:n.orientation;"function"===typeof(null==d?void 0:d.addEventListener)&&e.proxy(d,"change",c)}(t,this),function(t,e){if(!N||t.option.isLive)return;const{$video:r,$progress:n}=t.template,o=ce(t),i=t=>{e.proxy(t,"touchstart",e=>o.start(t,e)),e.proxy(t,"touchmove",t=>o.move(t)),e.proxy(t,"touchcancel",o.cancel)};t.option.gesture&&i(r),i(n)}(t,this),function(t){const{option:e,constructor:r,template:{$container:n}}=t,o=r.SCROLL_TIME,i=$(t),a=me(t);let s=!1;a("window:scroll",()=>{s||(t.emit("view",function(t,e){const r=t.getBoundingClientRect(),n=t.ownerDocument,o=n.defaultView,i=(null==o?void 0:o.innerHeight)||n.documentElement.clientHeight,a=(null==o?void 0:o.innerWidth)||n.documentElement.clientWidth,s=r.top-e<=i&&r.top+r.height+e>=0,l=r.left-e<=a+e&&r.left+r.width+e>=0;return s&&l}(n,r.SCROLL_GAP)),E(t)||(s=!0,Ft(i,()=>{s=!1},o)))}),a("view",r=>{e.autoMini&&(t.mini=!r)})}(t),function(t,e){let r,n=0;$(t).add(()=>{r=void 0,n++});const o=t=>{if(t){for(const r of t.disposers)e.remove(r);t.disposers.length=0}};function i(i={}){var a;if(E(t))return;const s=++n,l={disposers:[]},c=()=>s!==n||E(t);try{const{$player:n}=t.template,o=i.document||n.ownerDocument||document,s=i.window||(null==(a=n.ownerDocument)?void 0:a.defaultView)||window,d=(n,o,i)=>{for(const a of o){if(c())return;l.disposers.push(e.proxy(n,a,e=>{r!==l||E(t)||t.emit(`${i}:${a}`,e)}))}};d(o,de,"document"),d(s,ue,"window")}catch(u){throw o(l),u}if(c())return void o(l);const d=r;r=l,o(d)}i(),e.bindGlobalEvents=i}(t,this),ge(t)}proxy(t,e,r,n={}){return Array.isArray(e),fe(this,t,e,r,n)}hover(t,e,r){e&&this.proxy(t,"mouseenter",e),r&&this.proxy(t,"mouseleave",r)}remove(t){!function(t,e){if(t.destroyEvents.has(e))try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to remove event listener:",r)}}(this,t)}destroy(){!function(t){const e=he(t);if(!e.cleaning){e.cleaning=!0;try{for(const e of t.destroyEvents)try{e(),t.destroyEvents.delete(e)}catch(r){console.warn("Failed to destroy event listener:",r)}}finally{e.cleaning=!1}}}(this)}}function ye(t){if(t&&1===t.nodeType)return t}function be(t){const e=t.tagName.toUpperCase();return"INPUT"===e||"TEXTAREA"===e||"SELECT"===e||t.isContentEditable}const we=new WeakMap;class xe{constructor(t){this.art=t,this.keys={},we.set(this,{subscribed:!1}),N||this.init()}init(){const t=this.art;if(E(t))return;const e=we.get(this);if(t.option.hotkey){if(!e.defaults){const r=function(t){const{constructor:e}=t;return{Escape:()=>{t.fullscreenWeb&&(t.fullscreenWeb=!1)},Space:()=>{at(t.toggle())},ArrowLeft:()=>{t.backward=e.SEEK_STEP},ArrowUp:()=>{t.volume+=e.VOLUME_STEP},ArrowRight:()=>{t.forward=e.SEEK_STEP},ArrowDown:()=>{t.volume-=e.VOLUME_STEP}}}(t);e.defaults=()=>{for(const t of Object.keys(r))this.add(t,r[t])}}e.defaults()}if(e.subscribed)return;e.subscribed=!0;const r=e=>{if(!E(t)){if(t.isFocus&&function(t,e){var r,n;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.isComposing||229===t.keyCode)return!1;const o=function(t,e){var r;const n=t.target;return 9===(null==n?void 0:n.nodeType)?n:(null==n?void 0:n.ownerDocument)||(null==(r=t.view)?void 0:r.document)||e}(t,e);let i=ye(o.activeElement);for(;null==(r=null==i?void 0:i.shadowRoot)?void 0:r.activeElement;)i=ye(i.shadowRoot.activeElement);if(i&&be(i))return!1;const a=ye(null==(n=t.composedPath)?void 0:n.call(t)[0])||ye(t.target);return!a||!be(a)}(e,t.template.$player.ownerDocument)){const r=Object.prototype.hasOwnProperty.call(this.keys,e.code)?this.keys[e.code]:void 0;if(r){e.preventDefault();for(let n=0;n{e.subscribed=!1,t.off("document:keydown",r)})}add(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;return r?r.includes(e)||r.push(e):Object.defineProperty(this.keys,t,{value:[e],enumerable:!0,configurable:!0,writable:!0}),this}remove(t,e){const r=Object.prototype.hasOwnProperty.call(this.keys,t)?this.keys[t]:void 0;if(r){const n=r.indexOf(e);-1!==n&&r.splice(n,1),0===r.length&&delete this.keys[t]}return this}}const ke={"Video Info":"\u7edf\u8ba1\u4fe1\u606f",Close:"\u5173\u95ed","Video Load Failed":"\u52a0\u8f7d\u5931\u8d25",Volume:"\u97f3\u91cf",Play:"\u64ad\u653e",Pause:"\u6682\u505c",Rate:"\u901f\u5ea6",Mute:"\u9759\u97f3","Video Flip":"\u753b\u9762\u7ffb\u8f6c",Horizontal:"\u6c34\u5e73",Vertical:"\u5782\u76f4",Reconnect:"\u91cd\u65b0\u8fde\u63a5","Show Setting":"\u663e\u793a\u8bbe\u7f6e","Hide Setting":"\u9690\u85cf\u8bbe\u7f6e",Screenshot:"\u622a\u56fe","Play Speed":"\u64ad\u653e\u901f\u5ea6","Aspect Ratio":"\u753b\u9762\u6bd4\u4f8b",Default:"\u9ed8\u8ba4",Normal:"\u6b63\u5e38",Open:"\u6253\u5f00","Switch Video":"\u5207\u6362","Switch Subtitle":"\u5207\u6362\u5b57\u5e55",Fullscreen:"\u5168\u5c4f","Exit Fullscreen":"\u9000\u51fa\u5168\u5c4f","Web Fullscreen":"\u7f51\u9875\u5168\u5c4f","Exit Web Fullscreen":"\u9000\u51fa\u7f51\u9875\u5168\u5c4f","Mini Player":"\u8ff7\u4f60\u64ad\u653e\u5668","PIP Mode":"\u5f00\u542f\u753b\u4e2d\u753b","Exit PIP Mode":"\u9000\u51fa\u753b\u4e2d\u753b","PIP Not Supported":"\u4e0d\u652f\u6301\u753b\u4e2d\u753b","Fullscreen Not Supported":"\u4e0d\u652f\u6301\u5168\u5c4f","Subtitle Offset":"\u5b57\u5e55\u504f\u79fb","Last Seen":"\u4e0a\u6b21\u770b\u5230","Jump Play":"\u8df3\u8f6c\u64ad\u653e",AirPlay:"\u9694\u7a7a\u64ad\u653e","AirPlay Not Available":"\u9694\u7a7a\u64ad\u653e\u4e0d\u53ef\u7528"};!function(t,e){if("undefined"!==typeof window){window[t]=e}}("artplayer-i18n-zh-cn",ke);class $e{constructor(t){this.art=t,this.languages={"zh-cn":ke},this.language={},this.update(t.option.i18n)}init(){const t=this.art.option.lang.toLowerCase();this.language=yt(this.languages,t)&&this.languages[t]||{}}get(t){return yt(this.language,t)&&this.language[t]||t}update(t){this.languages=wt(this.languages,t),this.init()}}const Ee={loading:'\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n',state:'\r\n\r\n\r\n',play:'\r\n \r\n',pause:'\r\n \r\n',check:'\r\n\r\n',volume:'\r\n \r\n \r\n',volumeClose:'\r\n \r\n \r\n',screenshot:'\r\n\t\r\n\r\n',setting:'\r\n \r\n \r\n',pip:'\r\n\r\n',arrowLeft:'\r\n \r\n',arrowRight:'\r\n \r\n',playbackRate:'',aspectRatio:'',config:'',lock:'\r\n\r\n\r\n\r\n\r\n',flip:'\r\n\r\n\r\n\r\n\r\n\r\n',unlock:'\r\n\r\n\r\n',fullscreenOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenOn:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOff:'\r\n\r\n\r\n\r\n\r\n',fullscreenWebOn:'\r\n\r\n\r\n\r\n\r\n',switchOn:'\r\n\r\n\r\n \r\n',switchOff:'\r\n\r\n\r\n \r\n\r\n',error:'\r\n\r\n\r\n\r\n\r\n',close:'\r\n\r\n\r\n\r\n\r\n',airplay:'\r\n \r\n \r\n \r\n \r\n\r\n'};class Te{constructor(t){const e=l(l({},Ee),t.option.icons);for(const r in e)gt(this,r,{get:()=>Q(r,e[r])})}}const Ce=new WeakMap;class Le extends _t{constructor(t){super(t),this.name="info",Ce.set(this,{revision:0}),N||this.init()}init(){var t;const e=Ce.get(this),r=++e.revision;if(null==(t=e.scope)||t.dispose(),E(this.art)||e.revision!==r)return;const n=$(this.art).child();e.scope=n,n.add(()=>{e.scope===n&&(e.scope=void 0)}),function(t,e,r){const n=()=>!e.closed&&!E(t),o=t=>{try{e.dispose()}catch(r){console.warn("Failed to release info polling resources:",r)}throw t};try{const{proxy:i,constructor:a,template:{$infoPanel:s,$infoClose:l,$video:c}}=t,d=i(l,"click",()=>{n()&&r()});e.add(()=>{t.events.remove(d)});const u=Array.from(s.querySelectorAll("[data-video]")),p=()=>e.dispose();t.on("destroy",p),e.add(()=>{t.off("destroy",p)});const h=()=>{var t;try{for(const e of u){if(!n())return;const r=Reflect.get(c,null!=(t=e.dataset.video)?t:"undefined");if(!n())return;const o="number"===typeof r?r.toFixed(2):r;if(!n())return;if(e.textContent!==o){const t=null==o?null:`${o}`;if(!n())return;e.textContent=t}}n()&&Ft(e,h,a.INFO_LOOP_TIME)}catch(r){o(r)}};n()&&h()}catch(i){o(i)}}(this.art,n,()=>{this.show=!1})}}class Se extends _t{constructor(t){super(t);const{option:e,template:{$layer:r}}=t;this.name="layer",this.$parent=r;for(let n=0;n{j(i,"display","none"),j(s,"display",null),E(t)&&(l=!0)};var d;t.on("destroy",c),(d=t,k(d).finalizers).add(()=>{try{l||c()}finally{t.off("destroy",c)}}),E(t)||n.proxy(e.$state,"click",()=>{E(t)||at(t.play())})}}const ze=new WeakMap;function Ae(t){const e=ze.get(t);e.revision++,e.pending=void 0,null!==t.timer&&(clearTimeout(t.timer),t.timer=null)}class Oe{constructor(t){this.art=t,this.timer=null,ze.set(this,{revision:0});const e=()=>this.destroy();t.on("destroy",e),$(t).add(()=>{t.off("destroy",e)}),$(t).add(()=>{this.destroy()})}destroy(){Ae(this)}set show(t){if(E(this.art))return;const e=ze.get(this);e.revision++;const{constructor:r,template:{$player:n,$noticeInner:o}}=this.art;if(t){Ae(this);const i=e.revision,a=()=>!E(this.art)&&e.revision===i;if(o.textContent=t instanceof Error?t.message.trim():t,!a())return;if(V(n,"art-notice-show"),!a())return;const s=r.NOTICE_TIME;if(!a())return;const l={};e.pending=l;const c=setTimeout(()=>{if(E(this.art)||e.pending!==l)return;e.pending=void 0;const t=e.revision;o.textContent="",E(this.art)||e.revision!==t||Y(n,"art-notice-show")},s);a()?this.timer=c:clearTimeout(c)}else Y(n,"art-notice-show")}get show(){const{template:{$player:t}}=this.art;return t.classList.contains("art-notice-show")}}function Re({width:t,height:e}){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0}function Ie(t,e){if(!Re(t)||!Number.isFinite(e)||e<=0)return;const r=t.width/t.height>e?{width:e*t.height,height:t.height,axis:"width"}:{width:t.width,height:t.width/e,axis:"height"};return Re(r)?r:void 0}function Ne(t){const{$container:e,$video:r}=t.template;gt(t,"autoHeight",{value(){if(E(t))return;const n=function(t,e){if(!Number.isFinite(t)||t<=0||!Re(e))return;const r=e.height*(t/e.width);return Number.isFinite(r)&&r>0?r:void 0}(e.clientWidth,{width:r.videoWidth,height:r.videoHeight});void 0===n||E(t)||(e.style.height=`${n}px`,t.emit("autoHeight",n))}})}const _e=new WeakMap;function We(t){return _e.get(t)||0}function De(t){const{$video:e}=t.template;gt(t,"currentTime",{get:()=>e.currentTime||0,set:r=>{const n=Number.parseFloat(r);Number.isNaN(n)||(!function(t){_e.set(t,We(t)+1)}(t),e.currentTime=ct(n,0,t.duration))}})}function Fe(t,e,r,n=!1){const o=e=>{E(t)||r(e)};t[n?"once":"on"](e,o),$(t).add(()=>{t.off(e,o)})}function Ve(t,e,r){for(const[n,o]of e){if(E(t)||r&&!r())return;t[n].show=o}}function Ye(t){const{option:e,constructor:r,i18n:n,notice:o,template:{$player:i}}=t;let a,s=jt(t),l=0;return{reset(){l=0,null==a||a.dispose(),Y(i,"art-error")},loadStart(){Y(i,"art-error")},schedule(c){(c=>d(null,null,function*(){if(E(t))return;const d=jt(t);if(d!==s&&(s=d,l=0),a&&!a.closed)return;const u=d.child();a=u,u.add(()=>{a===u&&(a=void 0)});const p=()=>!E(t)&&!u.closed&&d===jt(t),h=l{console.warn("ArtPlayer reconnect failed:",t)})}}}function Be(t){!function(t){const{proxy:e,template:{$video:r}}=t;for(let n=0;n{E(t)||t.emit(`video:${e.type}`,e)})}(t);const e=Ye(t);!function(t,e){Fe(t,"video:canplay",()=>{e.reset(),Ve(t,[["loading",!1]])}),Fe(t,"video:canplay",()=>{Ve(t,[["loading",!1],["controls",!0],["mask",!0]]),E(t)||(t.isReady=!0,t.emit("ready"))},!0)}(t,e),function(t){const{option:e}=t;Fe(t,"video:ended",()=>{if(e.loop){const e=qt(t);if(t.seek=0,E(t)||!e())return;at(t.play()),e()&&Ve(t,[["controls",!1],["mask",!1]],e)}else Ve(t,[["controls",!0],["mask",!0]])})}(t),Fe(t,"video:error",e.schedule),function(t,e){const{template:{$poster:r}}=t;Fe(t,"video:loadedmetadata",()=>{t.emit("resize"),N&&Ve(t,[["loading",!1],["controls",!0],["mask",!0]])}),Fe(t,"video:loadstart",()=>{e.loadStart(),Ve(t,[["loading",!0],["mask",!1],["controls",!0]])}),Fe(t,"video:pause",()=>{Ve(t,[["controls",!0],["mask",!0]])}),Fe(t,"video:play",()=>{Ve(t,[["mask",!1]]),E(t)||j(r,"display","none")}),Fe(t,"video:playing",()=>Ve(t,[["mask",!1]])),Fe(t,"video:progress",()=>{t.playing&&Ve(t,[["loading",!1]])}),Fe(t,"video:seeked",()=>Ve(t,[["loading",!1],["mask",!0]])),Fe(t,"video:seeking",()=>Ve(t,[["loading",!0],["mask",!1]])),Fe(t,"video:timeupdate",()=>Ve(t,[["mask",!1]])),Fe(t,"video:waiting",()=>Ve(t,[["loading",!0],["mask",!1]]))}(t,e)}const He=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],je=(()=>{if("undefined"===typeof document)return!1;const t=He[0],e={};for(const r of He){if(r[1]in document){for(const[n,o]of r.entries())e[t[n]]=o;return e}}return!1})(),qe={change:je.fullscreenchange,error:je.fullscreenerror},Ue={request:(t=document.documentElement,e)=>new Promise((r,n)=>{const o=()=>{Ue.off("change",o),r()};Ue.on("change",o);const i=t[je.requestFullscreen](e);i instanceof Promise&&i.then(o).catch(n)}),exit:()=>new Promise((t,e)=>{if(!Ue.isFullscreen)return void t();const r=()=>{Ue.off("change",r),t()};Ue.on("change",r);const n=document[je.exitFullscreen]();n instanceof Promise&&n.then(r).catch(e)}),toggle:(t,e)=>Ue.isFullscreen?Ue.exit():Ue.request(t,e),onchange(t){Ue.on("change",t)},onerror(t){Ue.on("error",t)},on(t,e){const r=qe[t];r&&document.addEventListener(r,e,!1)},off(t,e){const r=qe[t];r&&document.removeEventListener(r,e,!1)},raw:je};function Xe(t,e,...r){const n=Reflect.get(t,e);if("function"!==typeof n)throw new TypeError(`Fullscreen method ${e} is not available`);return n.apply(t,r)}Object.defineProperties(Ue,{isFullscreen:{get:()=>Boolean(document[je.fullscreenElement])},element:{enumerable:!0,get:()=>document[je.fullscreenElement]},isEnabled:{enumerable:!0,get:()=>Boolean(document[je.fullscreenEnabled])}});const Ge=new WeakMap;function Ke(t){try{Promise.resolve(t()).catch(()=>{})}catch(e){}}function Ze(t){const{document:e,elementProperty:r,changeEvent:n,target:o,exit:i}=t,a=function(t,e,r){let n=Ge.get(t);if(!n){n=new WeakMap,Ge.set(t,n);const o=n;t.addEventListener(r,()=>{const r=Reflect.get(t,e),n=r&&o.get(r);n&&(o.delete(r),Ke(n))})}return n}(e,r,n);a.set(o,i),t.element===o&&(a.delete(o),Ke(i))}function Je(t,e,r,n,o=()=>t.element!==t.target){const i=e.child();let a,s,l=!1,c=!1,d=!1,u=!1,p=!1;const h=new Promise((t,e)=>{a=t,s=e});function f(t=!1,e){if(!l){l=!0;try{i.dispose()}catch(r){t||(t=!0,e=r)}t?s(e):a()}}i.add(()=>{l||(l=!0,c=!0,a(),d&&!u&&r&&Ze(t))});const m=()=>{d&&!u&&(r?t.element===t.target:o())&&f()};if(Dt(i,t.document,t.changeEvent,m),Dt(i,t.document,t.errorEvent,e=>{e.target!==t.target&&e.target!==t.document||(p=!0,d&&!u&&f(!0,new Error("Fullscreen request failed")))}),!i.closed)try{r&&function(t){var e;null==(e=Ge.get(t.document))||e.delete(t.target)}(t);const e=r?t.request():t.exit();u=Boolean(e&&"function"===typeof e.then),d=!0,c&&!u&&r&&Ze(t),u?Promise.resolve(e).then(()=>{c?n():f()},t=>f(!0,t)).catch(()=>{}):p?f(!0,new Error("Fullscreen request failed")):m()}catch(g){f(!0,g)}return{promise:h,cancel:()=>i.dispose()}}function Qe(t,e){const r=$(t).child(),{$player:n,$video:o}=t.template,i=()=>e.element===n||e.element===o;let a,s=i(),l=0,c=s,d=!1,u=!1,p=!1;function h(){if(i())try{Promise.resolve(e.exit()).catch(()=>{})}catch(t){}}return r.add(()=>{l+=1,c=!1,n.classList.remove("art-fullscreen"),h()}),Dt(r,e.document,e.changeEvent,()=>{const r=i();if(r&&function(t){var e,r;return null!=(r=null==(e=Ge.get(t.document))?void 0:e.has(t.target))&&r}(e))return;if(r&&u)return void h();if(r===s||E(t))return;s=r;const o=l,a=()=>E(t)||i()!==r||o!==l&&c!==r;t.emit("fullscreen",r),a()||(r&&(t.state="fullscreen"),a()||(n.classList.toggle("art-fullscreen",r),t.emit("resize")))}),Dt(r,e.document,e.errorEvent,r=>{(r.target===n||r.target===o||r.target===e.document&&(p||void 0!==a||i()))&&!E(t)&&t.emit("fullscreenError",r)}),{get:()=>!E(t)&&i(),set(n){if(E(t))return Promise.resolve();const o=++l;if(c=Boolean(n),c?u=!1:d&&(u=!0),null==a||a.cancel(),a=void 0,d=!1,!c&&!i())return Promise.resolve();p=!0,d=c;const s=Je(e,r,c,()=>{!E(t)&&c||h()},()=>!i());p=!1,l===o?a=s:s.cancel();const f=s.promise.catch(e=>{throw E(t)||l!==o||(t.notice.show=e),e}).finally(()=>{l===o&&(a=void 0,d=!1)});return f.catch(()=>{}),f}}}const tr=new WeakSet;function er(t,e=!1){return"string"===typeof t.webkitPresentationMode?"fullscreen"===t.webkitPresentationMode:"boolean"===typeof t.webkitDisplayingFullscreen?t.webkitDisplayingFullscreen:t.ownerDocument.fullscreenElement===t||e}function rr(t){tr.delete(t),t.removeEventListener("webkitbeginfullscreen",nr),t.removeEventListener("webkitpresentationmodechanged",nr)}function nr(t){var e;if(tr.has(this)&&er(this,"webkitbeginfullscreen"===t.type)){rr(this);try{null==(e=this.webkitExitFullscreen)||e.call(this)}catch(r){}}}function or(t){tr.add(t),t.addEventListener("webkitbeginfullscreen",nr),t.addEventListener("webkitpresentationmodechanged",nr)}function ir(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=er(e),i=o,a=!1,s=0;const l=()=>er(e,n);function c(r){if(E(t)||(c=e,tr.has(c)))return;var c;"boolean"===typeof r&&(n=r);const d=l();if(d&&(a=!1),d===o)return;o=d;const u=s,p=()=>E(t)||l()!==d||u!==s&&i!==d;t.emit("fullscreen",d),p()||(d&&(t.state="fullscreen"),p()||t.emit("resize"))}r.add(()=>{var t;s++,i=!1,a&&or(e),l()&&(null==(t=e.webkitExitFullscreen)||t.call(e))}),Dt(r,e,"webkitbeginfullscreen",()=>c(!0)),Dt(r,e,"webkitendfullscreen",()=>c(!1)),Dt(r,e,"webkitpresentationmodechanged",()=>c());const d=()=>c();return t.on("document:webkitfullscreenchange",d),r.add(()=>{t.off("document:webkitfullscreenchange",d)}),{get:()=>!E(t)&&l(),set(r){if(E(t))return;const n=++s;if(i=Boolean(r),r){if(rr(e),t.state="fullscreen",E(t)||n!==s)return;a=!0;try{e.webkitEnterFullscreen()}catch(o){throw n===s&&(a=!1),o}}else a&&(a=!1,or(e)),l()&&e.webkitExitFullscreen()}}}function ar(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t,i=()=>{if(E(t))return;const i=function(t){const e=Ue.raw,r=t.ownerDocument;if(e&&Reflect.get(r,e.fullscreenEnabled))return{document:r,target:t,get element(){return Reflect.get(r,e.fullscreenElement)},elementProperty:e.fullscreenElement,changeEvent:e.fullscreenchange,errorEvent:e.fullscreenerror,request:()=>Xe(t,e.requestFullscreen,void 0),exit:()=>Xe(r,e.exitFullscreen)}}(o);i?gt(t,"fullscreen",Qe(t,i)):n.webkitSupportsFullscreen&&"function"===typeof n.webkitEnterFullscreen&&"function"===typeof n.webkitExitFullscreen?gt(t,"fullscreen",ir(t)):gt(t,"fullscreen",{get:()=>!1,set(){E(t)||(r.show=e.get("Fullscreen Not Supported"))}}),gt(t,"fullscreen",bt(t,"fullscreen"))};t.once("video:loadedmetadata",i),$(t).add(()=>{t.off("video:loadedmetadata",i)})}function sr(t){return{node:t,parent:t.parentNode,next:t.nextSibling}}function lr({node:t,parent:e,next:r}){var n;if(!e)return void(null==(n=t.parentNode)||n.removeChild(t));const o=(null==r?void 0:r.parentNode)===e?r:null;t.parentNode===e&&t.nextSibling===o||e.insertBefore(t,o)}function cr(t){const e=function(t){const{$player:e}=t.template;let r,n=0;function o(t,r){return null===t.style?e.removeAttribute("style"):e.setAttribute("style",t.style),!!r()&&(e.classList.remove("art-fullscreen-web"),!!r()&&(lr(t.placement),r()))}return $(t).add(()=>{var t;n+=1;const i=r;if(r=void 0,i)try{o(i,()=>!0)}catch(a){try{e.parentNode!==i.placement.parent&&(null==(t=e.parentNode)||t.removeChild(e))}catch(s){throw new y([a,s])}throw a}}),i=>{if(E(t))return;const a=++n,s=()=>a===n&&!E(t);if(i){r||(r={placement:sr(e),style:e.getAttribute("style")});const n=r;try{if(t.constructor.FULLSCREEN_WEB_IN_BODY&&e.parentNode!==document.body&&document.body.appendChild(e),!s())return;if(t.state="fullscreenWeb",!s())return;e.style.width="100%",e.style.height="100%",e.classList.add("art-fullscreen-web")}catch(l){throw s()&&o(n,s)&&(r=void 0),l}if(!s())return;t.emit("fullscreenWeb",!0)}else{if(r){if(!o(r,s))return;r=void 0}else e.classList.remove("art-fullscreen-web");if(!s())return;t.emit("fullscreenWeb",!1)}s()&&t.emit("resize")}}(t);gt(t,"fullscreenWeb",{get:()=>t.template.$player.classList.contains("art-fullscreen-web"),set:e})}function dr(t,e,r){const n=Math.max(0,r.viewportWidth-r.width),o=Math.max(0,r.viewportHeight-r.height);return{left:Math.max(0,Math.min(t,n)),top:Math.max(0,Math.min(e,o))}}function ur(t){const{width:e,height:r}=t.getBoundingClientRect(),n=t.ownerDocument.defaultView;return{width:e,height:r,viewportWidth:n.innerWidth,viewportHeight:n.innerHeight}}function pr(t,e,r,n){const o=e.child();if(o.closed)return;const i=t.template.$mini;if(i){const t=i.style.display;return o.add(()=>{i.style.display=t}),{element:i,cancelDrag:()=>{},fresh:!1}}const a=t.template.$player.ownerDocument,s=a.createElement("div");s.className="art-mini-popup",o.add(()=>{s.remove()});try{const e=a.createElement("div");if(e.className="art-mini-close",e.append(t.icons.close),o.closed)return;const i=a.createElement("div");i.className="art-mini-state";const l=t.icons.play,c=t.icons.pause;if(o.closed)return;i.append(l,c),s.append(e,i),Dt(o,e,"click",n),Dt(o,l,"click",()=>{at(t.play())}),Dt(o,c,"click",()=>{t.pause()});const d=()=>{o.closed||(l.style.display=t.playing?"none":"flex",c.style.display=t.playing?"flex":"none")};d();for(const r of["video:playing","video:pause","video:timeupdate"])t.on(r,d),o.add(()=>{t.off(r,d)});const u=function(t,e,r,n){let o=!1,i=0,a=0;const s=()=>{o=!1,e.classList.remove("art-mini-dragging"),e.style.transform=""};Dt(r,e,"mousedown",t=>{const e=t;0===e.button&&n()&&(o=!0,i=e.clientX,a=e.clientY)});const l=t=>{!r.closed&&o&&n()&&(e.classList.add("art-mini-dragging"),e.style.transform=`translate(${t.clientX-i}px, ${t.clientY-a}px)`)},c=()=>{if(r.closed||!o||!n())return;const i=e.getBoundingClientRect(),a=dr(i.left,i.top,ur(e));s(),e.style.left=`${a.left}px`,e.style.top=`${a.top}px`,t.storage.set("left",a.left),r.closed||t.storage.set("top",a.top)};return t.on("document:mousemove",l),r.add(()=>{t.off("document:mousemove",l)}),t.on("document:mouseup",c),r.add(()=>{t.off("document:mouseup",c)}),r.add(s),s}(t,s,o,r);if(o.closed)return;if(t.template.$mini=s,a.body.append(s),!o.closed)return{element:s,cancelDrag:u,fresh:!0}}catch(l){throw o.dispose(),t.template.$mini===s&&delete t.template.$mini,l}}function hr(t){const{$player:e,$video:r}=t.template,n=$(t).child();let o,i,a=0,s=!1,d=!1;const u=()=>!E(t)&&e.classList.contains("art-mini");function p(){if(i){const e=i,r=a;i=void 0;try{lr(e)}catch(t){throw r!==a||i||(i=e),t}}}function h(){if(E(t))return;const r=++a;d=!1,p(),E(t)||r!==a||(null==o||o.cancelDrag(),e.classList.remove("art-mini"),t.template.$mini&&(t.template.$mini.style.display="none",t.emit("mini",!1)))}function f(){if(E(t))return;const m=++a;if(s)d=!0;else if(t.state="mini",!E(t)&&m===a){null!=i||(i=sr(r)),e.classList.add("art-mini");try{if(!o){s=!0;try{o=pr(t,n,u,h)}finally{s=!1}}if(d)return d=!1,void f();if(!o||E(t))return;if(m!==a)return void(u()||(o.element.style.display="none"));if(o.fresh?o.element.prepend(r):o.element.append(r),E(t)||m!==a)return;o.element.style.display=o.fresh?"":"flex",o.fresh=!1;const e=t.storage.get("top"),i=function(t,e,r){return"number"===typeof t&&Number.isFinite(t)&&"number"===typeof e&&Number.isFinite(e)&&t>=0&&e>=0&&t+r.width<=r.viewportWidth&&e+r.height<=r.viewportHeight?{left:t,top:e,reset:!1}:c(l({},dr(r.viewportWidth-r.width-50,r.viewportHeight-r.height-50,r)),{reset:!0})}(t.storage.get("left"),e,ur(o.element));if(E(t)||m!==a)return;if(o.element.style.left=`${i.left}px`,o.element.style.top=`${i.top}px`,i.reset){if(t.storage.set("top",i.top),E(t)||m!==a)return;t.storage.set("left",i.left)}E(t)||m!==a||t.emit("mini",!0)}catch(g){const r=d;throw d=!1,E(t)||m!==a&&!r||(p(),e.classList.remove("art-mini"),o&&(o.element.style.display="none")),g}}}return n.add(()=>{a++;try{p()}finally{null==o||o.cancelDrag(),e.classList.remove("art-mini")}}),{get:u,set(t){t?f():h()}}}const fr=new WeakSet,mr=t=>"picture-in-picture"===t.webkitPresentationMode;function gr(t){fr.delete(t),t.removeEventListener("webkitpresentationmodechanged",vr),t.removeEventListener("enterpictureinpicture",vr)}function vr(){var t;if(fr.has(this)&&mr(this)){gr(this);try{null==(t=this.webkitSetPresentationMode)||t.call(this,"inline")}catch(e){}}}function yr(t){fr.add(t),t.addEventListener("webkitpresentationmodechanged",vr),t.addEventListener("enterpictureinpicture",vr)}function br(t){const{i18n:e,notice:r,template:{$video:n}}=t,o=n.ownerDocument;o.pictureInPictureEnabled&&"function"===typeof n.requestPictureInPicture&&"function"===typeof o.exitPictureInPicture?gt(t,"pip",function(t){const{$video:e}=t.template,r=e.ownerDocument,n=$(t).child(),o=()=>r.pictureInPictureElement===e;let i=o(),a=i,s=!1,l=!1,c=0;function d(){if(o())try{r.exitPictureInPicture().catch(()=>{})}catch(t){}}function u(e,r,n){e.then(()=>{!r||!E(t)&&a||d()},e=>{E(t)||c!==n||(t.notice.show=e)}).finally(()=>{c===n&&(s=!1)}).catch(()=>{})}return e.disablePictureInPicture=!1,n.add(()=>{c++,a=!1,d()}),Dt(n,e,"enterpictureinpicture",()=>{if(l)return void d();if(!o()||i)return;const e=c;t.state="pip",!E(t)&&e===c&&o()&&(i=!0,t.emit("pip",!0))}),Dt(n,e,"leavepictureinpicture",()=>{i&&!o()&&(i=!1,t.emit("pip",!1))}),{get:()=>!E(t)&&o()?e:null,set(n){if(E(t))return;const i=++c;if(a=Boolean(n),a?l=!1:s&&(l=!0),s=!1,a){if(t.state="pip",E(t)||c!==i)return;s=!0;try{u(e.requestPictureInPicture(),!0,i)}catch(d){throw c===i&&(s=!1),d}}else o()&&u(r.exitPictureInPicture(),!1,i)}}}(t)):"function"===typeof n.webkitSupportsPresentationMode&&"function"===typeof n.webkitSetPresentationMode?gt(t,"pip",function(t){const{$video:e}=t.template,r=$(t).child();let n=!1,o=!1,i=0,a=0;function s(r=!1){if(E(t)||fr.has(e))return;const s=mr(e);if(s&&(o=!1),s===n&&!r)return;const l=i;s&&(t.state="pip"),E(t)||i!==l||mr(e)!==s||(n=s,a++,t.emit("pip",s))}e.webkitSetPresentationMode("inline"),r.add(()=>{i++,o&&yr(e),mr(e)&&e.webkitSetPresentationMode("inline")});for(const l of["webkitpresentationmodechanged","enterpictureinpicture","leavepictureinpicture"])Dt(r,e,l,()=>s());return{get:()=>!E(t)&&mr(e),set(r){var n;if(E(t))return;const l=++i,c=a;if(r){if(!1===(null==(n=e.webkitSupportsPresentationMode)?void 0:n.call(e,"picture-in-picture")))return void(t.notice.show=t.i18n.get("PIP Not Supported"));if(gr(e),t.state="pip",E(t)||i!==l)return;o=!0;try{e.webkitSetPresentationMode("picture-in-picture")}catch(d){throw l===i&&(o=!1),d}}else o&&(o=!1,yr(e)),mr(e)&&e.webkitSetPresentationMode("inline");E(t)||l!==i||c!==a||mr(e)!==Boolean(r)||s(!0)}}}(t)):gt(t,"pip",{get:()=>!1,set(){E(t)||(r.show=e.get("PIP Not Supported"))}})}function wr(t){gt(t,"quality",{set(e){const{controls:r,notice:n,i18n:o}=t,i=e.find(t=>t.default)||e[0];r.update({name:"quality",position:"right",index:10,style:{marginRight:"10px"},html:(null==i?void 0:i.html)||"",selector:e,onSelect(e,r,i){return d(this,null,function*(){const r=function(t){return t&&re.get(t)||(()=>!0)}(i);if(yield t.switchQuality(e.url),!E(t)&&r()){const i=`${o.get("Switch Video")}: ${e.html}`;!E(t)&&r()&&(n.show=i)}return e.html})}})}})}function xr(t){const{notice:e,template:{$video:r}}=t,n=document.createElement("canvas");function o(o){const i=qt(t);return new Promise((a,s)=>{const l=r=>{try{!E(t)&&i()&&(e.show=r)}catch(n){return void s(n)}s(r)};try{!function(t,e){t.width=e.videoWidth,t.height=e.videoHeight;const r=t.getContext("2d");if(!r)throw new TypeError("Canvas 2D context is unavailable");r.drawImage(e,0,0)}(n,r),o?function(t,e,r){t.toBlob(t=>{try{if(!t)throw new Error("Unable to encode screenshot blob");e(URL.createObjectURL(t))}catch(n){r(n)}})}(n,a,l):a(n.toDataURL("image/png"))}catch(c){l(c)}})}gt(t,"getDataURL",{value:()=>o(!1)}),gt(t,"getBlobUrl",{value:()=>o(!0)}),gt(t,"screenshot",{value:e=>d(null,null,function*(){const n=qt(t),o=yield t.getDataURL();if(!E(t)&&n()){const i=e||`artplayer_${ut(r.currentTime)}`;!E(t)&&n()&<(o,`${i}.png`),!E(t)&&n()&&t.emit("screenshot",o)}return o})})}function kr(t,e,r,n,o=!0){let i,a=!1;const s=e=>{t.closed||a||(o&&(a=!0,i()),n(e))};return e[o?"once":"on"](r,s),i=t.add(()=>{e.off(r,s)}),s}function $r(t,e,r){return new Promise((n,o)=>{if(E(t)||e===t.url)return void n();const i=Ut(t),a=i.scope.child();let s=!1;const l=(t=!1,e)=>{s||(s=!0,i.onError=void 0,i.onAssigned=void 0,a.dispose(),t?o(e):n(),t&&i.scope.dispose())};a.add(()=>{l()});const c=()=>!s&&i.active(),u=t=>l(!0,t);i.onError=u;try{const{playing:n,aspectRatio:o,playbackRate:s}=t;if(t.pause(),!c())return;const p=a.child();let h=!1,f=!1,m=!1;const g=function(t,e,r){let n,o=!1,i=!1,a=!1,s=We(t);const l=()=>a||We(t)!==s,c=()=>{var e,r;return!!(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)};return{restore(){if(!r()||l())return;const i=We(t);t.currentTime=e,s=We(t),s>i+1&&(a=!0),r()&&(n=t.currentTime,r()&&!l()&&(o=c()))},manual(){a=!0},ready(){if(!r()||c())return!1;const e=void 0!==n&&Math.abs(t.currentTime-n)>.05;if(!l()&&o&&!i&&void 0!==n&&e){if(i=!0,!r())return!1;t.currentTime=n}return r()&&!c()}}}(t,r,c),v=()=>d(null,null,function*(){if(t.aspectRatio=o,c()){if(n)try{yield t.play()}catch(e){}c()&&(t.notice.show="",l())}}),y=()=>{var e,r;if(c()&&!f&&h)try{if(null==(r=null==(e=t.template)?void 0:e.$video)?void 0:r.seeking)return;if(!c())return;if(m||(m=!0,t.playbackRate=s),!g.ready()||!c()||f)return;f=!0,p.dispose(),v().catch(u)}catch(n){u(n)}},b={"video:error":u,"video:loadedmetadata":()=>{if(c())try{g.restore()}catch(t){u(t)}},"video:canplay":()=>{h=!0,y()},"video:seeked":y,seek:g.manual},w=a.child(),x=[],k=Object.keys(b);for(const e of k)kr(w,t,e,t=>{i.acceptingEvents&&x.push([e,t])},!1);if(Gt(t,i,e),!c())return;if(t.notice.show="",!c())return;const $=()=>{if(w.dispose(),!e)return void l();const r={};for(const e of k)r[e]=kr(p,t,e,b[e],"video:seeked"!==e);for(const[t,e]of x){if(!c()||p.closed)break;r[t](e)}x.length=0};i.assigned?$():i.onAssigned=$}catch(p){u(p)}})}function Er(t){const{option:e,template:{$progress:r,$video:n}}=t;let o,i,a,s=$(t).child(),c=!1;function d(){const e=s;s=$(t).child(),o=void 0,c=!1,a=void 0,e.dispose()}function u(){const i=a,c=s;if(!i||!o)return;const d=()=>{var e;return!E(t)&&!c.closed&&s===c&&a===i&&i.sourceActive()&&(null==(e=t.controls)?void 0:e.thumbnails)===i.element};if(!d())return;const u=r.clientWidth*i.percentage;if(!(u>0&&ud-h/2?d-h+"px":u-h/2+"px"}}(e.thumbnails,{imageWidth:o.naturalWidth,videoWidth:n.videoWidth,videoHeight:n.videoHeight,progressWidth:r.clientWidth,position:u}));for(const[t,e]of Object.entries(p)){if(!d())return;j(i.element,t,e)}}me(t)("setBar",(r,n,l)=>{var p;const h=null==(p=t.controls)?void 0:p.thumbnails,{url:f,scale:m}=e.thumbnails;if(!E(t)&&h&&f&&("hover"===r||"played"===r&&l&&N)){if(i!==h){const t=S(h);if(t.closed)return;i=h,t.add(()=>{i===h&&(i=void 0,d())})}if(a={percentage:n,element:h,sourceActive:qt(t)},o)u();else if(!c){const t=s;c=!0,function(t,e,r){return W(t,e,r)}(f,m,t).then(e=>{s!==t||t.closed||(c=!1,o=e,u())}).catch(e=>{s!==t||t.closed||(c=!1,console.warn("ArtPlayer thumbnail load failed:",e))})}}}),gt(t,"thumbnails",{get:()=>t.option.thumbnails,set:e=>{E(t)||!e.url||t.option.isLive||E(t)||(t.option.thumbnails=e,d())}})}function Tr(t){const{option:e,template:{$video:r}}=t;gt(t,"url",{get:()=>r.src,set(n){return d(this,null,function*(){if(E(t))return;const o=function(t){const e=Bt.get(t);return Bt.delete(t),e||Ut(t)}(t);o.acceptingEvents=!1;try{if(!n)return void((yield Vt(o.scope))&&o.active()&&(t.loading.show=!0));const i=t.url,a=e.type||st(n),s=e.customType[a];if(a&&s){if(!(yield Vt(o.scope))||!o.active())return;t.loading.show=!0}if(!o.active())return;const l=o.scope.child();let c=!1,d=!1;kr(l,t,"video:canplay",()=>{c=!d}),kr(l,t,"video:error",()=>{d=!0});try{if(o.acceptingEvents=!0,a&&s){const e=s.call(t,r,n,t);Promise.resolve(e).catch(t=>Kt(o,t))}else{if(!o.active())return;r.src=n}}finally{l.dispose()}if(!o.active())return;if(i!==t.url&&(t.option.url=n,o.active()&&t.isReady&&i)){const e=()=>{o.active()&&t.emit("restart",n)};c?e():d||kr(o.scope,t,"video:canplay",e)}}catch(i){Kt(o,i)}finally{Xt(o)}})}})}class Cr{constructor(t){Tr(t),function(t){const{template:{$video:e}}=t;gt(t,"attr",{value(t,r){if(void 0===r)return e[t];e[t]=r}})}(t),function(t){const{i18n:e,notice:r,option:n,constructor:{instances:o},template:{$video:i}}=t;gt(t,"play",{value(){return d(this,null,function*(){const a=qt(t),s=yield i.play();if(!a())return s;const l=e.get("Play");if(!a())return s;if(r.show=l,!a())return s;if(t.emit("play"),n.mutex)for(let e=0;et.playing?t.pause():t.play()})}(t),function(t){const{notice:e}=t;gt(t,"seek",{set(r){t.currentTime=r,t.duration&&(e.show=`${ut(t.currentTime)} / ${ut(t.duration)}`),t.emit("seek",t.currentTime,r)}});const r=t;gt(t,"forward",{set(e){r.seek=t.currentTime+e}}),gt(t,"backward",{set(e){r.seek=t.currentTime-e}})}(t),function(t){const{template:{$video:e},i18n:r,notice:n,storage:o}=t;gt(t,"volume",{get:()=>e.volume||0,set:t=>{e.volume=ct(t,0,1),n.show=`${r.get("Volume")}: ${Number.parseInt(String(100*e.volume),10)}`,0!==e.volume&&o.set("volume",e.volume)}}),gt(t,"muted",{get:()=>e.muted,set:r=>{e.muted=r,t.emit("muted",r)}})}(t),De(t),function(t){gt(t,"duration",{get:()=>{const{duration:e}=t.template.$video;return e===1/0?0:e||0}})}(t),function(t){const e=e=>$r(t,e,0);gt(t,"switchQuality",{value:e=>$r(t,e,t.currentTime)}),gt(t,"switchUrl",{value:e}),gt(t,"switch",{set:e})}(t),function(t){const{template:{$video:e},i18n:r,notice:n}=t,o=t;gt(t,"playbackRate",{get:()=>e.playbackRate,set(t){if(t){if(t===e.playbackRate)return;e.playbackRate=t,n.show=`${r.get("Rate")}: ${1===t?r.get("Normal"):`${t}x`}`}else o.playbackRate=1}})}(t),function(t){const{i18n:e,notice:r,template:{$video:n,$player:o}}=t;gt(t,"aspectRatio",{get:()=>o.dataset.aspectRatio||"default",set(i){if(!E(t)){if(i||(i="default"),"default"===i)n.style.width="",n.style.height="",n.style.margin="",delete o.dataset.aspectRatio;else{const e=i.split(":").map(Number),r=Ie({width:o.clientWidth,height:o.clientHeight},e[0]/e[1]);if(E(t))return;"width"===(null==r?void 0:r.axis)?(n.style.width=`${r.width}px`,n.style.height="100%",n.style.margin="0 auto"):r&&(n.style.width="100%",n.style.height=`${r.height}px`,n.style.margin="auto 0"),o.dataset.aspectRatio=i}r.show=`${e.get("Aspect Ratio")}: ${"default"===i?e.get("Default"):i}`,E(t)||t.emit("aspectRatio",i)}}})}(t),xr(t),ar(t),cr(t),br(t),function(t){const{$video:e}=t.template,r=t;gt(t,"loaded",{get:()=>r.loadedTime/e.duration}),gt(t,"loadedTime",{get:()=>e.buffered.length?e.buffered.end(e.buffered.length-1):0})}(t),function(t){gt(t,"played",{get:()=>t.currentTime/t.duration})}(t),function(t){const{$video:e}=t.template;gt(t,"playing",{get:()=>"boolean"===typeof e.playing?e.playing:!!(e.currentTime>0&&!e.paused&&!e.ended&&e.readyState>2)})}(t),function(t){const{$container:e,$player:r,$video:n}=t.template;gt(t,"autoSize",{value(){if(E(t))return;const o={width:n.videoWidth,height:n.videoHeight};if(!Re(o))return;const i=et(e),a=Ie(i,o.width/o.height);a&&!E(t)&&("width"===a.axis?(r.style.width=a.width/i.width*100+"%",r.style.height="100%"):(r.style.width="100%",r.style.height=a.height/i.height*100+"%"),t.emit("autoSize",{width:t.width,height:t.height}))}})}(t),function(t){const e=t;gt(t,"rect",{get:()=>et(t.template.$player)});const r=["bottom","height","left","right","top","width"];for(let n=0;ne.rect[o]})}gt(t,"x",{get:()=>e.left+window.pageXOffset}),gt(t,"y",{get:()=>e.top+window.pageYOffset})}(t),function(t){const{template:{$player:e},i18n:r,notice:n}=t;gt(t,"flip",{get:()=>e.dataset.flip||"normal",set(o){E(t)||(o||(o="normal"),"normal"===o?delete e.dataset.flip:e.dataset.flip=o,n.show=`${r.get("Video Flip")}: ${r.get(dt(o))}`,E(t)||t.emit("flip",o))}})}(t),function(t){gt(t,"mini",hr(t))}(t),function(t){const{template:{$poster:e}}=t;gt(t,"poster",{get:()=>{try{return e.style.backgroundImage.match(/"(.*)"/)[1]}catch(t){return""}},set(t){j(e,"backgroundImage",`url(${t})`)}})}(t),Ne(t),function(t){const{$player:e}=t.template;gt(t,"cssVar",{value:(t,r)=>r?e.style.setProperty(t,r):getComputedStyle(e).getPropertyValue(t)})}(t),function(t){gt(t,"theme",{get:()=>t.cssVar("--art-theme"),set(e){t.cssVar("--art-theme",e)}})}(t),function(t){gt(t,"type",{get:()=>t.option.type,set(e){t.option.type=e}})}(t),function(t){const e=["mini","pip","fullscreen","fullscreenWeb"];gt(t,"state",{get:()=>e.find(e=>t[e])||"standard",set(r){for(let n=0;n{switch(t.availability){case"available":i=!0;break;case"not-available":i=!1}}):i=!1,gt(t,"airplay",{value(){i?(o.webkitShowPlaybackTargetPicker(),t.emit("airplay")):r.show=e.get("AirPlay Not Available")}})}(t),wr(t),Er(t),Be(t),function(t){const{option:e,storage:r,template:{$video:n,$poster:o}}=t;for(const a in e.moreVideoAttr)t.attr(a,e.moreVideoAttr[a]);e.muted&&(t.muted=e.muted),e.volume&&(n.volume=ct(e.volume,0,1));const i=r.get("volume");"number"===typeof i&&(n.volume=ct(i,0,1)),e.poster&&j(o,"backgroundImage",`url(${e.poster})`),e.autoplay&&(n.autoplay=e.autoplay),e.playsInline&&(n.playsInline=!0,n["webkit-playsinline"]=!0),e.theme&&(e.cssVar["--art-theme"]=e.theme);for(const a in e.cssVar)t.cssVar(a,e.cssVar[a]);t.url=e.url}(t)}}const Lr=new WeakMap,Sr="art-auto-orientation-fullscreen";function Pr(t){if(Lr.get(t.orientation)===t)try{t.orientation.unlock()}catch(e){}}const Mr="art-auto-orientation",zr=["width","height","transform-origin","transform"];function Ar(t){const{$player:e,$video:r}=t.template,n=()=>{const t={width:r.videoWidth,height:r.videoHeight},n=e.ownerDocument.documentElement,o={width:n.clientWidth,height:n.clientHeight};return Re(t)&&Re(o)&&(t.width>t.height&&o.widtho.height)},o=function(t,e){const{$player:r}=t.template,n=$(t);let o,i=()=>{};function a(){i(),i=()=>{};const e=o;if(o=void 0,e&&t.fullscreenWeb)for(const{name:t,value:o,priority:i}of e)r.style.setProperty(t,o,i);const n=r.classList.contains(Mr);r.classList.remove(Mr),n&&(t.isRotate=!1,E(t)||t.emit("resize"))}function s(n){if(!t.fullscreenWeb||!e())return;const i=nt();if(E(t)||!t.fullscreenWeb)return;const a=r.ownerDocument.documentElement;null!=o||(o=zr.map(t=>({name:t,value:r.style.getPropertyValue(t),priority:r.style.getPropertyPriority(t)}))),r.style.width=a.clientHeight-i.top-i.bottom+"px",r.style.height=a.clientWidth-i.left-i.right+"px",r.style.transformOrigin="0 0",r.style.transform=`rotate(90deg) translate(${i.top}px, -${a.clientWidth-i.right}px)`,r.classList.add(Mr),t.isRotate=!0,n&&t.emit("resize")}return n.add(a),r=>{var l;E(t)||(r?o?s(!1):e()&&(i(),i=Ft(n,()=>{o||s(!0)},Number(null!=(l=t.constructor.AUTO_ORIENTATION_TIME)?l:0))):a())}}(t,n),i=function(t,e){const{$player:r}=t.template;let n;function o(){const t=n;n=void 0,r.classList.remove(Sr),t&&(t.cancelled=!0,Pr(t),t.settled&&Lr.get(t.orientation)===t&&Lr.delete(t.orientation))}return $(t).add(o),i=>{var a,s;if(E(t))return;if(!i)return void o();if(n&&!n.cancelled&&Lr.get(n.orientation)===n)return;const l=null==(s=null==(a=r.ownerDocument.defaultView)?void 0:a.screen)?void 0:s.orientation;if("function"!==typeof(null==l?void 0:l.lock)||"function"!==typeof l.unlock||!e())return;const c={orientation:l,cancelled:!1,settled:!1};n=c,Lr.set(l,c);const d=()=>!E(t)&&!c.cancelled&&n===c&&Lr.get(l)===c,u=e=>{c.settled=!0;const o=d();Lr.get(l)===c&&Lr.delete(l),n===c&&(n=void 0),o&&(r.classList.remove(Sr),t.notice.show=e)};try{const t=l.lock(l.type.startsWith("portrait")?"landscape":"portrait");Promise.resolve(t).then(()=>{c.settled=!0,d()?r.classList.add(Sr):(Pr(c),Lr.get(l)===c&&Lr.delete(l))}).catch(u)}catch(p){u(p)}}}(t,n);return t.on("fullscreenWeb",o),t.on("fullscreen",i),$(t).add(()=>{t.off("fullscreenWeb",o),t.off("fullscreen",i)}),{name:"autoOrientation",get state(){return e.classList.contains("art-auto-orientation")}}}function Or(t){return t.get("times")||{}}function Rr(t){const{storage:e}=t,r=function(t){const{i18n:e,icons:r,storage:n,constructor:o,template:{$poster:i}}=t,a=t.layers.add({name:"auto-playback",html:'\n
\n
\n
\n '});if(!a||E(t))return()=>{};const s=Ct(".art-auto-playback-last",a),l=Ct(".art-auto-playback-jump",a),c=Ct(".art-auto-playback-close",a);Tt(c,r.close);const d=S(a);let u,p=0;const h=()=>{const r=++p;if(null==u||u.dispose(),d.closed||E(t)||p!==r)return;const h=d.child();u=h;const f=()=>u===h&&!h.closed&&!E(t);h.add(()=>{u===h&&(u=void 0,j(a,"display","none"))});const m=jt(t).add(()=>{h.dispose()});h.add(()=>{m()});const g=Or(n)[t.option.id||t.option.url];if(!f())return;if(j(a,"display","none"),!f()||!g||!(g>=o.AUTO_PLAYBACK_MIN))return;if(!f())return;if(j(a,"display","flex"),!f())return;const v=`${e.get("Last Seen")} ${ut(g)}`;if(!f())return;if(s.textContent=v,!f())return;const y=e.get("Jump Play");if(!f())return;if(l.textContent=y,!f())return;const b=(e,r)=>{const n=t.events.proxy(e,"click",()=>{f()&&r()});h.add(()=>{t.events.remove(n)})};if(b(c,()=>{j(a,"display","none")}),!f())return;if(b(l,()=>{t.seek=g,f()&&(at(t.play()),f()&&(j(i,"display","none"),f()&&j(a,"display","none")))}),!f())return;let w=()=>{},x=!1;const k=()=>{!x&&f()&&(x=!0,w(),Ft(h,()=>{f()&&j(a,"display","none")},o.AUTO_PLAYBACK_TIMEOUT))};t.on("video:timeupdate",k),w=h.add(()=>{t.off("video:timeupdate",k)}),x&&w()};return()=>{M(t,a,"ready",h),M(t,a,"restart",h)}}(t);return function(t){const{storage:e,constructor:r}=t;me(t)("video:timeupdate",()=>{if(!t.playing)return;const n=Or(e),o=Object.keys(n),i=r.AUTO_PLAYBACK_MAX,a=t.option.id||t.option.url,s=t.currentTime;E(t)||(o.length>i&&delete n[o[0]],n[a]=s,E(t)||e.set("times",n))})}(t),r(),{name:"auto-playback",get times(){return Or(e)},clear:()=>e.del("times"),delete(t){const r=Or(e);return delete r[t],e.set("times",r),r}}}function Ir(t){let e,r=0;return{start:n=>{const o=++r;if(null==e||e.scope.dispose(),o!==r||E(t)||1!==n.touches.length||!t.playing||t.isLock)return;const i={scope:jt(t).child(),active:!1,previousRate:1};e=i,i.scope.add(()=>{if(e===i&&(e=void 0,i.active))try{t.playbackRate=i.previousRate}finally{(null==e?void 0:e.active)||Y(t.template.$player,"art-fast-forward")}}),Ft(i.scope,()=>{if(e!==i||E(t)||!t.playing||t.isLock)i.scope.dispose();else try{if(i.previousRate=t.playbackRate,e!==i||i.scope.closed)return;i.active=!0;const r=t.constructor.FAST_FORWARD_VALUE;if(e!==i||i.scope.closed||E(t))return;t.playbackRate=r,e!==i||i.scope.closed||E(t)||V(t.template.$player,"art-fast-forward")}catch(r){try{i.scope.dispose()}catch(n){console.warn("Failed to restore fast-forward playback rate:",n)}throw r}},t.constructor.FAST_FORWARD_TIME)},stop:()=>{r++,null==e||e.scope.dispose()}}}function Nr(t){const{proxy:e,template:{$player:r,$video:n}}=t,o=Ir(t),i=me(t);return e(n,"touchstart",t=>o.start(t)),e(n,"touchcancel",o.stop),i("document:touchmove",o.stop),i("document:touchend",o.stop),i("document:touchcancel",o.stop),i("video:pause",o.stop),i("destroy",o.stop),i("lock",t=>{t&&o.stop()}),{name:"fastForward",get state(){return B(r,"art-fast-forward")}}}function _r(t){const{layers:e,icons:r,template:{$player:n}}=t;function o(){return B(n,"art-lock")}function i(){E(t)||(V(n,"art-lock"),E(t)||(t.isLock=!0,E(t)||t.emit("lock",!0)))}function a(){E(t)||(Y(n,"art-lock"),E(t)||(t.isLock=!1,E(t)||t.emit("lock",!1)))}return e.add({name:"lock",mounted(e){const n=S(e);if(n.closed||E(t))return;const o=Tt(e,r.lock);if(n.closed||E(t))return;const i=Tt(e,r.unlock);n.closed||E(t)||(j(o,"display","none"),M(t,e,"lock",e=>{E(t)||(j(o,"display",e?"inline-flex":"none"),n.closed||E(t)||j(i,"display",e?"none":"inline-flex"))}))},click(){o()?a():i()}}),{name:"lock",get state(){return o()},set state(t){t?i():a()}}}function Wr(t){return me(t)("control",e=>{e?Y(t.template.$player,"art-mini-progress-bar"):V(t.template.$player,"art-mini-progress-bar")}),{name:"mini-progress-bar"}}class Dr{constructor(t){this.art=t,this.id=0;const{option:e}=t;!function(t,e){E(t.art)||!e.miniProgressBar||e.isLive||t.add(Wr),!E(t.art)&&e.lock&&N&&t.add(_r),E(t.art)||!e.autoPlayback||e.isLive||t.add(Rr),!E(t.art)&&e.autoOrientation&&N&&t.add(Ar),!E(t.art)&&e.fastForward&&N&&!e.isLive&&t.add(Nr)}(this,e);for(let r=0;rconsole.warn("Failed to initialize ArtPlayer plugin:",t))}}add(t){it(!E(this.art),"Cannot add a plugin after ArtPlayer is destroyed"),this.id+=1;const e=t.call(this.art,this.art);return e instanceof Promise?e.then(e=>this.next(t,e)):this.next(t,e)}next(t,e){return function(t,e,r){if(E(t.art))return t;const n=r&&r.name||e.name||`plugin${t.id}`;if(E(t.art))return t;let o=n;const i=yt(t,o);if(E(t.art))return t;const a=`Cannot add a plugin that already has the same name: ${n}`;return E(t.art)||(it(!i,a),("object"===typeof n&&null!==n||"function"===typeof n)&&(o=Reflect.ownKeys({[o]:void 0})[0]),E(t.art)||gt(t,o,{value:r})),t}(this,t,e)}}const Fr=new WeakMap;function Vr(t){return!t.closed&&!Fr.get(t)}function Yr(t){Fr.set(t,(Fr.get(t)||0)+1);let e=!0;return()=>{if(!e)return;e=!1;const r=(Fr.get(t)||1)-1;r?Fr.set(t,r):Fr.delete(t)}}const Br=new WeakMap,Hr=new WeakMap,jr=["$parent","$parents","$option","$events","$formatted"];function qr(t){var e,r;const n=new Set;let o=t;for(;o&&!n.has(o);){n.add(o);const t=Br.get(o);if(!t||!t.owner.active||(null==(e=t.owner.scope)?void 0:e.closed)||!t.option.includes(o))return!1;if(!t.parent)return t.owner.root===t.option;if((null==(r=Br.get(t.parent))?void 0:r.owner)!==t.owner)return!1;o=t.parent}return!1}function Ur(t){let e=t;for(;e;){const r=Object.getOwnPropertyDescriptor(e,"name");if(r)return"set"in r?"function"===typeof r.set:Boolean(r.writable&&(e===t||Object.isExtensible(t)));e=Object.getPrototypeOf(e)}return Object.isExtensible(t)}function Xr(t){const e=Br.get(t);if(!e)throw new Error("Setting item has not been formatted");return e}function Gr(t,e){var r;for(let n=0;n{c&&c!==r&&c.dispose()},()=>rn(t,o)])try{e()}catch(d){d instanceof y?l.push(...d.errors):l.push(d)}if(r.closed||E(t)||(o.push(...i.splice(0)),en.set(r,o),Qr.set(e,r),tn.set(e,n)),a(),l.length)throw new y(l)},dispose(){if(s){s=!1;try{r.dispose()}finally{a()}}}}}function ln(t,e,r,n,o,i){const a=i||on(e);if(!Vr(a)||E(t))return;const s=t.proxy(r,n,e=>{if(Vr(a)&&!E(t))try{return o(e)}catch(r){console.warn("ArtPlayer setting callback failed:",r)}});!Vr(a)||E(t)?t.events.remove(s):(Xr(e).events.push(s),i&&i!==Qr.get(e)&&i.add(()=>{const r=Xr(e).events,n=r.indexOf(s);n>=0&&(r.splice(n,1),t.events.remove(s))}))}function cn(t,e,r,n){const o=on(e);if(!Vr(o)||E(t))return;const i=(...e)=>{if(Vr(o)&&!E(t))return n(...e)};t.on(r,i),o.add(()=>{t.off(r,i)})}function dn(t){var e,r;const{art:n,active:o}=t,{controls:i,constructor:{SETTING_WIDTH:a,SETTING_ITEM_HEIGHT:s},template:{$player:l,$setting:c,$bottom:d}}=n;if(!i.setting||!t.show||!o)return;const u=l.getBoundingClientRect(),p=i.setting.getBoundingClientRect(),h=u.width/l.offsetWidth||1,f=(p.left-u.left+p.width/2)/h-l.clientLeft,m=function(t){const{containerWidth:e,containerHeight:r,requestedWidth:n,rows:o,rowHeight:i,controlCenter:a,bottom:s,padding:l}=t,c=Math.min(Math.max(0,l),Math.max(0,e/2)),d=Math.min(Math.max(0,n),Math.max(0,e-2*c));return{width:d,height:Math.min(Math.max(0,o*i),Math.max(0,r-s-c)),left:Math.max(c,Math.min(a-d/2,e-c-d))}}({containerWidth:l.clientWidth,containerHeight:l.clientHeight,requestedWidth:(null==(r=null==(e=o[0])?void 0:e.$parent)?void 0:r.width)||a,rows:o.length+(o===t.option?0:1),rowHeight:s,controlCenter:f,bottom:Number.parseFloat(getComputedStyle(c).bottom)||0,padding:Number.parseFloat(getComputedStyle(d).paddingLeft)||0});c.style.height=`${m.height}px`,c.style.width=`${m.width}px`,n.isRotate||N||(f+m.width/2>l.clientWidth?(c.style.left="",c.style.right=""):(c.style.left=`${m.left}px`,c.style.right="auto"))}const un=new WeakMap;function pn(t){un.delete(t)}const hn=new WeakMap;function fn(t,e){e?hn.set(t,e):hn.delete(t)}function mn(t){var e;const r=new Map(Reflect.ownKeys(t).map(e=>[e,Object.getOwnPropertyDescriptor(t,e)])),n=[],o=hn.get(t),i=null==o?void 0:o();for(const a of["html","icon","tooltip"]){const t=null==(e=r.get(a))?void 0:e.value;t instanceof Node&&n.push({node:t,parent:t.parentNode,next:t.nextSibling})}return()=>{var e,a;for(const n of Reflect.ownKeys(t))!r.has(n)&&(null==(e=Object.getOwnPropertyDescriptor(t,n))?void 0:e.configurable)&&Reflect.deleteProperty(t,n);for(const[n,o]of r)Object.defineProperty(t,n,o);null==i||i(),fn(t,o);for(const{node:t,parent:r,next:o}of n)r?r.insertBefore(t,(null==o?void 0:o.parentNode)===r?o:null):null==(a=t.parentNode)||a.removeChild(t)}}const gn=new WeakMap;function vn(t,e,r,n,o,i,a,s){return d(this,null,function*(){try{const l=on(e),c=on(i),d=(gn.get(i)||0)+1;gn.set(i,d);const u=()=>Vr(l)&&Vr(c)&&!E(t.art)&&gn.get(i)===d;if(null==s||s(),!u())return;const p=yield o.call(t.art,e,r,n);u()&&Reflect.set(i,a,p)}catch(l){console.warn("ArtPlayer setting callback failed:",l)}})}function yn(t){const e=[];return function t(r){const n=Array.from(r.childNodes);e.push({node:r,children:n,attributes:1===r.nodeType?Array.from(r.attributes,t=>[t.name,t.value]):void 0,value:r.nodeValue}),n.forEach(t)}(t),()=>{for(const{node:t,children:r,attributes:n,value:o}of e){for(;t.firstChild;)t.removeChild(t.firstChild);for(const e of r)t.appendChild(e);if(n){const e=t;for(const t of Array.from(e.attributes))e.removeAttribute(t.name);for(const[t,r]of n)e.setAttribute(t,r)}else t.nodeValue=o}}}const bn=new WeakMap;function wn(t){const e=[];for(const n of t)try{n()}catch(r){r instanceof y?e.push(...r.errors):e.push(r)}if(e.length)throw new y(e)}function xn(t){var e;null==(e=bn.get(t))||e()}function kn(t,e){const r=t.find(e.name);if(E(t.art))return r||e;if(!r)return t.add(e);pn(r),xn(r);const n=mn(r),o=r.$item,i=null==o?void 0:o.parentNode,a=null==o?void 0:o.nextSibling,s=o?yn(o):void 0,l=t.active,c=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),d=function(t,e){const r=new Set,n=new Set,o=e=>{if(!r.has(e)&&(r.add(e),e.selector)){const r=t.cache.get(e.selector);r&&n.add(r),e.selector.forEach(o)}};o(e);const i=[],a=[];try{for(const e of r){const r=sn(t.art,e);r&&i.push(r)}for(const t of n)a.push(Yr(Zr(t)))}catch(l){try{wn([...i.reverse().map(t=>t.resume),...a])}catch(c){console.warn("ArtPlayer setting restore failed:",c)}throw l}let s=!0;return{items:r,resume(){s&&(s=!1,wn([...i.reverse().map(t=>t.resume),...a]))},dispose(){s&&(s=!1,wn([...i.reverse().map(t=>t.dispose),...Array.from(n).reverse().map(t=>()=>Jr(t)),...a]))}}}(t,r);let u=!0,p=!1;const h=()=>{if(!u)return;u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);if(E(t.art))return void d.dispose();const e=r.$item;try{wn([d.resume,()=>{e&&e!==o&&e.remove()},n,()=>null==s?void 0:s(),()=>{i&&o&&i.insertBefore(o,(null==a?void 0:a.parentNode)===i?a:null)},()=>t.format(),()=>{if(p){t.active=l,l&&t.cache.has(l)&&X(t.cache.get(l),"art-current");for(const[e,r,n]of c)t.$parent.style.setProperty(e,r,n)}}])}catch(f){console.warn("ArtPlayer setting restore failed:",f)}},f=()=>u&&!E(t.art)&&bn.get(r)===h;for(const v of d.items)bn.set(v,h);const m=$(t.art).add(()=>{u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);d.dispose()});try{if(function(t,e,r){for(const n of Reflect.ownKeys(e)){if(!r())return;const o=Object.getOwnPropertyDescriptor(e,n);if(!(null==o?void 0:o.enumerable)||!r())continue;const i=Reflect.get(e,n);if(!r())return;if(!Reflect.set(t,n,i))throw new TypeError(`Cannot assign setting item property [${String(n)}]`)}}(r,e,f),!f())return r;if(t.format(),!f())return r;if(t.createItem(r,!0),!f())return r;if(p=!0,t.render(),!f())return r;u=!1;for(const t of d.items)bn.get(t)===h&&bn.delete(t);return d.dispose(),r}catch(g){throw f()&&h(),g}finally{m()}}const $n=new WeakMap;function En(t,e,r){gt(t,`$${e}`,{configurable:!0,get:()=>r}),gt(t,e,{configurable:!0,get:()=>r.innerHTML,set(t){r.innerHTML="",H(r,t)}})}function Tn(t,e,r=!1){var n,o;const i=function(t){const e=bn.get(t);return()=>!e||bn.get(t)===e}(e);if(!t.cache.has(e.$option))return;const a=t.cache.get(e.$option),s=e.$item;let l="selector";yt(e,"switch")&&(l="switch"),yt(e,"range")&&(l="range"),yt(e,"onClick")&&(l="button");const{icons:c,constructor:d}=t.art;if(!i())return;const u=function(t,e,r=$(t)){const n=Qr.get(e);(!n||Vr(n)||n.closed)&&an(t,e);const o=r.child();return Qr.set(e,o),tn.set(e,r),en.set(o,Xr(e).events),o.add(()=>{rn(t,en.get(o))}),o}(t.art,e,Zr(a)),p=()=>Vr(u)&&!E(t.art)&&i();if(!p())return;const h=document.createElement("div");try{if(fn(e),V(h,"art-setting-item"),j(h,"height",`${d.SETTING_ITEM_HEIGHT}px`),h.dataset.name=e.name||"",h.dataset.value=String(e.value||""),!p())return;const i=H(h,'
'),f=H(h,'
'),m=document.createElement("div");switch(V(m,"art-setting-item-left-icon"),l){case"button":case"switch":case"range":{const t=e.icon||c.config;if(!p())return;H(m,t);break}case"selector":if(null==(n=e.selector)?void 0:n.length){const t=e.icon||c.config;if(!p())return;H(m,t)}else H(m,c.check)}if(H(i,m),!p())return;En(e,"icon",m);const g=document.createElement("div");V(g,"art-setting-item-left-text");const v=e.html||"";if(!p())return;H(g,v),H(i,g),En(e,"html",g);const y=document.createElement("div");V(y,"art-setting-item-right-tooltip");const b=e.tooltip||"";if(!p())return;switch(H(y,b),H(f,y),En(e,"tooltip",y),l){case"switch":{const t=document.createElement("div");V(t,"art-setting-item-right-icon");const r=H(t,c.switchOn),n=H(t,c.switchOff),o=e.switch;if(!p())return;j(o?n:r,"display","none"),H(f,t),gt(e,"$switch",{configurable:!0,get:()=>t});let i=e.switch;if(!p())return;fn(e,()=>{const t=i;return()=>{i=t}}),gt(e,"switch",{configurable:!0,get:()=>i,set(t){i=t,t?(j(n,"display","none"),j(r,"display",null)):(j(n,"display",null),j(r,"display","none"))}});break}case"range":{const t=document.createElement("div");V(t,"art-setting-item-right-icon");const r=document.createElement("input");r.type="range",H(t,r);for(const[o,i]of["value","min","max","step"].entries()){const t=e.range[o];if(!p())return;Reflect.set(r,i,String(t))}V(r,"art-setting-range"),H(f,t),gt(e,"$range",{configurable:!0,get:()=>r});let n=[...e.range];if(!p())return;fn(e,()=>{const t=n,e=[...t],o={min:r.min,max:r.max,step:r.step,value:r.value};return()=>{t.splice(0,t.length,...e),n=t,Object.assign(r,o)}}),gt(e,"range",{configurable:!0,get:()=>n,set(t){n=[...t],r.value=String(t[0]),r.min=String(t[1]),r.max=String(t[2]),r.step=String(t[3])}})}break;case"selector":if(null==(o=e.selector)?void 0:o.length){const t=document.createElement("div");V(t,"art-setting-item-right-icon"),H(t,c.arrowRight),H(f,t)}}if(!p())return;if(function(t,e,r,n){const{art:o}=t,i=on(e),a=(t,r,n)=>ln(o,e,t,r,n,i);switch(n){case"switch":e.onSwitch&&a(r,"click",n=>vn(t,e,r,n,e.onSwitch,e,"switch"));break;case"range":{const n=e.$range;if(n)for(const[o,i]of[["change","onRange"],["input","onChange"]])e[i]&&a(n,o,o=>vn(t,e,r,o,e[i],e,"tooltip",()=>{e.range[0]=n.valueAsNumber}));break}case"selector":a(r,"click",n=>{var o,i;if(null==(o=e.selector)?void 0:o.length)t.render(e.selector);else{if(null==(i=e.$parent)?void 0:i.onSelect)return vn(t,e,r,n,e.$parent.onSelect,e.$parent,"tooltip",()=>t.check(e));t.check(e)}}),e.default&&V(r,"art-current");break;case"button":e.onClick&&a(r,"click",n=>vn(t,e,r,n,e.onClick,e,"tooltip"))}}(t,e,h,l),!p())return;gt(e,"$item",{configurable:!0,get:()=>h}),r&&(null==s?void 0:s.parentNode)?s.replaceWith(h):H(a,h),e.mounted&&p()&&Ft(u,()=>{var r;if(!E(t.art))try{const n=null==(r=e.mounted)?void 0:r.call(t.art,h,e);Promise.resolve(n).catch(t=>console.warn("ArtPlayer setting mounted failed:",t))}catch(n){console.warn("ArtPlayer setting mounted failed:",n)}},0)}catch(f){try{u.dispose()}catch(m){console.warn("ArtPlayer setting cleanup failed:",m)}throw h.remove(),f}}function Cn(t,e=t.option){var r;if(E(t.art))return;const n=t.cache.get(e);if(n&&!Vr(Zr(n)))return;const o=($n.get(t)||0)+1;$n.set(t,o);const i=()=>$n.get(t)===o&&!E(t.art),a=t.active,s=["height","width","left","right"].map(e=>[e,t.$parent.style.getPropertyValue(e),t.$parent.style.getPropertyPriority(e)]),l=()=>{t.active=a,a&&t.cache.has(a)&&X(t.cache.get(a),"art-current");for(const[e,r,n]of s)t.$parent.style.setProperty(e,r,n)};if(t.active=e,n)try{X(n,"art-current"),t.resize()}catch(c){throw i()&&t.cache.get(e)===n&&!Zr(n).closed&&l(),c}else{const n=document.createElement("div");t.cache.set(e,n);const o=function(t,e,r){const n=$(t.art).child();return Kr.set(r,n),n.add(()=>{t.cache.get(e)===r&&t.cache.delete(e),r.remove()}),n}(t,e,n),a=()=>!o.closed&&!E(t.art)&&t.cache.get(e)===n,s=[];try{if(!a())return;V(n,"art-setting-panel"),H(t.$parent,n),X(n,"art-current"),(null==(r=e[0])?void 0:r.$parent)&&t.createHeader(e[0]);for(let r=0;r{!function(t){const e=Hr.get(t);e&&(e.active=!1,e.root=void 0,e.scope=void 0)}(this)}),e.setting&&(this.format(),this.render(),function(t){const{art:e}=t,r=$(e).child(),n=(t,n)=>{if(r.closed||E(e))return;const o=(...t)=>{if(!r.closed&&!E(e))return n(...t)};e.on(t,o),r.add(()=>{e.off(t,o)})};n("blur",()=>{t.show&&(t.show=!1,t.render())}),n("focus",r=>{const n=K(r,e.controls.setting),o=K(r,t.$parent);!t.show||n||o||(t.show=!1,t.render())}),n("resize",()=>t.resize());const o=()=>{r.closed||E(e)||t.resize()},i=e.proxy(t.$parent,"transitionend",e=>{e.target===t.$parent&&"bottom"===e.propertyName&&o()});r.add(()=>{e.events.remove(i)});const{$player:a,$controls:s}=e.template;if(!r.closed&&"undefined"!==typeof ResizeObserver){const t=new ResizeObserver(o);t.observe(a),t.observe(s),r.add(()=>{t.disconnect()})}if(!r.closed&&"undefined"!==typeof MutationObserver){const t=new MutationObserver(o);"undefined"===typeof ResizeObserver&&t.observe(s,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),t.observe(a,{attributes:!0,attributeFilter:["class","style"]}),r.add(()=>{t.disconnect()})}}(this))}get builtin(){const t=[],{option:e}=this.art;return e.playbackRate&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,PLAYBACK_RATE:o}}=t;function i(t){return 1===t?e.get("Normal"):t.toFixed(1)}function a(){const e=t.setting.find(`playback-rate-${t.playbackRate}`);t.setting.check(e)}return{width:n,name:"playback-rate",html:e.get("Play Speed"),tooltip:i(t.playbackRate),icon:r.playbackRate,selector:o.map(e=>({value:e,name:`playback-rate-${e}`,default:e===t.playbackRate,html:i(e)})),onSelect:e=>(t.playbackRate=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"video:ratechange",()=>a())}}}(this.art)),e.aspectRatio&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,ASPECT_RATIO:o}}=t;function i(t){return"default"===t?e.get("Default"):t}function a(){const e=t.setting.find(`aspect-ratio-${t.aspectRatio}`);t.setting.check(e)}return{width:n,name:"aspect-ratio",html:e.get("Aspect Ratio"),icon:r.aspectRatio,tooltip:i(t.aspectRatio),selector:o.map(e=>({value:e,name:`aspect-ratio-${e}`,default:e===t.aspectRatio,html:i(e)})),onSelect:e=>(t.aspectRatio=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"aspectRatio",()=>a())}}}(this.art)),e.flip&&t.push(function(t){const{i18n:e,icons:r,constructor:{SETTING_ITEM_WIDTH:n,FLIP:o}}=t;function i(t){return e.get(dt(t))}function a(){const e=t.setting.find(`flip-${t.flip}`);t.setting.check(e)}return{width:n,name:"flip",html:e.get("Video Flip"),tooltip:i(t.flip),icon:r.flip,selector:o.map(e=>({value:e,name:`flip-${e}`,default:e===t.flip,html:i(e)})),onSelect:e=>(t.flip=e.value,e.html),mounted:(e,r)=>{a(),cn(t,r,"flip",()=>a())}}}(this.art)),e.subtitleOffset&&t.push(function(t){const{i18n:e,icons:r,constructor:n}=t;return{width:n.SETTING_ITEM_WIDTH,name:"subtitle-offset",html:e.get("Subtitle Offset"),icon:r.subtitle,tooltip:"0s",range:[0,-10,10,.1],onChange:e=>(t.subtitleOffset=e.range[0],`${e.range[0]}s`),mounted:(e,r)=>{cn(t,r,"subtitleOffset",t=>{r.$range.value=String(t),r.tooltip=`${t}s`})}}}(this.art)),t}traverse(t,e=this.option){Gr(e,t)}check(t){!function(t,e){(null==e?void 0:e.$parent)&&(e.$parent.tooltip=e.html,t.traverse(t=>{t.default=t===e,t.default&&t.$item&&X(t.$item,"art-current")},e.$option),t.render(e.$parents))}(this,t)}format(t=this.option,e,r,n=[]){this.option=function(t,e,r,n,o=[]){const i=Hr.get(t)||{active:!0},a=[],s=new Set,l=new Set(o),c=(t,e,r)=>{var n;for(let o=0;oXr(t).parent},$parents:{get:()=>Xr(t).parents},$option:{get:()=>Xr(t).option},$events:{get:()=>Xr(t).events},$formatted:{get:()=>!0}}),Br.set(t,{parent:r,parents:n,option:o,events:(null==a?void 0:a.events)||[],owner:i}),u.generated&&(t.name=e)}for(const u of a)u.generated||o.push(u.name);return t.id=d,e}(this,t,e,r,n)}find(t=""){return function(t,e=""){let r=null;return Gr(t,t=>{t.name===e&&(r=t)}),r}(this.option,t)}resize(){dn(this)}inactivate(t){!function(t,e){const r=[],n=new Set,o=e=>{if(!n.has(e)){n.add(e);for(const t of e.selector||[])o(t);if(e.selector){const n=t.cache.get(e.selector);t.cache.delete(e.selector);try{n&&Jr(n)}catch(i){r.push(i)}}try{an(t.art,e)}catch(i){i instanceof y?r.push(...i.errors):r.push(i)}}};if(o(e),r.length)throw new y(r)}(this,t)}remove(t){const e=this.find(t);it(e,`Can't find [${t}] in the [setting]`),this.traverse(t=>{pn(t),xn(t)},[e]);const r=e.$option.indexOf(e);e.$option.splice(r,1);const n=e.$item,o=[];for(const a of[()=>this.inactivate(e),()=>null==n?void 0:n.remove(),()=>this.render()])try{a()}catch(i){i instanceof y?o.push(...i.errors):o.push(i)}if(o.length)throw new y(o)}update(t){return kn(this,t)}add(t,e=this.option){var r;if(E(this.art))return t;let n=!1;this.traverse(e=>{n||(n=e===t)});const o=e.length,i=n?void 0:function(t){const e={};un.set(t,e);const r=()=>un.get(t)===e;return{current:r,finish(){r()&&un.delete(t)}}}(t);let a=!1;try{e.push(t),this.format(),a=!0,this.createItem(t),this.render()}catch(s){if(E(this.art)||i&&!i.current())throw s;if(e[o]===t&&e.splice(o,1),!n&&a){try{this.inactivate(t)}catch(l){console.warn("ArtPlayer setting cleanup failed:",l)}null==(r=t.$item)||r.remove()}throw s}finally{null==i||i.finish()}return t}createHeader(t){!function(t,e){if(!t.cache.has(e.$option))return;const r=t.cache.get(e.$option),{icons:{arrowLeft:n},constructor:{SETTING_ITEM_HEIGHT:o}}=t.art,i=document.createElement("div");j(i,"height",`${o}px`),V(i,"art-setting-item"),V(i,"art-setting-item-back");const a=H(i,'
'),s=document.createElement("div");V(s,"art-setting-item-left-icon"),H(s,n),H(a,s),H(a,e.$parent.html),ln(t.art,e.$parent,i,"click",()=>t.render(e.$parents),Zr(r)),H(r,i)}(this,t)}createItem(t,e=!1){Tn(this,t,e)}render(t=this.option){Cn(this,t)}}class Pn{constructor(){this.name="artplayer_settings",this.settings={}}get(t){try{const e=JSON.parse(window.localStorage.getItem(this.name))||{};return t?e[t]:e}catch(e){return t?this.settings[t]:this.settings}}set(t,e){try{const r=Object.assign({},this.get(),{[t]:e});window.localStorage.setItem(this.name,JSON.stringify(r))}catch(r){this.settings[t]=e}}del(t){try{const e=this.get();delete e[t],window.localStorage.setItem(this.name,JSON.stringify(e))}catch(e){delete this.settings[t]}}clear(){try{window.localStorage.removeItem(this.name)}catch(t){this.settings={}}}}const Mn='.art-video-player{--art-theme: #f00;--art-font-color: #fff;--art-background-color: #000;--art-text-shadow-color: rgba(0, 0, 0, .5);--art-transition-duration: .2s;--art-padding: 10px;--art-border-radius: 3px;--art-progress-height: 6px;--art-progress-color: rgba(255, 255, 255, .25);--art-progress-top-gap: 10px;--art-hover-color: rgba(255, 255, 255, .25);--art-loaded-color: rgba(255, 255, 255, .25);--art-state-size: 80px;--art-state-opacity: .8;--art-bottom-height: 100px;--art-bottom-offset: 20px;--art-bottom-gap: 5px;--art-highlight-width: 8px;--art-highlight-color: rgba(255, 255, 255, .5);--art-control-height: 46px;--art-control-opacity: .75;--art-control-icon-size: 36px;--art-control-icon-scale: 1.1;--art-volume-height: 120px;--art-volume-handle-size: 14px;--art-lock-size: 36px;--art-indicator-scale: 0;--art-indicator-size: 16px;--art-fullscreen-web-index: 9999;--art-settings-icon-size: 24px;--art-settings-max-height: 300px;--art-selector-max-height: 300px;--art-contextmenus-min-width: 250px;--art-subtitle-font-size: 20px;--art-subtitle-gap: 5px;--art-subtitle-bottom: 15px;--art-subtitle-border: #000;--art-widget-background: rgba(0, 0, 0, .85);--art-tip-background: rgba(0, 0, 0, .7);--art-scrollbar-size: 4px;--art-scrollbar-background: rgba(255, 255, 255, .25);--art-scrollbar-background-hover: rgba(255, 255, 255, .5);--art-mini-progress-height: 2px}.art-bg-cover{background-position:center center;background-repeat:no-repeat;background-size:cover}.art-bottom-gradient{background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player{position:relative;margin:0 auto;width:100%;height:100%;outline:0;zoom:1;padding:0;text-align:left;direction:ltr;font-size:14px;line-height:1.3;user-select:none;box-sizing:border-box;color:var(--art-font-color);background-color:var(--art-background-color);text-shadow:0 0 2px var(--art-text-shadow-color);font-family:PingFang SC,Helvetica Neue,Microsoft YaHei,Roboto,Arial,sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-touch-action:manipulation;touch-action:manipulation;-ms-high-contrast-adjust:none}.art-video-player *,.art-video-player *:before,.art-video-player *:after{box-sizing:border-box}.art-video-player ::-webkit-scrollbar{width:var(--art-scrollbar-size);height:var(--art-scrollbar-size)}.art-video-player ::-webkit-scrollbar-thumb{background-color:var(--art-scrollbar-background)}.art-video-player ::-webkit-scrollbar-thumb:hover{background-color:var(--art-scrollbar-background-hover)}.art-video-player img{max-width:100%;vertical-align:top}.art-video-player svg{fill:var(--art-font-color)}.art-video-player a{color:var(--art-font-color);text-decoration:none}.art-icon{line-height:1;display:flex;justify-content:center;align-items:center}.art-video-player.art-backdrop .art-contextmenus,.art-video-player.art-backdrop .art-info,.art-video-player.art-backdrop .art-settings,.art-video-player.art-backdrop .art-layer-auto-playback,.art-video-player.art-backdrop .art-selector-list,.art-video-player.art-backdrop .art-volume-inner{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);background-color:#000000bf!important}.art-video{position:absolute;inset:0;z-index:10;width:100%;height:100%}.art-poster{position:absolute;inset:0;z-index:11;width:100%;height:100%;background-position:center center;background-repeat:no-repeat;background-size:cover;pointer-events:none}.art-video-player .art-subtitle{display:none;justify-content:center;align-items:center;flex-direction:column;position:absolute;z-index:20;width:100%;padding:0 5%;text-align:center;pointer-events:none;gap:var(--art-subtitle-gap);bottom:var(--art-subtitle-bottom);font-size:var(--art-subtitle-font-size);transition:bottom var(--art-transition-duration) ease;text-shadow:var(--art-subtitle-border) 1px 0 1px,var(--art-subtitle-border) 0 1px 1px,var(--art-subtitle-border) -1px 0 1px,var(--art-subtitle-border) 0 -1px 1px,var(--art-subtitle-border) 1px 1px 1px,var(--art-subtitle-border) -1px -1px 1px,var(--art-subtitle-border) 1px -1px 1px,var(--art-subtitle-border) -1px 1px 1px}.art-video-player.art-subtitle-show .art-subtitle{display:flex}.art-video-player.art-control-show .art-subtitle{bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-subtitle-bottom))}.art-danmuku{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none;overflow:hidden}.art-video-player .art-layers{position:absolute;inset:0;z-index:40;width:100%;height:100%;display:none;pointer-events:none}.art-video-player .art-layers .art-layer{pointer-events:auto}.art-video-player.art-layer-show .art-layers{display:flex}.art-video-player .art-mask{display:flex;justify-content:center;align-items:center;position:absolute;inset:0;z-index:50;width:100%;height:100%;pointer-events:none}.art-video-player .art-mask .art-state{display:flex;justify-content:center;align-items:center;opacity:0;transform:scale(2);width:var(--art-state-size);height:var(--art-state-size);transition:all var(--art-transition-duration) ease}.art-video-player.art-mask-show .art-state{pointer-events:auto;opacity:var(--art-state-opacity);transform:scale(1)}.art-video-player.art-loading-show .art-state{display:none}.art-video-player .art-loading{display:none;justify-content:center;align-items:center;position:absolute;inset:0;z-index:70;width:100%;height:100%;pointer-events:none}.art-video-player.art-loading-show .art-loading{display:flex}.art-video-player.art-loading-show .art-mask{display:none}.art-video-player .art-bottom{position:absolute;inset:0;z-index:60;width:100%;height:100%;display:flex;flex-direction:column;justify-content:flex-end;opacity:0;overflow:hidden;pointer-events:none;padding:0 var(--art-padding);transition:all var(--art-transition-duration) ease;background-size:100% var(--art-bottom-height);background-image:linear-gradient(to top,#000,rgba(0,0,0,.4),transparent);background-repeat:repeat-x;background-position:center bottom}.art-video-player .art-bottom .art-controls,.art-video-player .art-bottom .art-progress{transform:translateY(var(--art-bottom-offset));transition:transform var(--art-transition-duration) ease}.art-video-player.art-control-show .art-bottom,.art-video-player.art-hover .art-bottom{opacity:1}.art-video-player.art-control-show .art-bottom .art-controls,.art-video-player.art-hover .art-bottom .art-controls,.art-video-player.art-control-show .art-bottom .art-progress,.art-video-player.art-hover .art-bottom .art-progress{transform:translateY(0)}.art-bottom .art-progress{position:relative;z-index:0;cursor:pointer;pointer-events:auto;padding-top:var(--art-progress-top-gap);padding-bottom:var(--art-bottom-gap)}.art-bottom .art-progress .art-control-progress{position:relative;display:flex;justify-content:center;align-items:center;height:var(--art-progress-height)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner{display:flex;align-items:center;position:relative;height:50%;width:100%;transition:height var(--art-transition-duration) ease;background-color:var(--art-progress-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-hover{position:absolute;inset:0;z-index:0;width:100%;height:100%;width:0%;background-color:var(--art-hover-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-loaded{position:absolute;inset:0;z-index:10;width:100%;height:100%;width:0%;background-color:var(--art-loaded-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-played{position:absolute;inset:0;z-index:20;width:100%;height:100%;width:0%;background-color:var(--art-theme)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight{position:absolute;inset:0;z-index:30;width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-highlight span{position:absolute;inset:0 auto 0 0;z-index:0;width:100%;height:100%;pointer-events:auto;width:var(--art-highlight-width)!important;transform:translate(calc(var(--art-highlight-width) / -2));background-color:var(--art-highlight-color)}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{display:flex;justify-content:center;align-items:center;position:absolute;z-index:40;left:0;border-radius:50%;width:var(--art-indicator-size);height:var(--art-indicator-size);transform:scale(var(--art-indicator-scale));margin-left:calc(var(--art-indicator-size) / -2);transition:transform var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator .art-icon{width:100%;height:100%;pointer-events:none}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:hover{transform:scale(1.2)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator:active{transform:scale(1)!important}.art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;z-index:50;top:-25px;left:0;padding:3px 5px;line-height:1;font-size:12px;border-radius:var(--art-border-radius);white-space:nowrap;background-color:var(--art-tip-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease}.art-bottom .art-progress .art-control-thumbnails{transform-origin:bottom center;transform:scale(.5);opacity:0;position:absolute;bottom:calc(var(--art-bottom-gap) + 10px);left:0;border-radius:var(--art-border-radius);pointer-events:none;background-color:var(--art-widget-background);transition:transform var(--art-transition-duration) ease,opacity var(--art-transition-duration) ease;box-shadow:0 1px 3px #0003,0 1px 2px -1px #0003}.art-bottom .art-progress:hover .art-control-progress .art-control-progress-inner{height:100%}.art-bottom:hover .art-progress .art-control-progress .art-control-progress-inner .art-progress-indicator{transform:scale(1)}.art-progress-hover .art-bottom .art-progress .art-control-progress .art-control-progress-inner .art-progress-tip,.art-progress-hover .art-bottom .art-progress .art-control-thumbnails{transform:scale(1);opacity:1}.art-video-player .art-controls{position:relative;z-index:10;pointer-events:auto;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;flex-shrink:0;height:auto;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-left,.art-video-player .art-controls .art-controls-right{display:flex;flex-wrap:wrap;max-width:100%;min-height:var(--art-control-height)}.art-video-player .art-controls .art-controls-center{display:none;justify-content:center;align-items:center;flex:1;height:100%;padding:0 10px}.art-video-player .art-controls .art-controls-right{justify-content:flex-end;margin-left:auto}.art-video-player .art-controls .art-control{display:flex;justify-content:center;align-items:center;flex-shrink:0;max-width:100%;cursor:pointer;white-space:nowrap;opacity:var(--art-control-opacity);min-height:var(--art-control-height);min-width:var(--art-control-height);transition:opacity var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon{height:var(--art-control-icon-size);width:var(--art-control-icon-size);transform:scale(var(--art-control-icon-scale));transition:transform var(--art-transition-duration) ease}.art-video-player .art-controls .art-control .art-icon:active{transform:scale(calc(var(--art-control-icon-scale) * .8))}.art-video-player .art-controls .art-control:hover{opacity:1}.art-control-volume{position:relative}.art-control-volume .art-volume-panel{display:flex;justify-content:center;align-items:center;position:absolute;left:0;right:0;padding:0 5px;font-size:12px;text-align:center;cursor:default;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);width:var(--art-control-height);height:var(--art-volume-height);transition:all var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner{display:flex;flex-direction:column;align-items:center;gap:10px;height:100%;width:100%;padding:10px 0 12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider{flex:1;width:100%;display:flex;cursor:pointer;position:relative;justify-content:center}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle{position:relative;display:flex;justify-content:center;width:2px;border-radius:var(--art-border-radius);overflow:hidden;background-color:#ffffff40}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-handle .art-volume-loaded{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:var(--art-theme)}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider .art-volume-indicator{position:absolute;width:var(--art-volume-handle-size);height:var(--art-volume-handle-size);margin-top:calc(var(--art-volume-handle-size) / -2);flex-shrink:0;transform:scale(1);border-radius:100%;background-color:var(--art-theme);transition:transform var(--art-transition-duration) ease}.art-control-volume .art-volume-panel .art-volume-inner .art-volume-slider:active .art-volume-indicator{transform:scale(.9)}.art-control-volume:hover .art-volume-panel{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player .art-notice{display:none;position:absolute;inset:0 0 auto;z-index:80;width:100%;height:100%;height:auto;padding:var(--art-padding);pointer-events:none}.art-video-player .art-notice .art-notice-inner{display:inline-flex;padding:5px;line-height:1;border-radius:var(--art-border-radius);background-color:var(--art-tip-background)}.art-video-player.art-notice-show .art-notice{display:flex}.art-video-player .art-contextmenus{display:none;flex-direction:column;position:absolute;z-index:120;padding:5px 0;border-radius:var(--art-border-radius);font-size:12px;background-color:var(--art-widget-background);min-width:var(--art-contextmenus-min-width)}.art-video-player .art-contextmenus .art-contextmenu{cursor:pointer;display:flex;padding:10px 15px;border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player .art-contextmenus .art-contextmenu span{padding:0 8px}.art-video-player .art-contextmenus .art-contextmenu span:hover,.art-video-player .art-contextmenus .art-contextmenu span.art-current{color:var(--art-theme)}.art-video-player .art-contextmenus .art-contextmenu:hover{background-color:#ffffff1a}.art-video-player .art-contextmenus .art-contextmenu:last-child{border-bottom:none}.art-video-player.art-contextmenu-show .art-contextmenus{display:flex}.art-video-player .art-settings{display:none;flex-direction:column;position:absolute;z-index:90;left:auto;overflow-y:auto;overflow-x:hidden;border-radius:var(--art-border-radius);max-height:var(--art-settings-max-height);right:var(--art-padding);bottom:var(--art-controls-height, var(--art-control-height));transition:all var(--art-transition-duration) ease;background-color:var(--art-widget-background)}.art-video-player .art-settings .art-setting-panel{display:none;flex-direction:column}.art-video-player .art-settings .art-setting-panel.art-current{display:flex}.art-video-player .art-settings .art-setting-panel .art-setting-item{display:flex;justify-content:space-between;align-items:center;gap:5px;padding:0 5px;cursor:pointer;overflow:hidden;transition:background-color var(--art-transition-duration) ease}.art-video-player .art-settings .art-setting-panel .art-setting-item:hover{background-color:#ffffff1a}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current{color:var(--art-theme)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-icon-check{visibility:hidden;height:15px}.art-video-player .art-settings .art-setting-panel .art-setting-item.art-current .art-icon-check{visibility:visible}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left{display:flex;justify-content:center;align-items:center;flex-shrink:1;min-width:0;overflow:hidden;gap:5px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;height:var(--art-settings-icon-size);width:var(--art-settings-icon-size)}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-left .art-setting-item-left-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:0;max-width:55%;gap:5px;font-size:12px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-tooltip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff80}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-item-right-icon{display:flex;justify-content:center;align-items:center;flex-shrink:0;min-width:32px;height:24px}.art-video-player .art-settings .art-setting-panel .art-setting-item .art-setting-item-right .art-setting-range{height:3px;width:80px;outline:none;appearance:none;background-color:#fff3}.art-video-player .art-settings .art-setting-panel .art-setting-item-back{border-bottom:1px solid rgba(255,255,255,.1)}.art-video-player.art-setting-show .art-settings{display:flex}.art-video-player .art-info{display:none;position:absolute;left:var(--art-padding);top:var(--art-padding);z-index:100;padding:10px;font-size:12px;border-radius:var(--art-border-radius);background-color:var(--art-widget-background)}.art-video-player .art-info .art-info-panel{display:flex;flex-direction:column;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item{display:flex;align-items:center;gap:5px}.art-video-player .art-info .art-info-panel .art-info-item .art-info-title{width:100px;text-align:right}.art-video-player .art-info .art-info-panel .art-info-item .art-info-content{width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:all}.art-video-player .art-info .art-info-close{position:absolute;top:5px;right:5px;cursor:pointer}.art-video-player.art-info-show .art-info{display:flex}.art-hide-cursor *{cursor:none!important}.art-video-player[data-aspect-ratio]{overflow:hidden}.art-video-player[data-aspect-ratio] .art-video{object-fit:fill;box-sizing:content-box}.art-fullscreen{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3}.art-fullscreen-web{--art-progress-height: 8px;--art-indicator-size: 20px;--art-control-height: 60px;--art-control-icon-scale: 1.3;position:fixed;inset:0;z-index:var(--art-fullscreen-web-index);width:100%;height:100%}.art-mini-popup{position:fixed;z-index:9999;width:320px;height:180px;max-width:100vw;max-height:100vh;background:#000;border-radius:var(--art-border-radius);cursor:move;user-select:none;overflow:hidden;transition:opacity .2s ease;box-shadow:0 0 5px #00000080}.art-mini-popup svg{fill:#fff}.art-mini-popup .art-video{pointer-events:none}.art-mini-popup .art-mini-close{position:absolute;z-index:20;right:10px;top:10px;cursor:pointer;opacity:0;transition:opacity .2s ease}.art-mini-popup .art-mini-state{position:absolute;inset:0;z-index:30;width:100%;height:100%;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transition:opacity .2s ease;background-color:#00000040}.art-mini-popup .art-mini-state .art-icon{opacity:.75;cursor:pointer;transform:scale(3);pointer-events:auto;transition:transform .2s ease}.art-mini-popup .art-mini-state .art-icon:active{transform:scale(2.5)}.art-mini-popup.art-mini-dragging{opacity:.9}.art-mini-popup:hover .art-mini-close,.art-mini-popup:hover .art-mini-state{opacity:1}.art-video-player[data-flip=horizontal] .art-video{transform:scaleX(-1)}.art-video-player[data-flip=vertical] .art-video{transform:scaleY(-1)}.art-video-player .art-layer-lock{display:none;justify-content:center;align-items:center;position:absolute;top:50%;border-radius:50%;transform:translateY(-50%);height:var(--art-lock-size);width:var(--art-lock-size);left:var(--art-padding);background-color:var(--art-tip-background)}.art-video-player .art-layer-auto-playback{display:none;gap:10px;align-items:center;position:absolute;border-radius:var(--art-border-radius);padding:10px;line-height:1;left:var(--art-padding);bottom:calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + 10px);background-color:var(--art-widget-background)}.art-video-player .art-layer-auto-playback .art-auto-playback-close{display:flex;justify-content:center;align-items:center;cursor:pointer}.art-video-player .art-layer-auto-playback .art-auto-playback-close svg{width:15px;height:15px;fill:var(--art-theme)}.art-video-player .art-layer-auto-playback .art-auto-playback-jump{color:var(--art-theme);cursor:pointer}.art-video-player.art-lock .art-subtitle{bottom:var(--art-subtitle-bottom)!important}.art-video-player.art-mini-progress-bar .art-bottom,.art-video-player.art-lock .art-bottom{opacity:1;padding:0;background-image:none}.art-video-player.art-mini-progress-bar .art-bottom .art-controls,.art-video-player.art-lock .art-bottom .art-controls,.art-video-player.art-mini-progress-bar .art-bottom .art-progress,.art-video-player.art-lock .art-bottom .art-progress{transform:translateY(calc(var(--art-controls-height, var(--art-control-height)) + var(--art-bottom-gap) + var(--art-progress-height) / 4))}.art-video-player.art-mini-progress-bar .art-bottom .art-progress-indicator,.art-video-player.art-lock .art-bottom .art-progress-indicator{display:none!important}.art-video-player.art-control-show .art-layer-lock{display:flex}.art-control-selector{position:relative;display:flex;justify-content:center}.art-control-selector .art-selector-list{display:flex;flex-direction:column;align-items:center;text-align:center;position:absolute;border-radius:var(--art-border-radius);overflow-y:auto;overflow-x:hidden;opacity:0;transform:translateY(10px);pointer-events:none;bottom:var(--art-control-height);max-height:var(--art-selector-max-height);background-color:var(--art-widget-background);transition:all var(--art-transition-duration) ease}.art-control-selector .art-selector-list .art-selector-item{display:flex;justify-content:center;align-items:center;width:100%;padding:10px 15px;flex-shrink:0;line-height:1}.art-control-selector .art-selector-list .art-selector-item:hover{background-color:#ffffff1a}.art-control-selector .art-selector-list .art-selector-item:hover,.art-control-selector .art-selector-list .art-selector-item.art-current{color:var(--art-theme)}.art-control-selector:hover .art-selector-list{opacity:1;transform:translateY(0);pointer-events:auto}.art-video-player [class*=hint--]{position:relative;display:inline-block;font-style:normal}.art-video-player [class*=hint--]:before,.art-video-player [class*=hint--]:after{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{visibility:visible;opacity:1}.art-video-player [class*=hint--]:hover:before,.art-video-player [class*=hint--]:hover:after{-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}.art-video-player [class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.art-video-player [class*=hint--]:after{background:#000;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}.art-video-player [class*=hint--][aria-label]:after{content:attr(aria-label)}.art-video-player [class*=hint--][data-hint]:after{content:attr(data-hint)}.art-video-player [aria-label=""]:before,.art-video-player [aria-label=""]:after,.art-video-player [data-hint=""]:before,.art-video-player [data-hint=""]:after{display:none!important}.art-video-player .hint--top-left:before{border-top-color:#000}.art-video-player .hint--top-right:before{border-top-color:#000}.art-video-player .hint--top:before{border-top-color:#000}.art-video-player .hint--bottom-left:before{border-bottom-color:#000}.art-video-player .hint--bottom-right:before{border-bottom-color:#000}.art-video-player .hint--bottom:before{border-bottom-color:#000}.art-video-player .hint--left:before{border-left-color:#000}.art-video-player .hint--right:before{border-right-color:#000}.art-video-player .hint--top:before{margin-bottom:-11px}.art-video-player .hint--top:before,.art-video-player .hint--top:after{bottom:100%;left:50%}.art-video-player .hint--top:before{left:calc(50% - 6px)}.art-video-player .hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--bottom:before{margin-top:-11px}.art-video-player .hint--bottom:before,.art-video-player .hint--bottom:after{top:100%;left:50%}.art-video-player .hint--bottom:before{left:calc(50% - 6px)}.art-video-player .hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translate(-50%)}.art-video-player .hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--right:before{margin-left:-11px;margin-bottom:-6px}.art-video-player .hint--right:after{margin-bottom:-14px}.art-video-player .hint--right:before,.art-video-player .hint--right:after{left:100%;bottom:50%}.art-video-player .hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--left:before{margin-right:-11px;margin-bottom:-6px}.art-video-player .hint--left:after{margin-bottom:-14px}.art-video-player .hint--left:before,.art-video-player .hint--left:after{right:100%;bottom:50%}.art-video-player .hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--top-left:before{margin-bottom:-11px}.art-video-player .hint--top-left:before,.art-video-player .hint--top-left:after{bottom:100%;left:50%}.art-video-player .hint--top-left:before{left:calc(50% - 6px)}.art-video-player .hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--top-left:after{margin-left:12px}.art-video-player .hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--top-right:before{margin-bottom:-11px}.art-video-player .hint--top-right:before,.art-video-player .hint--top-right:after{bottom:100%;left:50%}.art-video-player .hint--top-right:before{left:calc(50% - 6px)}.art-video-player .hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--top-right:after{margin-left:-12px}.art-video-player .hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--top-right:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--bottom-left:before{margin-top:-11px}.art-video-player .hint--bottom-left:before,.art-video-player .hint--bottom-left:after{top:100%;left:50%}.art-video-player .hint--bottom-left:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translate(-100%)}.art-video-player .hint--bottom-left:after{margin-left:12px}.art-video-player .hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--bottom-right:before{margin-top:-11px}.art-video-player .hint--bottom-right:before,.art-video-player .hint--bottom-right:after{top:100%;left:50%}.art-video-player .hint--bottom-right:before{left:calc(50% - 6px)}.art-video-player .hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translate(0)}.art-video-player .hint--bottom-right:after{margin-left:-12px}.art-video-player .hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--bottom-right:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--small:after,.art-video-player .hint--medium:after,.art-video-player .hint--large:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.art-video-player .hint--small:after{width:80px}.art-video-player .hint--medium:after{width:150px}.art-video-player .hint--large:after{width:300px}.art-video-player [class*=hint--]:after{text-shadow:0 -1px 0px black;box-shadow:4px 4px 8px #0000004d}.art-video-player .hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0px #592726}.art-video-player .hint--error.hint--top-left:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top-right:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--top:before{border-top-color:#b34e4d}.art-video-player .hint--error.hint--bottom-left:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom-right:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.art-video-player .hint--error.hint--left:before{border-left-color:#b34e4d}.art-video-player .hint--error.hint--right:before{border-right-color:#b34e4d}.art-video-player .hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0px #6c5328}.art-video-player .hint--warning.hint--top-left:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top-right:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--top:before{border-top-color:#c09854}.art-video-player .hint--warning.hint--bottom-left:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom-right:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--bottom:before{border-bottom-color:#c09854}.art-video-player .hint--warning.hint--left:before{border-left-color:#c09854}.art-video-player .hint--warning.hint--right:before{border-right-color:#c09854}.art-video-player .hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0px #1a3c4d}.art-video-player .hint--info.hint--top-left:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top-right:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--top:before{border-top-color:#3986ac}.art-video-player .hint--info.hint--bottom-left:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom-right:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--bottom:before{border-bottom-color:#3986ac}.art-video-player .hint--info.hint--left:before{border-left-color:#3986ac}.art-video-player .hint--info.hint--right:before{border-right-color:#3986ac}.art-video-player .hint--success:after{background-color:#458746;text-shadow:0 -1px 0px #1a321a}.art-video-player .hint--success.hint--top-left:before{border-top-color:#458746}.art-video-player .hint--success.hint--top-right:before{border-top-color:#458746}.art-video-player .hint--success.hint--top:before{border-top-color:#458746}.art-video-player .hint--success.hint--bottom-left:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom-right:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--bottom:before{border-bottom-color:#458746}.art-video-player .hint--success.hint--left:before{border-left-color:#458746}.art-video-player .hint--success.hint--right:before{border-right-color:#458746}.art-video-player .hint--always:after,.art-video-player .hint--always:before{opacity:1;visibility:visible}.art-video-player .hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translate(-50%) translateY(-8px)}.art-video-player .hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translate(-100%) translateY(-8px)}.art-video-player .hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--top-right:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.art-video-player .hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translate(-50%) translateY(8px)}.art-video-player .hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translate(-100%) translateY(8px)}.art-video-player .hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--bottom-right:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.art-video-player .hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--left:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translate(-8px)}.art-video-player .hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--always.hint--right:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translate(8px)}.art-video-player .hint--rounded:after{border-radius:4px}.art-video-player .hint--no-animate:before,.art-video-player .hint--no-animate:after{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.art-video-player .hint--bounce:before,.art-video-player .hint--bounce:after{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.art-video-player .hint--no-shadow:before,.art-video-player .hint--no-shadow:after{text-shadow:initial;box-shadow:initial}.art-video-player .hint--no-arrow:before{display:none}.art-video-player.art-mobile{--art-bottom-gap: 10px;--art-control-height: 38px;--art-control-icon-scale: 1;--art-state-size: 60px;--art-settings-max-height: 180px;--art-selector-max-height: 180px;--art-indicator-scale: 1;--art-control-opacity: 1}.art-video-player.art-mobile .art-controls-left{margin-left:calc(var(--art-padding) / -1)}.art-video-player.art-mobile .art-controls-right{margin-right:calc(var(--art-padding) / -1)}';class zn{constructor(t){var e;this.scope=t.child(),this.cancelled=new Promise(t=>{this.scope.add(()=>{t(void 0)})}),this.signal=null==(e=function(t){if("undefined"===typeof AbortController)return;const e=new AbortController;return t.add(()=>{e.abort()}),e}(this.scope))?void 0:e.signal}get active(){return!this.scope.closed}cancel(){this.scope.dispose()}run(t){return d(this,null,function*(){if(this.active)try{return yield Promise.race([t(),this.cancelled])}finally{this.cancel()}})}}const An=new WeakMap;function On(t){return An.get(t)}function Rn(t){const e=t.ownedURL;t.ownedURL=void 0,e&&URL.revokeObjectURL(e)}const In=_t;class Nn extends In{constructor(t){super(t),this.name="subtitle",this.option=null,this.destroyEvent=()=>null;const e=function(t,e){const r=$(e).child(),n={scope:r,revision:0,render:0,trackRevision:0};return An.set(t,n),r.add(()=>{Rn(n)}),n}(this,t);this.init(t.option.subtitle).catch(()=>{});let r=!1;const n=()=>{if(e.scope.closed||!this.url)return;const n=t.template.$video.webkitDisplayingFullscreen;"boolean"===typeof n&&n!==r&&(r=n,this.createTrack(n?"subtitles":"metadata",this.url))};t.on("video:timeupdate",n),e.scope.add(()=>{t.off("video:timeupdate",n)})}get url(){return this.art.template.$track.src}set url(t){this.switch(t).catch(()=>{})}get textTrack(){var t,e;return null==(e=null==(t=this.art.template.$video)?void 0:t.textTracks)?void 0:e[0]}get activeCues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.activeCues)||[])}get cues(){var t;return Array.from((null==(t=this.textTrack)?void 0:t.cues)||[])}style(t,e){const{$subtitle:r}=this.art.template;return"object"===typeof t?q(r,t):j(r,t,e)}update(){!function(t){const e=On(t);if(e.scope.closed)return;const r=e.revision,n=++e.render,o=()=>!e.scope.closed&&e.revision===r&&e.render===n,{art:i}=t,{$subtitle:a}=i.template;if(a.innerHTML="",!t.activeCues.length)return;if(i.emit("subtitleBeforeUpdate",t.activeCues),!o())return;const s=t.activeCues.map((t,e)=>t.text.split(/\r?\n/).filter(t=>t.trim()).map(t=>`
\n ${i.option.subtitle.escape?mt(t):t}\n
`).join("")).join("");o()&&(a.innerHTML=s,i.emit("subtitleAfterUpdate",t.activeCues))}(this)}switch(t){return d(this,arguments,function*(t,e={}){const{i18n:r,notice:n,option:o}=this.art,i=c(l(l({},o.subtitle),e),{url:t}),a=On(this),s=a.revision+1,d=yield this.init(i);return!a.scope.closed&&a.revision===s&&e.name&&(n.show=`${r.get("Switch Subtitle")}: ${e.name}`),d})}createTrack(t,e){!function(t,e,r){const n=On(t);if(n.scope.closed)return;const o=++n.trackRevision,{art:i}=t,{template:a}=i,s=a.$track,l=s.parentNode,c=s.nextSibling,d=document.createElement("track"),u=n.scope.child();u.add(()=>{d.onload=null,d.onerror=null});let p=!1;try{if(d.default=!0,d.kind=e,d.src=r,d.label=i.option.subtitle.name||"Artplayer",d.track.mode="hidden",d.onload=()=>{u.closed||a.$track!==d||i.emit("subtitleLoad",t.cues,t.option)},d.onerror=()=>{u.closed||a.$track!==d||(i.notice.show=new Error("Failed to load subtitle track"))},u.closed||n.trackRevision!==o)return void u.dispose();s.remove(),a.$video.appendChild(d),a.$track=d;const l=t.textTrack,c=l?i.proxy(l,"cuechange",()=>{u.closed||a.$track!==d||t.update()}):()=>{};if(u.add(()=>{i.events.remove(c)}),u.closed||n.trackRevision!==o)return u.dispose(),void d.remove();const h=n.track;n.track=u,t.destroyEvent=c,s.onload=null,s.onerror=null,p=!0;try{null==h||h.dispose()}finally{n.ownedURL&&n.ownedURL!==r&&Rn(n)}}catch(h){if(p)throw h;if(u.dispose(),d.remove(),n.scope.closed||n.trackRevision!==o)throw h;throw a.$track=s,l&&l.insertBefore(s,(null==c?void 0:c.parentNode)===l?c:null),h}}(this,t,e)}init(t){return d(this,null,function*(){const e=On(this),r=function(t){const e=t.request,r=new zn(t.scope);return t.request=r,t.revision+=1,null==e||e.cancel(),r}(e),{notice:n,template:{$subtitle:o}}=this.art;return r.run(()=>d(this,null,function*(){if(!this.textTrack)return null;if(m(t,It.subtitle),!t.url)return;let i;this.option=t,this.style(t.style);try{if(!r.active)return;const n=yield fetch(t.url,{signal:r.signal});if(!r.active)return;if(!n.ok)throw new Error(`Failed to load subtitle: ${n.status} ${n.statusText}`);const a=yield n.arrayBuffer();if(!r.active)return;const s=function(t,e){const r=new TextDecoder(e.encoding).decode(t);switch(e.type||st(e.url)){case"srt":return{vtt:e.onVttLoad(xt(r))};case"ass":return{vtt:e.onVttLoad($t(r))};case"vtt":return{vtt:e.onVttLoad(r)};default:return}}(a,t);if(!r.active)return;const l=void 0===s?t.url:i=kt(s.vtt);if(!r.active)return;o.innerHTML="";const c=e.trackRevision+1;if(this.url!==l&&this.createTrack("metadata",l),!r.active||e.trackRevision>c)return;return i&&(e.ownedURL=i,i=void 0),l}catch(a){if(!r.active)return;throw o.innerHTML="",n.show=a,a}finally{i&&(e.scope.closed||this.url!==i?URL.revokeObjectURL(i):e.ownedURL=i)}}))})}}const _n=`\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Player version:
\n
${g}
\n
\n
\n
Video url:
\n
\n
\n
\n
Video volume:
\n
\n
\n
\n
Video time:
\n
\n
\n
\n
Video duration:
\n
\n
\n
\n
Video resolution:
\n
\n x \n
\n
\n
\n
[x]
\n
\n
\n
\n `;class Wn{constructor(t){this.art=t;const{option:e,constructor:r}=t;e.container instanceof Element?this.$container=e.container:(this.$container=F(e.container),it(this.$container,`No container element found by ${e.container}`)),it(tt(),"The current browser does not support flex layout");const n=this.$container.tagName.toLowerCase();it("div"===n,`Unsupported container element type, only support 'div' but got '${n}'`),it(r.instances.every(t=>t.template.$container!==this.$container),"Cannot mount multiple instances on the same dom element"),this.query=this.query.bind(this),function(t,e,r){const n=x.get(e);if(n&&n!==t)throw new Error("Cannot mount multiple instances on the same dom element");const o=k(t);o.rollback=r,x.set(e,t),o.releaseContainer=()=>{x.get(e)===t&&x.delete(e)}}(t,this.$container,yn(this.$container)),this.$container.dataset.artId=String(t.id),this.init()}static get html(){return _n}query(t){return F(t,this.$container)}init(){const{option:t}=this.art;var e;if(t.useSSR||(this.$container.innerHTML=Wn.html),(e=this).$player=e.query(".art-video-player"),e.$video=e.query(".art-video"),e.$track=e.query("track"),e.$poster=e.query(".art-poster"),e.$subtitle=e.query(".art-subtitle"),e.$danmuku=e.query(".art-danmuku"),e.$bottom=e.query(".art-bottom"),e.$progress=e.query(".art-progress"),e.$controls=e.query(".art-controls"),e.$controlsLeft=e.query(".art-controls-left"),e.$controlsCenter=e.query(".art-controls-center"),e.$controlsRight=e.query(".art-controls-right"),e.$layer=e.query(".art-layers"),e.$loading=e.query(".art-loading"),e.$notice=e.query(".art-notice"),e.$noticeInner=e.query(".art-notice-inner"),e.$mask=e.query(".art-mask"),e.$state=e.query(".art-state"),e.$setting=e.query(".art-settings"),e.$info=e.query(".art-info"),e.$infoPanel=e.query(".art-info-panel"),e.$infoClose=e.query(".art-info-close"),e.$contextmenu=e.query(".art-contextmenus"),t.proxy){const e=t.proxy.call(this.art,this.art);!function(t){it(t instanceof HTMLVideoElement||t instanceof HTMLCanvasElement,"Function 'option.proxy' needs to return 'HTMLVideoElement' or 'HTMLCanvasElement'")}(e),Z(e,this.$video),e.className="art-video",this.$video=e}t.backdrop&&V(this.$player,"art-backdrop"),N&&V(this.$player,"art-mobile")}destroy(t){t?this.$container.innerHTML="":V(this.$player,"art-destroy")}}const Dn=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Fn{on(t,e,r){const n=this.e||(this.e={});let o=Dn(n,t)?n[t]:void 0;return o||(o=[],Object.defineProperty(n,t,{value:o,enumerable:!0,configurable:!0,writable:!0})),o.push({fn:e,ctx:r}),this}once(t,e,r){const n=this,o=e;let i=!1;function a(...e){i||(i=!0,n.off(t,a),o.apply(r,e))}return a._=e,this.on(t,a,r)}emit(t,...e){const r=this.e||(this.e={}),n=(Dn(r,t)&&r[t]||[]).slice();for(const o of n)o.fn.apply(o.ctx,e);return this}off(t,e){const r=this.e||(this.e={}),n=Dn(r,t)?r[t]:void 0,o=[];if(n&&e)for(let i=0,a=n.length;i{e.destroying||e.finalizers.dispose()})}(this);try{if(this.template=new Wn(this),this.events=new ve(this),this.storage=new Pn(this),this.icons=new Te(this),this.i18n=new $e(this),this.notice=new Oe(this),this.player=new Cr(this),this.layers=new Se(this),this.controls=new se(this),this.contextmenu=new Wt(this),this.subtitle=new Nn(this),this.info=new Le(this),this.loading=new Pe(this),this.hotkey=new xe(this),this.mask=new Me(this),this.setting=new Sn(this),this.plugins=new Dr(this),$(this).closed)return;if("function"===typeof e&&this.on("ready",()=>e.call(this,this)),Bn.DEBUG){const t=t=>console.log(`[ART.${this.id}] -> ${t}`);t(`Version@${Bn.version}`);for(let e=0;et(`Event@${e.type}`))}(function(t){const e=k(t);return e.rollback=void 0,!e.scope.closed})(this)&&Yn.push(this)}catch(r){try{T(this,Yn,!0,Bn.REMOVE_SRC_WHEN_DESTROY,!0)}catch(n){console.warn("Failed to clean up ArtPlayer initialization:",n)}throw r}}static get instances(){return Yn}static get version(){return g}static get config(){return v}static get utils(){return Et}static get scheme(){return It}static get Emitter(){return Fn}static get validator(){return m}static get kindOf(){return m.kindOf}static get html(){return Wn.html}static get option(){return{id:"",container:"#artplayer",url:"",poster:"",type:"",theme:"#f00",volume:.7,isLive:!1,muted:!1,autoplay:!1,autoSize:!1,autoMini:!1,loop:!1,flip:!1,playbackRate:!1,aspectRatio:!1,screenshot:!1,setting:!1,hotkey:!0,pip:!1,mutex:!0,backdrop:!0,fullscreen:!1,fullscreenWeb:!1,subtitleOffset:!1,miniProgressBar:!1,useSSR:!1,playsInline:!0,lock:!1,gesture:!0,fastForward:!1,autoPlayback:!1,autoOrientation:!1,airplay:!1,proxy:void 0,layers:[],contextmenu:[],controls:[],settings:[],quality:[],highlight:[],plugins:[],thumbnails:{url:"",number:60,column:10,width:0,height:0,scale:1},subtitle:{url:"",type:"",style:{},name:"",escape:!0,encoding:"utf-8",onVttLoad:t=>t},moreVideoAttr:{controls:!1,preload:O?"auto":"metadata"},i18n:{},icons:{},cssVar:{},customType:{},lang:null==navigator?void 0:navigator.language.toLowerCase()}}get proxy(){return this.events.proxy}get query(){return this.template.query}get video(){return this.template.$video}reset(){this.video.removeAttribute("src"),this.video.load()}destroy(t=!0){T(this,Yn,t,Bn.REMOVE_SRC_WHEN_DESTROY)}}return Bn.STYLE=Mn,Bn.DEBUG=!1,Bn.CONTEXTMENU=!0,Bn.NOTICE_TIME=2e3,Bn.SETTING_WIDTH=250,Bn.SETTING_ITEM_WIDTH=200,Bn.SETTING_ITEM_HEIGHT=35,Bn.RESIZE_TIME=200,Bn.SCROLL_TIME=200,Bn.SCROLL_GAP=50,Bn.AUTO_PLAYBACK_MAX=10,Bn.AUTO_PLAYBACK_MIN=5,Bn.AUTO_PLAYBACK_TIMEOUT=3e3,Bn.RECONNECT_TIME_MAX=5,Bn.RECONNECT_SLEEP_TIME=1e3,Bn.CONTROL_HIDE_TIME=3e3,Bn.DBCLICK_TIME=300,Bn.DBCLICK_FULLSCREEN=!0,Bn.MOBILE_DBCLICK_PLAY=!0,Bn.MOBILE_CLICK_PLAY=!1,Bn.AUTO_ORIENTATION_TIME=200,Bn.INFO_LOOP_TIME=1e3,Bn.FAST_FORWARD_VALUE=3,Bn.FAST_FORWARD_TIME=1e3,Bn.TOUCH_MOVE_RATIO=.5,Bn.VOLUME_STEP=.1,Bn.SEEK_STEP=5,Bn.PLAYBACK_RATE=[.5,.75,1,1.25,1.5,2],Bn.ASPECT_RATIO=["default","4:3","16:9"],Bn.FLIP=["normal","horizontal","vertical"],Bn.FULLSCREEN_WEB_IN_BODY=!0,Bn.LOG_VERSION=!0,Bn.USE_RAF=!1,Bn.REMOVE_SRC_WHEN_DESTROY=!0,_&&(window.Artplayer=Bn,D("artplayer-style",Mn),setTimeout(()=>{Bn.LOG_VERSION&&console.log(`%c ArtPlayer %c ${Bn.version} %c https://artplayer.org`,"color: #fff; background: #5f5f5f","color: #fff; background: #4bc729","")},100)),Bn}); diff --git a/packages/artplayer/dist/artplayer.mjs b/packages/artplayer/dist/artplayer.mjs index bd4940049..3a9f59cd8 100644 --- a/packages/artplayer/dist/artplayer.mjs +++ b/packages/artplayer/dist/artplayer.mjs @@ -496,6 +496,132 @@ const isIOS = /iPad|iPhone|iPod/i.test(userAgent) && !window.MSStream; const isIOS13 = isIOS || userAgent.includes("Macintosh") && navigator.maxTouchPoints >= 1; const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || isIOS13; const isBrowser = typeof window !== "undefined" && typeof document !== "undefined"; +function requestImage(url, scale, owner) { + return new Promise((resolve, reject) => { + const request = owner ? owner.child() : new ResourceScope(); + let complete = false; + let releaseBlob = () => { + }; + function fail(error2) { + if (complete) + return; + complete = true; + try { + request.dispose(); + } catch (cleanupError) { + console.warn("Additional image cleanup failure:", cleanupError); + } + try { + releaseBlob(); + } catch (cleanupError) { + console.warn("Additional image cleanup failure:", cleanupError); + } + reject(error2); + } + function finish2(image) { + if (complete || request.closed) + return; + complete = true; + try { + request.dispose(); + resolve(image); + } catch (error2) { + try { + releaseBlob(); + } finally { + reject(error2); + } + } + } + request.add(() => { + if (!complete) { + complete = true; + try { + releaseBlob(); + } finally { + resolve(void 0); + } + } + }); + if (request.closed) + return; + function watch(image, loaded) { + image.onload = () => { + if (!complete && !request.closed) { + try { + loaded(); + } catch (error2) { + fail(error2); + } + } + }; + image.onerror = () => fail(new Error(`Image load failed: ${url}`)); + request.add(() => { + image.onload = null; + image.onerror = null; + if (!complete) + image.removeAttribute("src"); + }); + } + try { + const image = new Image(); + watch(image, () => { + if (!scale || scale === 1) { + finish2(image); + return; + } + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + canvas.width = image.width * scale; + canvas.height = image.height * scale; + if (!context) + throw new TypeError("Canvas 2D context is unavailable"); + if (complete || request.closed) + return; + context.drawImage(image, 0, 0, canvas.width, canvas.height); + if (complete || request.closed) + return; + canvas.toBlob((blob) => { + if (complete || request.closed) + return; + try { + if (!blob) + throw new Error("Unable to encode thumbnail image"); + const blobUrl = URL.createObjectURL(blob); + let revoked = false; + const revoke = () => { + if (!revoked) { + revoked = true; + URL.revokeObjectURL(blobUrl); + } + }; + releaseBlob = owner ? owner.add(revoke) : revoke; + if (complete || request.closed) { + releaseBlob(); + return; + } + const scaled = new Image(); + watch(scaled, () => finish2(scaled)); + if (!request.closed) + scaled.src = blobUrl; + } catch (error2) { + fail(error2); + } + }); + }); + if (!request.closed) + image.src = url; + } catch (error2) { + fail(error2); + } + }); +} +function loadImg(url, scale) { + return requestImage(url, scale, void 0); +} +function loadThumbnailImage(url, scale, owner) { + return requestImage(url, scale, owner); +} function setStyleText(id2, style) { let $style = document.getElementById(id2); if (!$style) { @@ -598,38 +724,6 @@ function supportsFlex() { function getRect(el) { return el.getBoundingClientRect(); } -function loadImg(url, scale) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = function() { - if (!scale || scale === 1) { - resolve(img); - } else { - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - canvas.width = img.width * scale; - canvas.height = img.height * scale; - ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - canvas.toBlob((blob) => { - const blobUrl = URL.createObjectURL(blob); - const scaledImg = new Image(); - scaledImg.onload = function() { - resolve(scaledImg); - }; - scaledImg.onerror = function() { - URL.revokeObjectURL(blobUrl); - reject(new Error(`Image load failed: ${url}`)); - }; - scaledImg.src = blobUrl; - }); - } - }; - img.onerror = function() { - reject(new Error(`Image load failed: ${url}`)); - }; - img.src = url; - }); -} function getComposedPath(event) { if (event.composedPath) return event.composedPath(); @@ -1619,6 +1713,75 @@ function playAndPause(option) { } }); } +const current = /* @__PURE__ */ new WeakMap(); +const assignments = /* @__PURE__ */ new WeakMap(); +const sources = /* @__PURE__ */ new WeakMap(); +function getSourceScope(owner) { + return sources.get(owner) || getScope(owner); +} +function captureSource(owner) { + const operation = current.get(owner); + const source = sources.get(owner); + return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); +} +function beginSource(owner) { + const previous = sources.get(owner); + const source = getScope(owner).child(); + const scope = source.child(); + sources.set(owner, source); + source.add(() => { + if (sources.get(owner) === source) + sources.delete(owner); + }); + const operation = { + scope, + assigned: false, + acceptingEvents: false, + active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation + }; + current.set(owner, operation); + scope.add(() => { + if (current.get(owner) === operation) + current.delete(owner); + operation.onAssigned = void 0; + operation.onError = void 0; + }); + previous?.dispose(); + return operation; +} +function takeAssignment(owner) { + const operation = assignments.get(owner); + assignments.delete(owner); + return operation || beginSource(owner); +} +function finishAssignment(operation) { + operation.assigned = true; + const callback = operation.onAssigned; + operation.onAssigned = void 0; + if (operation.active()) + callback?.(); +} +function assignUrl(owner, operation, url) { + assignments.set(owner, operation); + operation.acceptingEvents = true; + try { + owner.url = url; + } finally { + if (assignments.get(owner) === operation) { + assignments.delete(owner); + finishAssignment(operation); + } + } +} +function failSource(operation, error2) { + if (!operation.active()) + return; + if (operation.onError) + operation.onError(error2); + else + console.warn("Failed to initialize ArtPlayer source:", error2); + operation.scope.dispose(); +} function getPosFromEvent(art, event) { const { $progress } = art.template; const { left } = getRect($progress); @@ -1630,14 +1793,20 @@ function getPosFromEvent(art, event) { return { second, time: time2, width, percentage }; } function setCurrentTime(art, event, active2 = () => true) { + if (!active2()) + return; if (art.isRotate) { const percentage = (event.touches[0].clientY - art.top) / art.height; const second = percentage * art.duration; + if (!active2()) + return; art.emit("setBar", "played", percentage, event); if (active2()) art.seek = second; } else { const { second, percentage } = getPosFromEvent(art, event); + if (!active2()) + return; art.emit("setBar", "played", percentage, event); if (active2()) art.seek = second; @@ -1647,34 +1816,51 @@ function installProgressInteractions(art, $control) { const { $progress } = art.template; const $indicator = $control.querySelector(".art-progress-indicator"); const { on, proxy } = controlEvents(art, $control); + const scope = entryScope($control); + let action = 0; + const capture = () => { + const sourceActive = captureSource(art); + return () => !scope.closed && !isClosing(art) && sourceActive(); + }; + const captureAction = () => { + const revision = ++action; + const active2 = capture(); + return () => revision === action && active2(); + }; if (!isMobile) { - let isDragging = false; + let dragging; proxy($progress, "click", (event) => { if (event.target !== $indicator) { - setCurrentTime(art, event); + setCurrentTime(art, event, captureAction()); } }); proxy($progress, "mousemove", (event) => { + const active2 = capture(); const { percentage } = getPosFromEvent(art, event); - art.emit("setBar", "hover", percentage, event); + if (active2()) + art.emit("setBar", "hover", percentage, event); }); proxy($progress, "mouseleave", (event) => { art.emit("setBar", "hover", 0, event); }); proxy($progress, "mousedown", (event) => { - isDragging = event.button === 0; + dragging = event.button === 0 ? captureAction() : void 0; }); on("document:mousemove", (event) => { - if (isDragging) { + const active2 = dragging; + if (active2?.()) { const { second, percentage } = getPosFromEvent(art, event); + if (!active2() || dragging !== active2) + return; art.emit("setBar", "played", percentage, event); - art.seek = second; + if (active2() && dragging === active2) + art.seek = second; + } else { + dragging = void 0; } }); on("document:mouseup", () => { - if (isDragging) { - isDragging = false; - } + dragging = void 0; }); } } @@ -1814,7 +2000,7 @@ function screenshot$1(option) { const { icons } = art; appendElement($control, icons.screenshot); proxy($control, "click", () => { - art.screenshot(); + silencePromise(art.screenshot()); }); } }); @@ -2278,75 +2464,6 @@ function clickInit(art, events) { } }); } -const current = /* @__PURE__ */ new WeakMap(); -const assignments = /* @__PURE__ */ new WeakMap(); -const sources = /* @__PURE__ */ new WeakMap(); -function getSourceScope(owner) { - return sources.get(owner) || getScope(owner); -} -function captureSource(owner) { - const operation = current.get(owner); - const source = sources.get(owner); - return () => current.get(owner) === operation && (!operation || operation.active()) && sources.get(owner) === source && (!source || !source.closed); -} -function beginSource(owner) { - const previous = sources.get(owner); - const source = getScope(owner).child(); - const scope = source.child(); - sources.set(owner, source); - source.add(() => { - if (sources.get(owner) === source) - sources.delete(owner); - }); - const operation = { - scope, - assigned: false, - acceptingEvents: false, - active: () => !isClosing(owner) && !scope.closed && current.get(owner) === operation - }; - current.set(owner, operation); - scope.add(() => { - if (current.get(owner) === operation) - current.delete(owner); - operation.onAssigned = void 0; - operation.onError = void 0; - }); - previous?.dispose(); - return operation; -} -function takeAssignment(owner) { - const operation = assignments.get(owner); - assignments.delete(owner); - return operation || beginSource(owner); -} -function finishAssignment(operation) { - operation.assigned = true; - const callback = operation.onAssigned; - operation.onAssigned = void 0; - if (operation.active()) - callback?.(); -} -function assignUrl(owner, operation, url) { - assignments.set(owner, operation); - operation.acceptingEvents = true; - try { - owner.url = url; - } finally { - if (assignments.get(owner) === operation) { - assignments.delete(owner); - finishAssignment(operation); - } - } -} -function failSource(operation, error2) { - if (!operation.active()) - return; - if (operation.onError) - operation.onError(error2); - else - console.warn("Failed to initialize ArtPlayer source:", error2); - operation.scope.dispose(); -} function slideDirection(startX, startY, endX, endY) { const dy = startY - endY; const dx = endX - startX; @@ -3473,6 +3590,13 @@ function cssVarMix(art) { } }); } +const revisions = /* @__PURE__ */ new WeakMap(); +function positionRevision(art) { + return revisions.get(art) || 0; +} +function advancePosition(art) { + revisions.set(art, positionRevision(art) + 1); +} function currentTimeMix(art) { const { $video } = art.template; def(art, "currentTime", { @@ -3481,6 +3605,7 @@ function currentTimeMix(art) { const parsed = Number.parseFloat(time2); if (Number.isNaN(parsed)) return; + advancePosition(art); $video.currentTime = clamp(parsed, 0, art.duration); } }); @@ -4939,46 +5064,66 @@ function rectMix(art) { } }); } +function drawFrame(canvas, video) { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const context = canvas.getContext("2d"); + if (!context) + throw new TypeError("Canvas 2D context is unavailable"); + context.drawImage(video, 0, 0); +} +function captureBlobUrl(canvas, resolve, reject) { + canvas.toBlob((blob) => { + try { + if (!blob) + throw new Error("Unable to encode screenshot blob"); + resolve(URL.createObjectURL(blob)); + } catch (error2) { + reject(error2); + } + }); +} function screenshotMix(art) { - const { - notice, - template: { $video } - } = art; - const $canvas = createElement("canvas"); - def(art, "getDataURL", { - value: () => new Promise((resolve, reject) => { + const { notice, template: { $video } } = art; + const canvas = document.createElement("canvas"); + function capture(blob) { + const active2 = captureSource(art); + return new Promise((resolve, reject) => { + const fail = (error2) => { + try { + if (!isClosing(art) && active2()) + notice.show = error2; + } catch (noticeError) { + reject(noticeError); + return; + } + reject(error2); + }; try { - $canvas.width = $video.videoWidth; - $canvas.height = $video.videoHeight; - $canvas.getContext("2d").drawImage($video, 0, 0); - resolve($canvas.toDataURL("image/png")); - } catch (err) { - notice.show = err; - reject(err); + drawFrame(canvas, $video); + if (blob) { + captureBlobUrl(canvas, resolve, fail); + } else { + resolve(canvas.toDataURL("image/png")); + } + } catch (error2) { + fail(error2); } - }) - }); - def(art, "getBlobUrl", { - value: () => new Promise((resolve, reject) => { - try { - $canvas.width = $video.videoWidth; - $canvas.height = $video.videoHeight; - $canvas.getContext("2d").drawImage($video, 0, 0); - $canvas.toBlob((blob) => { - resolve(URL.createObjectURL(blob)); - }); - } catch (err) { - notice.show = err; - reject(err); - } - }) - }); + }); + } + def(art, "getDataURL", { value: () => capture(false) }); + def(art, "getBlobUrl", { value: () => capture(true) }); def(art, "screenshot", { value: async (name) => { + const active2 = captureSource(art); const dataUri = await art.getDataURL(); - const fileName = name || `artplayer_${secondToTime($video.currentTime)}`; - download(dataUri, `${fileName}.png`); - art.emit("screenshot", dataUri); + if (!isClosing(art) && active2()) { + const fileName = name || `artplayer_${secondToTime($video.currentTime)}`; + if (!isClosing(art) && active2()) + download(dataUri, `${fileName}.png`); + if (!isClosing(art) && active2()) + art.emit("screenshot", dataUri); + } return dataUri; } }); @@ -5061,6 +5206,48 @@ function listenSource(scope, art, name, callback, once = true) { }); return guarded; } +const POSITION_TOLERANCE = 0.05; +function positionRestoration(art, target, active2) { + let expected; + let observedSeek = false; + let corrected = false; + let manual = false; + let revision = positionRevision(art); + const manualPosition = () => manual || positionRevision(art) !== revision; + const seeking = () => !!art.template?.$video?.seeking; + return { + restore() { + if (!active2() || manualPosition()) + return; + const previousRevision = positionRevision(art); + art.currentTime = target; + revision = positionRevision(art); + if (revision > previousRevision + 1) + manual = true; + if (!active2()) + return; + expected = art.currentTime; + if (!active2() || manualPosition()) + return; + observedSeek = seeking(); + }, + manual() { + manual = true; + }, + ready() { + if (!active2() || seeking()) + return false; + const missed = expected !== void 0 && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE; + if (!manualPosition() && observedSeek && !corrected && expected !== void 0 && missed) { + corrected = true; + if (!active2()) + return false; + art.currentTime = expected; + } + return active2() && !seeking(); + } + }; +} function switchSource(art, url, currentTime) { return new Promise((resolve, reject) => { if (isClosing(art) || url === art.url) { @@ -5096,41 +5283,63 @@ function switchSource(art, url, currentTime) { if (!active2()) return; const readiness = scope.child(); + let canPlay = false; + let resuming = false; + let rateRestored = false; + const position = positionRestoration(art, currentTime, active2); + const resume = async () => { + art.aspectRatio = aspectRatio2; + if (!active2()) + return; + if (playing) { + try { + await art.play(); + } catch { + } + } + if (!active2()) + return; + art.notice.show = ""; + settle(); + }; + const resumeWhenReady = () => { + if (!active2() || resuming || !canPlay) + return; + try { + if (art.template?.$video?.seeking) + return; + if (!active2()) + return; + if (!rateRestored) { + rateRestored = true; + art.playbackRate = playbackRate2; + } + if (!position.ready() || !active2() || resuming) + return; + resuming = true; + readiness.dispose(); + void resume().catch(fail); + } catch (error2) { + fail(error2); + } + }; const handlers = { "video:error": fail, "video:loadedmetadata": () => { if (!active2()) return; try { - art.currentTime = currentTime; + position.restore(); } catch (error2) { fail(error2); } }, "video:canplay": () => { - if (!active2()) - return; - readiness.dispose(); - const resume = async () => { - art.playbackRate = playbackRate2; - if (!active2()) - return; - art.aspectRatio = aspectRatio2; - if (!active2()) - return; - if (playing) { - try { - await art.play(); - } catch { - } - } - if (!active2()) - return; - art.notice.show = ""; - settle(); - }; - void resume().catch(fail); - } + canPlay = true; + resumeWhenReady(); + }, + "video:seeked": resumeWhenReady, + "seek": position.manual }; const capture = scope.child(); const queued = []; @@ -5155,7 +5364,7 @@ function switchSource(art, url, currentTime) { } const dispatch = {}; for (const name of names) - dispatch[name] = listenSource(readiness, art, name, handlers[name]); + dispatch[name] = listenSource(readiness, art, name, handlers[name], name !== "video:seeked"); for (const [name, event] of queued) { if (!active2() || readiness.closed) break; @@ -5188,69 +5397,106 @@ function themeMix(art) { } }); } +function thumbnailLayout(option, geometry) { + const { number, column, width, height, scale } = option; + const { imageWidth, videoWidth, videoHeight, progressWidth, position } = geometry; + const columns = Number(column); + const previewWidth = Number(width) * Number(scale) || imageWidth / columns; + const previewHeight = Number(height) * Number(scale) || previewWidth / (videoWidth / videoHeight); + const index = Math.floor(position / (progressWidth / Number(number))); + const row = Math.floor(index / columns); + const cell = index % columns; + const left = position <= previewWidth / 2 ? 0 : position > progressWidth - previewWidth / 2 ? `${progressWidth - previewWidth}px` : `${position - previewWidth / 2}px`; + return { + height: `${previewHeight}px`, + width: `${previewWidth}px`, + backgroundPosition: `-${cell * previewWidth}px -${row * previewHeight}px`, + left + }; +} function thumbnailsMix(art) { - const { - option, - template: { $progress, $video } - } = art; - let timer = null; - let loding = false; - let image = null; + const { option, template: { $progress, $video } } = art; + let scope = getScope(art).child(); + let image; + let loading2 = false; + let control; + let hover; function reset() { - clearTimeout(timer); - timer = null; - loding = false; - image = null; + const previous = scope; + scope = getScope(art).child(); + image = void 0; + loading2 = false; + hover = void 0; + previous.dispose(); } - function showThumbnails(posWidth) { - const $thumbnails = art.controls?.thumbnails; - if (!$thumbnails) + function render() { + const current2 = hover; + const currentScope = scope; + if (!current2 || !image) return; - const { number, column, width, height, scale } = option.thumbnails; - const width2 = width * scale || image.naturalWidth / column; - const height2 = height * scale || width2 / ($video.videoWidth / $video.videoHeight); - const perWidth = $progress.clientWidth / number; - const perIndex = Math.floor(posWidth / perWidth); - const yIndex = Math.ceil(perIndex / column) - 1; - const xIndex = perIndex % column || column - 1; - setStyle($thumbnails, "backgroundImage", `url(${image.src})`); - setStyle($thumbnails, "height", `${height2}px`); - setStyle($thumbnails, "width", `${width2}px`); - setStyle($thumbnails, "backgroundPosition", `-${xIndex * width2}px -${yIndex * height2}px`); - if (posWidth <= width2 / 2) { - setStyle($thumbnails, "left", 0); - } else if (posWidth > $progress.clientWidth - width2 / 2) { - setStyle($thumbnails, "left", `${$progress.clientWidth - width2}px`); - } else { - setStyle($thumbnails, "left", `${posWidth - width2 / 2}px`); + const active2 = () => !isClosing(art) && !currentScope.closed && scope === currentScope && hover === current2 && current2.sourceActive() && art.controls?.thumbnails === current2.element; + if (!active2()) + return; + const position = $progress.clientWidth * current2.percentage; + if (!(position > 0 && position < $progress.clientWidth)) + return; + const styles = { + backgroundImage: `url(${image.src})`, + ...thumbnailLayout(option.thumbnails, { + imageWidth: image.naturalWidth, + videoWidth: $video.videoWidth, + videoHeight: $video.videoHeight, + progressWidth: $progress.clientWidth, + position + }) + }; + for (const [key, value] of Object.entries(styles)) { + if (!active2()) + return; + setStyle(current2.element, key, value); } } - art.on("setBar", async (type, percentage, event) => { - const $thumbnails = art.controls?.thumbnails; + eventSubscriptions(art)("setBar", (type, percentage, event) => { + const element = art.controls?.thumbnails; const { url, scale } = option.thumbnails; - if (!$thumbnails || !url) + if (isClosing(art) || !element || !url || !(type === "hover" || type === "played" && event && isMobile)) return; - const isMobileDragging = type === "played" && event && isMobile; - if (type === "hover" || isMobileDragging) { - if (!image && !loding) { - loding = true; - image = await loadImg(url, scale); - loding = false; - } - if (!image) + if (control !== element) { + const elementScope = entryScope(element); + if (elementScope.closed) return; - const width = $progress.clientWidth * percentage; - if (width > 0 && width < $progress.clientWidth) { - showThumbnails(width); - } + control = element; + elementScope.add(() => { + if (control === element) { + control = void 0; + reset(); + } + }); + } + hover = { percentage, element, sourceActive: captureSource(art) }; + if (image) { + render(); + } else if (!loading2) { + const currentScope = scope; + loading2 = true; + loadThumbnailImage(url, scale, currentScope).then((loaded) => { + if (scope !== currentScope || currentScope.closed) + return; + loading2 = false; + image = loaded; + render(); + }).catch((error2) => { + if (scope === currentScope && !currentScope.closed) { + loading2 = false; + console.warn("ArtPlayer thumbnail load failed:", error2); + } + }); } }); def(art, "thumbnails", { - get() { - return art.option.thumbnails; - }, - set(thumbnails) { - if (thumbnails.url && !art.option.isLive) { + get: () => art.option.thumbnails, + set: (thumbnails) => { + if (!isClosing(art) && thumbnails.url && !art.option.isLive && !isClosing(art)) { art.option.thumbnails = thumbnails; reset(); } @@ -5319,8 +5565,6 @@ function urlMix(art) { const result = typeCallback.call(art, $video, newUrl, art); void Promise.resolve(result).catch((error2) => failSource(operation, error2)); } else { - if (oldUrl) - URL.revokeObjectURL(oldUrl); if (!operation.active()) return; $video.src = newUrl; diff --git a/packages/artplayer/src/capture/frame.ts b/packages/artplayer/src/capture/frame.ts new file mode 100644 index 000000000..ea53d957f --- /dev/null +++ b/packages/artplayer/src/capture/frame.ts @@ -0,0 +1,28 @@ +export type CaptureMedia = CanvasImageSource & { + videoWidth: number + videoHeight: number + currentTime: number +} + +export function drawFrame(canvas: HTMLCanvasElement, video: CaptureMedia): void { + canvas.width = video.videoWidth + canvas.height = video.videoHeight + const context = canvas.getContext('2d') + if (!context) + throw new TypeError('Canvas 2D context is unavailable') + context.drawImage(video, 0, 0) +} + +export function captureBlobUrl(canvas: HTMLCanvasElement, resolve: (url: string) => void, reject: (error: unknown) => void): void { + canvas.toBlob((blob) => { + try { + if (!blob) + throw new Error('Unable to encode screenshot blob') + // The public getBlobUrl caller owns this URL, including after destroy. + resolve(URL.createObjectURL(blob)) + } + catch (error) { + reject(error) + } + }) +} diff --git a/packages/artplayer/src/control/progress/interactions.ts b/packages/artplayer/src/control/progress/interactions.ts index 161f032eb..b13e9b046 100644 --- a/packages/artplayer/src/control/progress/interactions.ts +++ b/packages/artplayer/src/control/progress/interactions.ts @@ -1,4 +1,7 @@ import type { ControlHost } from '../types' +import { entryScope } from '../../component/resources' +import { isClosing } from '../../lifecycle/instance' +import { captureSource } from '../../source/operation' import { isMobile } from '../../utils' import { controlEvents } from '../resources' import { getPosFromEvent, setCurrentTime } from './position' @@ -7,17 +10,30 @@ export function installProgressInteractions(art: ControlHost, $control: HTMLDivE const { $progress } = art.template const $indicator = $control.querySelector('.art-progress-indicator') const { on, proxy } = controlEvents(art, $control) + const scope = entryScope($control) + let action = 0 + const capture = () => { + const sourceActive = captureSource(art) + return () => !scope.closed && !isClosing(art) && sourceActive() + } + const captureAction = () => { + const revision = ++action + const active = capture() + return () => revision === action && active() + } if (!isMobile) { - let isDragging = false + let dragging: (() => boolean) | undefined proxy($progress, 'click', (event) => { if (event.target !== $indicator) { - setCurrentTime(art, event) + setCurrentTime(art, event, captureAction()) } }) proxy($progress, 'mousemove', (event) => { + const active = capture() const { percentage } = getPosFromEvent(art, event) - art.emit('setBar', 'hover', percentage, event) + if (active()) + art.emit('setBar', 'hover', percentage, event) }) proxy($progress, 'mouseleave', (event) => { @@ -25,21 +41,26 @@ export function installProgressInteractions(art: ControlHost, $control: HTMLDivE }) proxy($progress, 'mousedown', (event) => { - isDragging = event.button === 0 + dragging = event.button === 0 ? captureAction() : undefined }) on('document:mousemove', (event) => { - if (isDragging) { + const active = dragging + if (active?.()) { const { second, percentage } = getPosFromEvent(art, event) + if (!active() || dragging !== active) + return art.emit('setBar', 'played', percentage, event) - art.seek = second + if (active() && dragging === active) + art.seek = second + } + else { + dragging = undefined } }) on('document:mouseup', () => { - if (isDragging) { - isDragging = false - } + dragging = undefined }) } } diff --git a/packages/artplayer/src/control/progress/position.ts b/packages/artplayer/src/control/progress/position.ts index 8bc31deca..814ac53fe 100644 --- a/packages/artplayer/src/control/progress/position.ts +++ b/packages/artplayer/src/control/progress/position.ts @@ -23,15 +23,21 @@ export function getPosFromEvent(art: ProgressPositionHost, event: ProgressEvent) } export function setCurrentTime(art: ProgressPositionHost, event: ProgressEvent, active: () => boolean = () => true) { + if (!active()) + return if (art.isRotate) { const percentage = ((event as TouchEvent).touches[0]!.clientY - art.top) / art.height const second = percentage * art.duration + if (!active()) + return art.emit('setBar', 'played', percentage, event) if (active()) art.seek = second } else { const { second, percentage } = getPosFromEvent(art, event) + if (!active()) + return art.emit('setBar', 'played', percentage, event) if (active()) art.seek = second diff --git a/packages/artplayer/src/control/screenshot.ts b/packages/artplayer/src/control/screenshot.ts index 0c9d99f5c..04bfb7f52 100644 --- a/packages/artplayer/src/control/screenshot.ts +++ b/packages/artplayer/src/control/screenshot.ts @@ -1,5 +1,6 @@ import type { ControlFactory, ControlOption } from './types' import { appendElement } from '../component/dom' +import { silencePromise } from '../utils' import { controlEvents } from './resources' export default function screenshot(option: ControlOption): ControlFactory { @@ -12,7 +13,7 @@ export default function screenshot(option: ControlOption): ControlFactory { appendElement($control, icons.screenshot) proxy($control, 'click', () => { - art.screenshot() + silencePromise(art.screenshot()) }) }, }) diff --git a/packages/artplayer/src/image/load.ts b/packages/artplayer/src/image/load.ts new file mode 100644 index 000000000..1b5d14300 --- /dev/null +++ b/packages/artplayer/src/image/load.ts @@ -0,0 +1,146 @@ +import ResourceScope from '../lifecycle/scope' + +function requestImage(url: string, scale: number | undefined, owner: undefined): Promise +function requestImage(url: string, scale: number | undefined, owner: ResourceScope): Promise +function requestImage(url: string, scale: number | undefined, owner: ResourceScope | undefined): Promise { + return new Promise((resolve, reject) => { + const request = owner ? owner.child() : new ResourceScope() + let complete = false + let releaseBlob = () => {} + + function fail(error: unknown): void { + if (complete) + return + complete = true + try { + request.dispose() + } + catch (cleanupError) { + console.warn('Additional image cleanup failure:', cleanupError) + } + try { + releaseBlob() + } + catch (cleanupError) { + console.warn('Additional image cleanup failure:', cleanupError) + } + reject(error) + } + + function finish(image: HTMLImageElement): void { + if (complete || request.closed) + return + complete = true + try { + request.dispose() + resolve(image) + } + catch (error) { + try { + releaseBlob() + } + finally { + reject(error) + } + } + } + + request.add(() => { + if (!complete) { + complete = true + try { + releaseBlob() + } + finally { + resolve(undefined) + } + } + }) + if (request.closed) + return + + function watch(image: HTMLImageElement, loaded: () => void): void { + image.onload = () => { + if (!complete && !request.closed) { + try { + loaded() + } + catch (error) { + fail(error) + } + } + } + image.onerror = () => fail(new Error(`Image load failed: ${url}`)) + request.add(() => { + image.onload = null + image.onerror = null + if (!complete) + image.removeAttribute('src') + }) + } + + try { + const image = new Image() + watch(image, () => { + if (!scale || scale === 1) { + finish(image) + return + } + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + canvas.width = image.width * scale + canvas.height = image.height * scale + if (!context) + throw new TypeError('Canvas 2D context is unavailable') + if (complete || request.closed) + return + context.drawImage(image, 0, 0, canvas.width, canvas.height) + if (complete || request.closed) + return + canvas.toBlob((blob) => { + if (complete || request.closed) + return + try { + if (!blob) + throw new Error('Unable to encode thumbnail image') + const blobUrl = URL.createObjectURL(blob) + let revoked = false + const revoke = (): undefined => { + if (!revoked) { + revoked = true + URL.revokeObjectURL(blobUrl) + } + } + releaseBlob = owner ? owner.add(revoke) : revoke + if (complete || request.closed) { + releaseBlob() + return + } + const scaled = new Image() + watch(scaled, () => finish(scaled)) + if (!request.closed) + scaled.src = blobUrl + } + catch (error) { + fail(error) + } + }) + }) + if (!request.closed) + image.src = url + } + catch (error) { + fail(error) + } + }) +} + +// Public callers own a scaled result's image.src object URL. +export function loadImg(url: string, scale?: number): Promise { + return requestImage(url, scale, undefined) +} + +// Internal previews own their result until configuration replacement or destroy. +export function loadThumbnailImage(url: string, scale: number | undefined, owner: ResourceScope): Promise { + return requestImage(url, scale, owner) +} diff --git a/packages/artplayer/src/media/position-revision.ts b/packages/artplayer/src/media/position-revision.ts new file mode 100644 index 000000000..58084685a --- /dev/null +++ b/packages/artplayer/src/media/position-revision.ts @@ -0,0 +1,9 @@ +const revisions = new WeakMap() + +export function positionRevision(art: object): number { + return revisions.get(art) || 0 +} + +export function advancePosition(art: object): void { + revisions.set(art, positionRevision(art) + 1) +} diff --git a/packages/artplayer/src/player/currentTimeMix.ts b/packages/artplayer/src/player/currentTimeMix.ts index d3caeb11e..261298916 100644 --- a/packages/artplayer/src/player/currentTimeMix.ts +++ b/packages/artplayer/src/player/currentTimeMix.ts @@ -1,5 +1,6 @@ import type { MediaHost } from '../media/hosts' import type { Position } from '../media/playback' +import { advancePosition } from '../media/position-revision' import { clamp, def } from '../utils' export default function currentTimeMix(art: MediaHost> & Pick): asserts art is typeof art & Position { @@ -11,6 +12,7 @@ export default function currentTimeMix(art: MediaHost - new Promise((resolve, reject) => { - try { - $canvas.width = $video.videoWidth - $canvas.height = $video.videoHeight - $canvas.getContext('2d').drawImage($video, 0, 0) - resolve($canvas.toDataURL('image/png')) - } - catch (err) { - notice.show = err - reject(err) - } - }), - }) - - def(art, 'getBlobUrl', { - value: () => - new Promise((resolve, reject) => { - try { - $canvas.width = $video.videoWidth - $canvas.height = $video.videoHeight - $canvas.getContext('2d').drawImage($video, 0, 0) - $canvas.toBlob((blob) => { - resolve(URL.createObjectURL(blob)) - }) - } - catch (err) { - notice.show = err - reject(err) - } - }), - }) - - def(art, 'screenshot', { - value: async (name) => { - const dataUri = await art.getDataURL() - const fileName = name || `artplayer_${secondToTime($video.currentTime)}` - download(dataUri, `${fileName}.png`) - art.emit('screenshot', dataUri) - return dataUri - }, - }) -} diff --git a/packages/artplayer/src/player/screenshotMix.ts b/packages/artplayer/src/player/screenshotMix.ts new file mode 100644 index 000000000..6f030cc90 --- /dev/null +++ b/packages/artplayer/src/player/screenshotMix.ts @@ -0,0 +1,65 @@ +import type { CaptureMedia } from '../capture/frame' +import { captureBlobUrl, drawFrame } from '../capture/frame' +import { isClosing } from '../lifecycle/instance' +import { captureSource } from '../source/operation' +import { def, download, secondToTime } from '../utils' + +export interface ScreenshotHost { + template: { $video: CaptureMedia } + notice: { set show(value: unknown) } + getDataURL: () => Promise + emit: (name: 'screenshot', dataUri: string) => unknown +} + +export default function screenshotMix(art: ScreenshotHost): void { + const { notice, template: { $video } } = art + const canvas = document.createElement('canvas') + + function capture(blob: boolean): Promise { + const active = captureSource(art) + // Draw synchronously as before; awaiting must not capture a later frame. + return new Promise((resolve, reject) => { + const fail = (error: unknown) => { + try { + if (!isClosing(art) && active()) + notice.show = error + } + catch (noticeError) { + reject(noticeError) + return + } + reject(error) + } + try { + drawFrame(canvas, $video) + if (blob) { + // Handle failures inside toBlob as well as synchronous canvas errors. + captureBlobUrl(canvas, resolve, fail) + } + else { + resolve(canvas.toDataURL('image/png')) + } + } + catch (error) { + fail(error) + } + }) + } + + def(art, 'getDataURL', { value: () => capture(false) }) + def(art, 'getBlobUrl', { value: () => capture(true) }) + def(art, 'screenshot', { + value: async (name?: string): Promise => { + const active = captureSource(art) + const dataUri = await art.getDataURL() + if (!isClosing(art) && active()) { + const fileName = name || `artplayer_${secondToTime($video.currentTime)}` + if (!isClosing(art) && active()) + download(dataUri, `${fileName}.png`) + if (!isClosing(art) && active()) + art.emit('screenshot', dataUri) + } + return dataUri + }, + }) +} diff --git a/packages/artplayer/src/player/thumbnailsMix.js b/packages/artplayer/src/player/thumbnailsMix.js deleted file mode 100644 index dbd53c284..000000000 --- a/packages/artplayer/src/player/thumbnailsMix.js +++ /dev/null @@ -1,84 +0,0 @@ -import { def, isMobile, loadImg, setStyle } from '../utils' - -export default function thumbnailsMix(art) { - const { - option, - template: { $progress, $video }, - } = art - - let timer = null - let loding = false - let image = null - - function reset() { - clearTimeout(timer) - timer = null - loding = false - image = null - } - - function showThumbnails(posWidth) { - const $thumbnails = art.controls?.thumbnails - if (!$thumbnails) - return - - const { number, column, width, height, scale } = option.thumbnails - const width2 = width * scale || image.naturalWidth / column - const height2 = height * scale || width2 / ($video.videoWidth / $video.videoHeight) - const perWidth = $progress.clientWidth / number - const perIndex = Math.floor(posWidth / perWidth) - const yIndex = Math.ceil(perIndex / column) - 1 - const xIndex = perIndex % column || column - 1 - setStyle($thumbnails, 'backgroundImage', `url(${image.src})`) - setStyle($thumbnails, 'height', `${height2}px`) - setStyle($thumbnails, 'width', `${width2}px`) - setStyle($thumbnails, 'backgroundPosition', `-${xIndex * width2}px -${yIndex * height2}px`) - if (posWidth <= width2 / 2) { - setStyle($thumbnails, 'left', 0) - } - else if (posWidth > $progress.clientWidth - width2 / 2) { - setStyle($thumbnails, 'left', `${$progress.clientWidth - width2}px`) - } - else { - setStyle($thumbnails, 'left', `${posWidth - width2 / 2}px`) - } - } - - art.on('setBar', async (type, percentage, event) => { - const $thumbnails = art.controls?.thumbnails - const { url, scale } = option.thumbnails - if (!$thumbnails || !url) - return - - const isMobileDragging = type === 'played' && event && isMobile - - if (type === 'hover' || isMobileDragging) { - if (!image && !loding) { - loding = true - image = await loadImg(url, scale) - loding = false - } - - if (!image) - return - - const width = $progress.clientWidth * percentage - - if (width > 0 && width < $progress.clientWidth) { - showThumbnails(width) - } - } - }) - - def(art, 'thumbnails', { - get() { - return art.option.thumbnails - }, - set(thumbnails) { - if (thumbnails.url && !art.option.isLive) { - art.option.thumbnails = thumbnails - reset() - } - }, - }) -} diff --git a/packages/artplayer/src/player/thumbnailsMix.ts b/packages/artplayer/src/player/thumbnailsMix.ts new file mode 100644 index 000000000..b5ccfa464 --- /dev/null +++ b/packages/artplayer/src/player/thumbnailsMix.ts @@ -0,0 +1,115 @@ +import type { Thumbnails } from '../../types/option' +import type { SubscriptionHost } from '../component/resources' +import { entryScope } from '../component/resources' +import { eventSubscriptions } from '../events/subscriptions' +import { loadThumbnailImage } from '../image/load' +import { getScope, isClosing } from '../lifecycle/instance' +import { captureSource } from '../source/operation' +import { thumbnailLayout } from '../thumbnails/layout' +import { def, isMobile, setStyle } from '../utils' + +interface ThumbnailEvents { + setBar: [type: string, percentage: number, event?: Event] +} + +export interface ThumbnailsHost extends SubscriptionHost { + option: { thumbnails: Thumbnails, isLive: boolean } + template: { $progress: HTMLElement, $video: { videoWidth: number, videoHeight: number } } + controls?: { thumbnails?: HTMLDivElement } +} + +export default function thumbnailsMix(art: ThumbnailsHost): void { + const { option, template: { $progress, $video } } = art + let scope = getScope(art).child() + let image: HTMLImageElement | undefined + let loading = false + let control: HTMLDivElement | undefined + let hover: { percentage: number, element: HTMLDivElement, sourceActive: () => boolean } | undefined + + function reset(): void { + const previous = scope + scope = getScope(art).child() + image = undefined + loading = false + hover = undefined + previous.dispose() + } + + function render(): void { + const current = hover + const currentScope = scope + if (!current || !image) + return + const active = () => !isClosing(art) && !currentScope.closed && scope === currentScope + && hover === current && current.sourceActive() && art.controls?.thumbnails === current.element + if (!active()) + return + const position = $progress.clientWidth * current.percentage + if (!(position > 0 && position < $progress.clientWidth)) + return + const styles = { + backgroundImage: `url(${image.src})`, + ...thumbnailLayout(option.thumbnails, { + imageWidth: image.naturalWidth, + videoWidth: $video.videoWidth, + videoHeight: $video.videoHeight, + progressWidth: $progress.clientWidth, + position, + }), + } + for (const [key, value] of Object.entries(styles)) { + if (!active()) + return + setStyle(current.element, key, value) + } + } + + eventSubscriptions(art)('setBar', (type, percentage, event) => { + const element = art.controls?.thumbnails + const { url, scale } = option.thumbnails + if (isClosing(art) || !element || !url || !(type === 'hover' || (type === 'played' && event && isMobile))) + return + if (control !== element) { + const elementScope = entryScope(element) + if (elementScope.closed) + return + control = element + elementScope.add(() => { + if (control === element) { + control = undefined + reset() + } + }) + } + hover = { percentage, element, sourceActive: captureSource(art) } + if (image) { + render() + } + else if (!loading) { + const currentScope = scope + loading = true + loadThumbnailImage(url, scale, currentScope).then((loaded) => { + if (scope !== currentScope || currentScope.closed) + return + loading = false + image = loaded + render() + }).catch((error: unknown) => { + if (scope === currentScope && !currentScope.closed) { + loading = false + console.warn('ArtPlayer thumbnail load failed:', error) + } + }) + } + }) + + def(art, 'thumbnails', { + get: () => art.option.thumbnails, + set: (thumbnails: Thumbnails) => { + if (!isClosing(art) && thumbnails.url && !art.option.isLive && !isClosing(art)) { + art.option.thumbnails = thumbnails + reset() + } + }, + }) +} diff --git a/packages/artplayer/src/player/urlMix.ts b/packages/artplayer/src/player/urlMix.ts index dfee86292..918541947 100644 --- a/packages/artplayer/src/player/urlMix.ts +++ b/packages/artplayer/src/player/urlMix.ts @@ -50,8 +50,7 @@ export default function urlMix failSource(operation, error)) } else { - if (oldUrl) - URL.revokeObjectURL(oldUrl) + // Media URLs are supplied by callers or adapters, which own revocation. if (!operation.active()) return $video.src = newUrl diff --git a/packages/artplayer/src/source/restore-position.ts b/packages/artplayer/src/source/restore-position.ts new file mode 100644 index 000000000..b1cf89a02 --- /dev/null +++ b/packages/artplayer/src/source/restore-position.ts @@ -0,0 +1,49 @@ +import type { SwitchHost } from './types' +import { positionRevision } from '../media/position-revision' + +// Native media clocks may round within a frame. Larger misses need one correction. +const POSITION_TOLERANCE = 0.05 + +export function positionRestoration(art: Pick, target: number, active: () => boolean) { + let expected: number | undefined + let observedSeek = false + let corrected = false + let manual = false + let revision = positionRevision(art) + const manualPosition = () => manual || positionRevision(art) !== revision + const seeking = () => !!art.template?.$video?.seeking + return { + restore(): void { + if (!active() || manualPosition()) + return + const previousRevision = positionRevision(art) + art.currentTime = target + revision = positionRevision(art) + // Nested public writes supersede the restoration's own setter call. + if (revision > previousRevision + 1) + manual = true + if (!active()) + return + // Keep the actual clamped value accepted by the player setter. + expected = art.currentTime + if (!active() || manualPosition()) + return + observedSeek = seeking() + }, + manual(): void { + manual = true + }, + ready(): boolean { + if (!active() || seeking()) + return false + const missed = expected !== undefined && Math.abs(art.currentTime - expected) > POSITION_TOLERANCE + if (!manualPosition() && observedSeek && !corrected && expected !== undefined && missed) { + corrected = true + if (!active()) + return false + art.currentTime = expected + } + return active() && !seeking() + }, + } +} diff --git a/packages/artplayer/src/source/switch.ts b/packages/artplayer/src/source/switch.ts index 26b223ad0..687304a3a 100644 --- a/packages/artplayer/src/source/switch.ts +++ b/packages/artplayer/src/source/switch.ts @@ -2,6 +2,7 @@ import type { SourceEvent, SourceListener, SwitchHost } from './types' import { isClosing } from '../lifecycle/instance' import { listenSource } from './listen' import { assignUrl, beginSource } from './operation' +import { positionRestoration } from './restore-position' export function switchSource(art: SwitchHost, url: string, currentTime: number): Promise { return new Promise((resolve, reject) => { @@ -39,44 +40,67 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number): return const readiness = scope.child() + let canPlay = false + let resuming = false + let rateRestored = false + const position = positionRestoration(art, currentTime, active) + const resume = async () => { + art.aspectRatio = aspectRatio + if (!active()) + return + if (playing) { + // The public play promise still rejects; this internal resume is best effort. + try { + await art.play() + } + catch {} + } + if (!active()) + return + art.notice.show = '' + settle() + } + const resumeWhenReady = () => { + if (!active() || resuming || !canPlay) + return + try { + // canplay can arrive before the metadata restoration seek has settled. + if (art.template?.$video?.seeking) + return + if (!active()) + return + if (!rateRestored) { + rateRestored = true + art.playbackRate = playbackRate + } + if (!position.ready() || !active() || resuming) + return + resuming = true + readiness.dispose() + void resume().catch(fail) + } + catch (error) { + fail(error) + } + } const handlers = { 'video:error': fail, 'video:loadedmetadata': () => { if (!active()) return try { - art.currentTime = currentTime + position.restore() } catch (error) { fail(error) } }, 'video:canplay': () => { - if (!active()) - return - // Detach readiness handlers before awaiting a possibly pending play. - readiness.dispose() - const resume = async () => { - art.playbackRate = playbackRate - if (!active()) - return - art.aspectRatio = aspectRatio - if (!active()) - return - if (playing) { - // The public play promise still rejects; this internal resume is best effort. - try { - await art.play() - } - catch {} - } - if (!active()) - return - art.notice.show = '' - settle() - } - void resume().catch(fail) + canPlay = true + resumeWhenReady() }, + 'video:seeked': resumeWhenReady, + 'seek': position.manual, } const capture = scope.child() const queued: [SourceEvent, unknown][] = [] @@ -101,7 +125,7 @@ export function switchSource(art: SwitchHost, url: string, currentTime: number): } const dispatch = {} as Record for (const name of names) - dispatch[name] = listenSource(readiness, art, name, handlers[name]) + dispatch[name] = listenSource(readiness, art, name, handlers[name], name !== 'video:seeked') for (const [name, event] of queued) { if (!active() || readiness.closed) break diff --git a/packages/artplayer/src/source/types.ts b/packages/artplayer/src/source/types.ts index 4a31c575a..21ebc6afc 100644 --- a/packages/artplayer/src/source/types.ts +++ b/packages/artplayer/src/source/types.ts @@ -1,4 +1,4 @@ -export type SourceEvent = 'video:error' | 'video:loadedmetadata' | 'video:canplay' +export type SourceEvent = 'video:error' | 'video:loadedmetadata' | 'video:canplay' | 'video:seeked' | 'seek' export type SourceListener = (event?: unknown) => void export interface SourceEvents { @@ -28,6 +28,7 @@ export interface UrlHost extends UrlTarget, Sou } export interface SwitchHost extends UrlTarget, SourceEvents { + template?: { $video?: { readonly seeking?: boolean } } currentTime: number readonly playing: boolean aspectRatio: string diff --git a/packages/artplayer/src/thumbnails/layout.ts b/packages/artplayer/src/thumbnails/layout.ts new file mode 100644 index 000000000..c28b9d0bb --- /dev/null +++ b/packages/artplayer/src/thumbnails/layout.ts @@ -0,0 +1,32 @@ +import type { Thumbnails } from '../../types/option' + +export interface ThumbnailGeometry { + imageWidth: number + videoWidth: number + videoHeight: number + progressWidth: number + position: number +} + +export function thumbnailLayout(option: Thumbnails, geometry: ThumbnailGeometry) { + const { number, column, width, height, scale } = option + const { imageWidth, videoWidth, videoHeight, progressWidth, position } = geometry + const columns = Number(column) + const previewWidth = Number(width) * Number(scale) || imageWidth / columns + const previewHeight = Number(height) * Number(scale) || previewWidth / (videoWidth / videoHeight) + const index = Math.floor(position / (progressWidth / Number(number))) + // Match the zero-based cells produced by artplayer-tool-thumbnail. + const row = Math.floor(index / columns) + const cell = index % columns + const left = position <= previewWidth / 2 + ? 0 + : position > progressWidth - previewWidth / 2 + ? `${progressWidth - previewWidth}px` + : `${position - previewWidth / 2}px` + return { + height: `${previewHeight}px`, + width: `${previewWidth}px`, + backgroundPosition: `-${cell * previewWidth}px -${row * previewHeight}px`, + left, + } +} diff --git a/packages/artplayer/src/utils/dom.js b/packages/artplayer/src/utils/dom.js index 6ff4b5627..9e593a1af 100644 --- a/packages/artplayer/src/utils/dom.js +++ b/packages/artplayer/src/utils/dom.js @@ -1,5 +1,6 @@ import { isMobile } from './compatibility' +export { loadImg } from '../image/load' export { setStyleText } from '../style/inject' /** @param {string} selector @param {ParentNode} parent */ @@ -112,47 +113,6 @@ export function getRect(el) { return el.getBoundingClientRect() } -export function loadImg(url, scale) { - return new Promise((resolve, reject) => { - const img = new Image() - - img.onload = function () { - if (!scale || scale === 1) { - resolve(img) - } - else { - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d') - canvas.width = img.width * scale - canvas.height = img.height * scale - ctx.drawImage(img, 0, 0, canvas.width, canvas.height) - - canvas.toBlob((blob) => { - const blobUrl = URL.createObjectURL(blob) - const scaledImg = new Image() - - scaledImg.onload = function () { - resolve(scaledImg) - } - - scaledImg.onerror = function () { - URL.revokeObjectURL(blobUrl) - reject(new Error(`Image load failed: ${url}`)) - } - - scaledImg.src = blobUrl - }) - } - } - - img.onerror = function () { - reject(new Error(`Image load failed: ${url}`)) - } - - img.src = url - }) -} - export function getComposedPath(event) { if (event.composedPath) return event.composedPath() diff --git a/refactor/baselines/capture-progress-validation.json b/refactor/baselines/capture-progress-validation.json new file mode 100644 index 000000000..95bd2edaa --- /dev/null +++ b/refactor/baselines/capture-progress-validation.json @@ -0,0 +1,26874 @@ +{ + "task": "CORE-19", + "date": "2026-09-11", + "status": "validated", + "node": "v24.21.0", + "parentCommit": "98a18000321500f92f228be7b7edff4bda948a56", + "source": { + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/component/dom.ts": "740f63e6e5942c444b9f05605880f8d56a77b066dbe5c4791da74f78cb96c668", + "packages/artplayer/src/component/resources.ts": "ff158ef0db8ba13343ff6ba329713820cfe2f5c2c446a7873a6cfff782855edf", + "packages/artplayer/src/component/selection.ts": "1f0bd089415da28db862647ffd1a0b4af752576465fb616d4b97ae4f8dcae3a7", + "packages/artplayer/src/component/types.ts": "d7b0e7008b0f6c82e3e97ac43e0188598dca4f740a860e7a60b3b38a46f4565d", + "packages/artplayer/src/config/index.js": "d6d2bd612daaf6c5c6e982158acbdf724b16d3c35bb5f1a5c923284665a8de79", + "packages/artplayer/src/contextmenu/aspectRatio.ts": "a25464e14216b2be392fcb3fdda2439e6d6f98d1962f0acbba30e3bd53bcb2d4", + "packages/artplayer/src/contextmenu/close.ts": "84b7a96df910e6f38140df8b1e73519d209a7331e9be9f42d076ae791757024f", + "packages/artplayer/src/contextmenu/flip.ts": "42c192d23e347d74e0bb814697a4d59eac20afbec102a282d5aa15780cab5f72", + "packages/artplayer/src/contextmenu/index.ts": "4fd292a931b5bda9f16a1c2bedd50cd0d8c0b8fb6010ffc5faaad2c197d2d9e5", + "packages/artplayer/src/contextmenu/info.ts": "f37cf0104510c13a130d2f55114c8f7ff15cc1b51863f97e60825442bdb2bf01", + "packages/artplayer/src/contextmenu/playbackRate.ts": "e177f4017ea9291794fb4023715c81bfc01f927324ab9bd0e32c741e4a3b0ca7", + "packages/artplayer/src/contextmenu/types.ts": "a93fc90f4e17b731e8f6b486a507117810b61c1f1b0d9e775eba27dabeaeee1d", + "packages/artplayer/src/contextmenu/version.ts": "0553a716be0ba49f614059c41eef6dc694a9641fca79e6448b1b30382c6b582b", + "packages/artplayer/src/control/airplay.ts": "a02ab41654a963e06fb2eb206cfe606cebc27252ba00b3fc2116ea232c8d7d51", + "packages/artplayer/src/control/builtins.ts": "2a0e12a9741713c92938e1d2009149bbbde498284aa85c63f270d02b27dc22b1", + "packages/artplayer/src/control/fullscreen.ts": "6856d98530877b9458275d8e064a94a81b9e2a4de079cce1a83e7cbe71e5ab8b", + "packages/artplayer/src/control/fullscreenWeb.ts": "e20f8fe9788738adfccb21e7bf248e5e8068312e856bb2626d05fbb20cfdb65d", + "packages/artplayer/src/control/index.ts": "ce23b79a0a40f22bdd8ad5f461d6b0df9366c7e4ab78571e0c67649f6e6d38e7", + "packages/artplayer/src/control/layout.ts": "b5134a9d0cb5ad128b1fb229dce79a306b944f750d8620e224a99f5791e6cab5", + "packages/artplayer/src/control/pip.ts": "9299d785ce21b16dc9edbcb6a803f8748157ed16e1924f461bdbc4853adaa5ac", + "packages/artplayer/src/control/playAndPause.ts": "e65461f5bf29680f12b7e0efa7d44186f07bbe9936247a9a220f724c9d9774bb", + "packages/artplayer/src/control/progress/interactions.ts": "da03600375451ecf8c152be5afcc5f1a4f8b759e837bbd54b7faaf8f8b228497", + "packages/artplayer/src/control/progress/position.ts": "31ca4a6a4cdd93636f79d79196dafb4c5213ee1428753be0a58783f0d27c6ae9", + "packages/artplayer/src/control/progress/view.ts": "60ee16d5170be81b8132bb56dd0bc0eaf23e50f5c268d0697c9187b38a14aba9", + "packages/artplayer/src/control/progress.ts": "f0876ddbdc01f812a5a776bdeefdff8dc52e557aff684f99b5ea7f6bfc8c0fb3", + "packages/artplayer/src/control/resources.ts": "16fd7c53ac8f47b333041c4f298313390dc102523d47767b8a16f39a2564ba74", + "packages/artplayer/src/control/screenshot.ts": "67be1306991861cb8bb0adec2b58a8468211459f9337895e611972dbb71a6ef5", + "packages/artplayer/src/control/selector.ts": "5d946c36d0308f32e08dd0e189f0c959f738ed7ab521230833c76a5bf9ca6478", + "packages/artplayer/src/control/setting.ts": "63e9824ffee2221ba82be9f2bc430b9b3133a2186905fcce2a61b8aa946a3d8a", + "packages/artplayer/src/control/time.ts": "fa572092e0848878689367fb536e9658d13888d0a0d476babc5acd165af0f8d3", + "packages/artplayer/src/control/types.ts": "7fab47c7106efa51aae89026af335f74d9f3ea52ef9864ec2801d0ea2deffc4c", + "packages/artplayer/src/control/volume.ts": "b50d1a5d2697d6440ac0f3d82634b13f7c2fff00c185a1adf4451ed8ba810709", + "packages/artplayer/src/display/fullscreen-abandoned.ts": "1715b30d336976921b4957b444418702b7d93dbf1debce47429269638d15810f", + "packages/artplayer/src/display/fullscreen-adapter.ts": "71da10ec21c7706a8264badedac9022c74b865887931e9e369168fe3233c3b2f", + "packages/artplayer/src/display/fullscreen-request.ts": "c6292ded96aab0f2dbc978af251f6cd9f5fd074819529ca498077db8d14e1bfe", + "packages/artplayer/src/display/mini-drag.ts": "73d2f48f868c0ba4d8d5e5df40cbbdb4698c26540f3973b178d9cd374008f1cb", + "packages/artplayer/src/display/mini-layout.ts": "3835fe3d314da2fc624cbeb0e79fcdfa5393f08d87dfde730d2eac4e827f405b", + "packages/artplayer/src/display/mini-view.ts": "83a6e5c6d1923332973009b7ac1561f7a55fb72e5c60e5ebc88af1fa4b641d5e", + "packages/artplayer/src/display/mini.ts": "3ffae49b1407523da2dc5f2bc687018268f6c1d1d3c71911dd4aa96d1a66c1dc", + "packages/artplayer/src/display/native-fullscreen.ts": "323401f2b3ea5186da981a1215b1b9e7dcf4ef4261a8e885fe8ff0c090de6a7a", + "packages/artplayer/src/display/native-pip.ts": "647879ae027cc0ebe684daa31d75511dd882e123e4ca8da2942e659bae3719f2", + "packages/artplayer/src/display/orientation-native.ts": "909980ba837471d9b456545a18fb0ab19f0990e8788936f0580a4b332cd4baee", + "packages/artplayer/src/display/orientation-types.ts": "911207b0a3a9d4c2d0ef10b65ce7ace67e29e274fb922a8679fe818cf043d08c", + "packages/artplayer/src/display/orientation-web.ts": "aea55c3b9e8c708fe5559f07cf8f0afd7ad37ac5b1a43bf519245c3072ec4129", + "packages/artplayer/src/display/placement.ts": "dbe4491ebd0f46b4efe13ac567e476fcd9ca5b84da675f19025935b5e3f8d733", + "packages/artplayer/src/display/sizing-types.ts": "da9b3d957dafaca9331f7319257dd8156b3c3e7b6db11f33f11ded48512450ad", + "packages/artplayer/src/display/sizing.ts": "c19856976320f1f35ff5a1049d19a940768300e095270b336dd12861b200da2a", + "packages/artplayer/src/display/types.ts": "9dff7ee42c0cd1a9ab37a5acd9788b30ad01455bfd2f3abc2f4e1f157bf16c89", + "packages/artplayer/src/display/video-fullscreen-state.ts": "5fcb5e6b80ac45577664ef67e0460e0ceefd4022cafacdd7434c376a86d619be", + "packages/artplayer/src/display/video-fullscreen.ts": "b425bf0df462524b5d3accc9e3df383c6635676c152bf4bef09c477a90662728", + "packages/artplayer/src/display/web-fullscreen.ts": "dd2c5cf65cfe35d6b5a87d01acb28f48119b27fe6e5f0c6a8b9bab3db1a1923f", + "packages/artplayer/src/display/webkit-pip.ts": "3617927b4bb8fa46f651d0e584141f804ae438e2b4531cc2e9cf9f7eeb027550", + "packages/artplayer/src/events/clickInit.ts": "bd1ba29fe0af4332ceb19297797c4c942a3a74bfd901998d6b93293f1b309300", + "packages/artplayer/src/events/gestureInit.ts": "9e9d1ac0da7f87e89dd0d86fa2820b980e9cb810782d6ab30017de8686fc910b", + "packages/artplayer/src/events/global-types.ts": "3f4672d7af959cfa34ba39aa84ce614f422901437686bba98b14f578df40021c", + "packages/artplayer/src/events/globalInit.ts": "6f6ea497a20a8fd0746b1f020caff76ad6817cd70a1a90fbaea12f992b6d03a7", + "packages/artplayer/src/events/hoverInit.ts": "d1250e0dd35a8ba8067275986acbe6320c22adf1a977ec1009c0c012ed1563fe", + "packages/artplayer/src/events/index.ts": "30d2286316dbd351e93f5a2234dcca84bf68ca28c05921169cca70c2e0b1ecf9", + "packages/artplayer/src/events/listener-registry.ts": "fb062df5151c4e8e970de469f1c7d9af948f72214d32c293c81a5feeb8406124", + "packages/artplayer/src/events/moveInit.ts": "11342cb9c97c8ff728bbf6b47e58ce93a43062d4f69cf6cbbbc0a6f8d086c8fe", + "packages/artplayer/src/events/resizeInit.ts": "719e27d11d2f93fcbe8368393c9190e251fc86dd0c3c2919f60e9b3b1edd0192", + "packages/artplayer/src/events/scheduling-types.ts": "5cfeb1bfc23b06bf71c8049bd2cc2f5de384840a2b16511d1222944b0ccd4684", + "packages/artplayer/src/events/subscriptions.ts": "98573ed6cce73a73467c0e7fdb8ddc45e66b6bdf684c38886749453b2002a1d8", + "packages/artplayer/src/events/types.ts": "df03625039605314a96ef15b5e3777cbb9d444fd317e1a2fbeaaa0f1e83f6b0f", + "packages/artplayer/src/events/updateInit.ts": "6f174db14d20319f03a76e6ea267a3d71973faac44a92483badfa4420791817a", + "packages/artplayer/src/events/viewInit.ts": "d77b83eab802ff0046a4966e28b810a25592bcada49f526adae37556c1e4c3e9", + "packages/artplayer/src/events/viewport.ts": "6196fccb8b08ae22bde732c4389d9aceb5d727a63efd87b6d3914e338aadc46f", + "packages/artplayer/src/hotkey.ts": "d8e477bf451143e566e1f743a5f253dcf00beb23544709794779f275e11498e8", + "packages/artplayer/src/i18n/ar.ts": "c1e41787c700096ecbc91de6558353f43d8930929ee312b7aa2c7da14a07ec75", + "packages/artplayer/src/i18n/cs.ts": "62c5ffcf3ac24e0dc2d7222b7ebb2b4d3454e9c04b80930a50defb3867d645be", + "packages/artplayer/src/i18n/es.ts": "5d31184b41ef29c1544c91ff08e3bbf9fc5c5776f0af0aa0238f90a9d161b9b1", + "packages/artplayer/src/i18n/fa.ts": "1294b91178ebdc7bc26d14a6f407ba8598207ae0dc812f3b821b62b7bf0089e5", + "packages/artplayer/src/i18n/fr.ts": "7125c0011b90f507d5b5fe20afd875992b62af9cdd44f02bbabed051c4ebc107", + "packages/artplayer/src/i18n/id.ts": "0d2e79cc0118cff6be83786a3fc048461785a64bdffc6bc45ffb68cb595f6da4", + "packages/artplayer/src/i18n/index.ts": "09c6f5bce58e4118dde10e8b2a2d3808785b7fde913a54dd189e0b473e21266a", + "packages/artplayer/src/i18n/pl.ts": "f6fb58a0d3fa118e22cfa6df5edd74c7bf39dc9ff1d416fb2b01e1bb8708b06f", + "packages/artplayer/src/i18n/publish.ts": "5b216bbe313b3cda56a5da41fba4fb9d095eeec0dc903fcf284ddd8f94926e99", + "packages/artplayer/src/i18n/ru.ts": "473c43197acec10991b0f67814f79421dfe9ec4f534fb15413a32cf2a4d8ad38", + "packages/artplayer/src/i18n/tr.ts": "7b6afbbe452c4907c8bef36663bd218fd140bd1a4b3c776f31c53415e78e8f16", + "packages/artplayer/src/i18n/vi.ts": "29ea7f23d7400c847596632c86a4ca10c39cbafe1e6d723ed099b819aca7e764", + "packages/artplayer/src/i18n/zh-cn.ts": "22584521b0aa92da5278b01581e6e8e5bb3a23a2c3029e9df8642b7f0bded392", + "packages/artplayer/src/i18n/zh-tw.ts": "8da94a4fd508176bbb6b7ce2f4ba6ef6a56e7b1229bc67cc42d1a7bde70a7e9d", + "packages/artplayer/src/icons/airplay.svg": "8c75a40f1bfacee2be2a425e132ff51f3712eba60679010f7b1349d4a04374bc", + "packages/artplayer/src/icons/arrow-left.svg": "8b9d544b7bd728d01747005fc7a2d63f822eed3b605393e2435b6733861b585f", + "packages/artplayer/src/icons/arrow-right.svg": "68c63d6d5810173ec9192c9e96ee7b6aefdc3b79d3c1329fb4d6c750f859fe10", + "packages/artplayer/src/icons/aspect-ratio.svg": "987752a87701523057d8dfa7c45a6a139c4542b96fdcfaf8665722bbeb41f3b2", + "packages/artplayer/src/icons/check.svg": "963ce0aee2337fdee951aa6c917cc75ee0b4e75158887ccc16baebfd3925942b", + "packages/artplayer/src/icons/close.svg": "ebabfe8044f48d5df4d13f4f906a163fd55a4d6f1dedb3b5ba95601209bc8888", + "packages/artplayer/src/icons/config.svg": "e1884d5411296b5cd1bfec7803b558b0afa5ab64478393977b07a662e2e0f15c", + "packages/artplayer/src/icons/defaults.ts": "31df862d754922fe5d68b20911c477d7c22893a6a67b5dcb1a48d3b437a0b23a", + "packages/artplayer/src/icons/error.svg": "b40c01e511a599c9dd369aeb9a3b2a0d1a76ef3c5ede8124cbbc23f8e4e7248c", + "packages/artplayer/src/icons/fast-forward.svg": "abef6fe4d75ffa74d3a84683373b4702a4eda2a5b4045952f969ee62cc68b0be", + "packages/artplayer/src/icons/flip.svg": "474a9d53a97add71e3fb7bc6530a68580ce63a1d83f9b75d1c2908a7cf494152", + "packages/artplayer/src/icons/fullscreen-off.svg": "71125ac56586897e2c0e52035a4d65cff34cf52043a95b45d186e0d268671399", + "packages/artplayer/src/icons/fullscreen-on.svg": "d46cdf265cac729c9b7382722ebe7a4c76d71ad4e5a27c2d5ed8323fd595ebf5", + "packages/artplayer/src/icons/fullscreen-web-off.svg": "52a6862ecd7cba12ab7042de5064c498bc2e9f86b430358c912401fafe4f4a98", + "packages/artplayer/src/icons/fullscreen-web-on.svg": "5cfaae62b61456251e771bff01356fad8376ebedb10a4b8819740f60e6e5a073", + "packages/artplayer/src/icons/index.ts": "3ef720aee403e6b7baf1ab472dbdd16c671f2d691ecea48ff1c25ca1ffc66296", + "packages/artplayer/src/icons/loading.svg": "485472153890eff3ed49963f7bf7d841f66ca2f40894c01d6e8bcf1bf4ad1c58", + "packages/artplayer/src/icons/lock.svg": "431e9a25fae051016be0efa286387ec3e5f7651c3ecf569bf0ece9842f57156c", + "packages/artplayer/src/icons/pause.svg": "57405dba81dd3d9f329d957fdc704101cbb6f6654325eb0083c03324c4453a68", + "packages/artplayer/src/icons/pip.svg": "1e922140e0941e5b9ef53dc0b4776813e1c470ea229fe3ec786fd148148c3352", + "packages/artplayer/src/icons/play.svg": "41a961c629a55cb25a813e115a25204e492d4e935a0879177e65d6e1ddfd6796", + "packages/artplayer/src/icons/playback-rate.svg": "872deecac0365ab04aeb5ccb1cdd9a0c88589a1442709fdac7c0ed12a241ff2b", + "packages/artplayer/src/icons/screenshot.svg": "538b5cd0c6b20afb98bd850e15019072d652d191075c2869f2fc0f28b597b131", + "packages/artplayer/src/icons/setting.svg": "2976b00d1f03e78f28d0e55ebcb01d5a0746ec1a6ff8de97a5e8294bacdd1fad", + "packages/artplayer/src/icons/state.svg": "620a127f74bb5e249993bd7008c027373263eacb4a44af8adeaa0d7523346887", + "packages/artplayer/src/icons/switch-off.svg": "95a8d81a4a3bfcf7c016d5f71d46a72be73c5e94790c55fd1d31023416ef5deb", + "packages/artplayer/src/icons/switch-on.svg": "cccd0f9c1e54d9ac50c323360da944d8ff44633a82ff17889914b6bc8b1652ae", + "packages/artplayer/src/icons/unlock.svg": "fc058db3d99a475fb9ffbbbb6248978a95990a9c532b83d0955ac28eaa626c60", + "packages/artplayer/src/icons/volume-close.svg": "f7e100fd9e9f3f6e06afe5bc994d5d9305ee4d1ee23fae37e4108cf286dab379", + "packages/artplayer/src/icons/volume.svg": "3a78f40d8b48595e8f15d9189e4d767e0c7abbf0338d3f2db1ac810049dd3942", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/index.js": "cb874ac34fa650bd364b3fef7eed4830bf3bd47093097ae7ba0432e7e64b1a10", + "packages/artplayer/src/info/poll.ts": "1d7a519dd1960c8cd5fb7a020d8d3dbcd2eb272b612d823f2167997751aaf663", + "packages/artplayer/src/info.ts": "6594ff3ee5643d63fec874631865d0e35b4ebdcf8aeafdd9fd3d9c595cfa3713", + "packages/artplayer/src/input/gesture-controller.ts": "1ebbd18184771a623b02ec19c363f84dcc72fdb7cd82bcf2adc97f4a138cb2b4", + "packages/artplayer/src/input/gesture-direction.ts": "65737f60e177338ebb3337a13ca75aeae77d77e94bc21495ddb829cc30de33a7", + "packages/artplayer/src/input/gesture-types.ts": "2b6bec62d5f7468ea028a39914f9177cfbf96779f4b20274aa7e6b8784592764", + "packages/artplayer/src/input/hotkey-defaults.ts": "c28e14821e5c7f7ac92a302e92439ab68fe77d5ef7d90a36b147b7c979ab96c6", + "packages/artplayer/src/input/hotkey-types.ts": "30a4354e89f96a10bd15e3b94ce03050286d5cb4641b8f951fd17c0724afc238", + "packages/artplayer/src/input/keyboard-focus.ts": "9f49538e93c23e07a448a8f9c9773cbc2e199c6d86e7e0adb59236ce97a07fb5", + "packages/artplayer/src/input/long-press.ts": "110cf16cf9dae845597377ebbc43249e103cbc0ece56f89e44ec6ecc7f3819b0", + "packages/artplayer/src/input/pointer-focus.ts": "802087098c786135eefa6727f13177ffe4a98e2abf48fad0e356b91e26960077", + "packages/artplayer/src/input/pointer-types.ts": "ad542779ae4030c7619b5874fb33466cbd45af5ddb72d3ce984c09f54b24dccf", + "packages/artplayer/src/layer.ts": "4014268eed043d5dd7b925cdeef6245e357cda67192a1301c5612ef98cdbec12", + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/lifecycle/instance.ts": "b1d05ae464278c82f7880d3186bca552e4429956198a067af72293b29e3ac461", + "packages/artplayer/src/lifecycle/resources.ts": "399ea5e84545c973f8967e8ffd7326dad7b3168ca6f96f77286995a5b62ee389", + "packages/artplayer/src/lifecycle/scope.ts": "e2188e8544b27cf8c7ac149e7146af628a2d6166c82b719a247adef5d85be5db", + "packages/artplayer/src/lifecycle/template-rollback.ts": "7a83da6739bcec1587b02f8157934988910d7f9103fe489a0d6f4f65290c3d77", + "packages/artplayer/src/loading.ts": "216fa5e2af5be5fcbf95a1578c869553a02f625683a98333d4a404f9a70df9f5", + "packages/artplayer/src/mask.ts": "500b8c2fb5ded63d5acab3c984fc9757f28a8b6cbd4d5beeac8c5a6d73ca63e4", + "packages/artplayer/src/media/events/forward.ts": "6b1b7e80036bfb523b51843dc6ec6d83c2b949cefb9cef085b2d679a444e46d8", + "packages/artplayer/src/media/events/listen.ts": "4eb7e943c1ebca77da8025d83b7d408276187cd02860b7793284344378bd0fe0", + "packages/artplayer/src/media/events/playback.ts": "2c68e4f6274a0dc65e56d42c928e500fc1d63bf3e03bbdd8a83c3f3ed7ae8ee4", + "packages/artplayer/src/media/events/readiness.ts": "3ba74f26dd9ff0729967097c2cb6f329a9cea57745bfe8173f9173e0d134476a", + "packages/artplayer/src/media/events/reconnect.ts": "876027b5116d0d3628755705682b30630f4b713199ed8015541932d81d2944be", + "packages/artplayer/src/media/events/types.ts": "5532f57129032a9685305d0d319543146c3e8af134ac12c8aa521cca9e83a6c2", + "packages/artplayer/src/media/hosts.ts": "7129cb93290a250e932464b71a4e4abce8a98e83935d4fd6c36a59fc6357b6af", + "packages/artplayer/src/media/playback.ts": "b0e8ae22f2660249361bf05bb2333685e14f5a7ac3e9ba0c62ee7efd38338b93", + "packages/artplayer/src/media/position-revision.ts": "ba074cce7e7c6bda84aa234de8eb315e5ca482aa9b06250896f9ac6251192851", + "packages/artplayer/src/media/types.ts": "96d4a7f066cbb6fb9138165dd736b4ca500cb19c827bd7702134d61c44cc0e87", + "packages/artplayer/src/notice.ts": "467979cc85e64bef9525af10a0384af1fa72847bc8fa7d6785f1e119785a6e77", + "packages/artplayer/src/option/defaults.ts": "f357ef80cf32085fcbc3409d92dfa27b31c13fbcf823f576052c0347911c0cca", + "packages/artplayer/src/option/resolve.ts": "53a73627cd540e3f21349c0a43beda35ea5195647a31e3f5b30ac292390b4b1b", + "packages/artplayer/src/option/types.ts": "f2ce01c01acf45fac6cbb34685b8e6c321bcad6b0da2526f3f189eb5962ea0e5", + "packages/artplayer/src/player/airplayMix.js": "b9ce49489e75045b6a1df4d8ed28f123c1b105ac4c04fefaabcffe4353ad004d", + "packages/artplayer/src/player/aspectRatioMix.ts": "9e5e7365d469aeaef65a6010cb92734702191f9086b2f21d98c9f0ad7f356898", + "packages/artplayer/src/player/attrMix.js": "c873d587ff71e024cfda5b5464d0c70a09a6a319da3f18fbaa7451a16c9ae055", + "packages/artplayer/src/player/autoHeightMix.ts": "5848e34cd826f5d4cc81d076c83fb3bcea0aed1228cd93a1edb6b8ca402ad175", + "packages/artplayer/src/player/autoSizeMix.ts": "6373a8ea7fff4cd875d17c5d3df6dc37764055ab77850a6c6348526969071cbb", + "packages/artplayer/src/player/cssVarMix.js": "93e641dd760e8f844a643a0b7d8af92b73a7f205e55087d9501934d218701bd2", + "packages/artplayer/src/player/currentTimeMix.ts": "cc374abeb85b203b9f31c566a6b9e53a4a1723d609fccc7b0c9c210993b79e75", + "packages/artplayer/src/player/durationMix.ts": "60a9d665cf302dcb6b3e37e2f057e31720935e5e588fd7709231f691f6014191", + "packages/artplayer/src/player/eventInit.ts": "a915c5a618e70b1ab10536b1273ba0fea4ec11d3a2ca629b538e90b5ad2b55f9", + "packages/artplayer/src/player/flipMix.ts": "a1519c83f8c9437a9b7e99a59e38a3d931032c579f4085226fc0955c7c9eab67", + "packages/artplayer/src/player/fullscreenMix.ts": "b339bebb4c87f7b75232d7e0d637ebe25bd09a0a0428ba87339a16af5daa71aa", + "packages/artplayer/src/player/fullscreenWebMix.ts": "75b83a6093c7887ca8725f63c55503d0bf3aafdbbf2347b579120cb257503555", + "packages/artplayer/src/player/index.js": "c3eaeab0aa5015a51dfeeb4de6f25b02b8cd66e1f8471940367d628b5fd0bdec", + "packages/artplayer/src/player/loadedMix.ts": "6a4c4a08ed74346dad3e138b1dda22c8c9c12f175fe6d00da41b89c78cbe2c18", + "packages/artplayer/src/player/miniMix.ts": "d68a0c4f6c6059d5831d2d1fd4823b8d3cbce95eefd6d36d38670d6d8720f44e", + "packages/artplayer/src/player/optionInit.js": "9d1d9d276da2403a580498c62f947373e000d9cd6e4bef5831d272c3055b5592", + "packages/artplayer/src/player/pauseMix.ts": "5bbb68eab7dcf2170c944cabb8d4b82be4e6d7623e37ad6ea464b81c1028bc0b", + "packages/artplayer/src/player/pipMix.ts": "63dfb29ffd66ce7d081b24f8e8bf697c041675b49ab8919e206d2df5132de236", + "packages/artplayer/src/player/playbackRateMix.ts": "e185c6ff52cd567f7fd7c30553bbd6c65517324d1d16c4948c3623ef457ef536", + "packages/artplayer/src/player/playedMix.ts": "5b6b89bf8dec1efb19cd51e46af1505bae006bdb3fb798e9dec7e3fb5cf0acaa", + "packages/artplayer/src/player/playingMix.ts": "968c9f6e6d23c233c77d62a593db64adcc6d1a2411f5f1c61a35c6996d6a54d9", + "packages/artplayer/src/player/playMix.ts": "60249fcacdc5b1bc6f33bcd806e8a4f5472cea21d40550b042794a75027fe34a", + "packages/artplayer/src/player/posterMix.js": "a96b0a9f5817919e373a5a55b43fe7ea94af357051c01ddd6ce9c68bc932ecba", + "packages/artplayer/src/player/qualityMix.ts": "8dfcb94f695cf983f313f00abe1aec183ceb2af4b398fbf62bf1d114257a8f43", + "packages/artplayer/src/player/rectMix.ts": "a741ee09fa3271df84363c5d73eac1b2e5adb39491f95f8112af81f1219ffed4", + "packages/artplayer/src/player/screenshotMix.ts": "fb16737d3bb2735ef0d0aa1ebe536cc3418c27d92e1b66ad4b34e81c165773b2", + "packages/artplayer/src/player/seekMix.ts": "e6e1bf00e8441f1ce58d2a67a66f7e5e98c86d78620ff10a5e6268d54f13fadb", + "packages/artplayer/src/player/stateMix.ts": "e45b3209a93ab14665d19c5740d5c632187e9fe234b019a2a0263e26884ab3b2", + "packages/artplayer/src/player/subtitleOffsetMix.ts": "e7866cf3a6d9fe271a4c34973f7a961542a738e89a3647df85197cee5853ce8b", + "packages/artplayer/src/player/switchMix.ts": "b47e174ef0edb2b96ff29f2ddd3c9f2dd2a38713db2a81002b18c89ce71994e9", + "packages/artplayer/src/player/themeMix.js": "382acfaf113fbd1ee77c63dba72953d984ea715f2d99748a12b9eae70c081d49", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/player/toggleMix.ts": "a3050136248e7d0b942387484c61286ac2b33a90724b1dc3460f5061be76f247", + "packages/artplayer/src/player/typeMix.js": "70920c8f785dca6d4bd66d82b996c37f1b69265190d7747ae8de298afae3604e", + "packages/artplayer/src/player/urlMix.ts": "726a42899261879e03c8b1d4f716458bf3e6e614cecc3bb8d7a581afc2b7866d", + "packages/artplayer/src/player/volumeMix.ts": "d830bb27b984e0ab2f687943fb49abcbd0331d71fe96049fd81edbddaa64f07f", + "packages/artplayer/src/plugins/auto-playback/prompt.ts": "cdcfd8542d49c2be61a31c74f2ff5ff0cdd1f829858b9bf5b497f2dde85c2002", + "packages/artplayer/src/plugins/auto-playback/records.ts": "731df519f264c602e5128c66f943b40e8645c403dc880652dea8f171574adc78", + "packages/artplayer/src/plugins/autoOrientation.ts": "4a13b0c010ea7a5002e66c422260ed24bb0d18b3ed41ce10974ac7ca2804cc09", + "packages/artplayer/src/plugins/autoPlayback.ts": "e349010813bbcd53503383b707c5f6e6e60d8ade6442d020fe6ba07a128c3122", + "packages/artplayer/src/plugins/builtins.ts": "1f45028b00dd82e622cc6387b1ee73e39e6ab85ca0d15117ace11b5f02dee37f", + "packages/artplayer/src/plugins/fastForward.ts": "74c03e3fcfe2f87dcb0ef1a5da5410cb96322509fd07e32930128584c54f62b5", + "packages/artplayer/src/plugins/index.ts": "28d13abc95cbedafadae0fdb682bf86fda9b705191c51843943a5dadddbd0a53", + "packages/artplayer/src/plugins/lock.ts": "9a08cec3a92006be8a9d2dba8d850bc4f8f38d586a50de86d725d0d8929130fd", + "packages/artplayer/src/plugins/miniProgressBar.ts": "21b4850fcaf6b0e82d5e62ca7aca60c179c578f7ff6d5606e6025628ff4b1cc7", + "packages/artplayer/src/plugins/registration.ts": "9891686c32aeaa33c48ca500cf30ab24ffbb0835c6248769b4c645a5ff20129b", + "packages/artplayer/src/plugins/types.ts": "6823098d5ec1bf053f60ddfdd36bfcd3f06f3b528cc5dd30fd676a1318dac590", + "packages/artplayer/src/scheme/index.ts": "dc4a3b5e08478cf72b46b0b59c023359ad5f79b891ea8a6a119ce24a5251821a", + "packages/artplayer/src/setting/activity.ts": "699ceed4bdeddb6d48eacf79c8dbf737f5d2d8c4983be70205322b14807a91b7", + "packages/artplayer/src/setting/aspectRatio.ts": "a16eb58fadf77f0a9009cf162d957ffd59d9b8fde83cc193d510fd642e3456cb", + "packages/artplayer/src/setting/checkpoint.ts": "9d3bff311f9b15c067ca49661af4f48de939f266b8077e7c2f0d66edef22dde6", + "packages/artplayer/src/setting/events.ts": "f7a3347ca146232caf2a8c9a5a18731cf7bc91dca4cd36370e0265c6eb70df53", + "packages/artplayer/src/setting/flip.ts": "e72a4ae33300d9e48880897a4f85a04fa6d9a5fff7b06ecaf9081cfb1bb14404", + "packages/artplayer/src/setting/index.ts": "f1e8a302077a8ccfa77c17ce344bdd6816943e77b5876c7f623314ff846742f7", + "packages/artplayer/src/setting/layout.ts": "584604e8fffaeaf1d633d1ed45e64d94595c2a56976e3a3f7ede01839b83a37d", + "packages/artplayer/src/setting/model.ts": "c47348f0f9494c4ce8ea5561bcde6eb698fb11e9197ccdc1ca1359a6d5e370dd", + "packages/artplayer/src/setting/panels.ts": "64d48720971763985a2a652a18c2ed2f32300c3553d56b52049ae40c4dfceae1", + "packages/artplayer/src/setting/playbackRate.ts": "2e70e0d2a33cb0ec9fcdd6d22424979fed7b2e01f87015d6be4e520d5cf4e88a", + "packages/artplayer/src/setting/registration.ts": "c29db62b5d90e0efa4a926c753015e65e96a47add3f5b8840ee51017052edf7c", + "packages/artplayer/src/setting/render.ts": "2bb29994c60d0c47517bdf7cacb6afac7d65075f0a67d895a3ce52250b668232", + "packages/artplayer/src/setting/resources.ts": "64c28cc2cb08cb87b0864ab957d7999bc94931be4788f282d6f190b8806a81fd", + "packages/artplayer/src/setting/selection.ts": "a1bc04b99bda45cc1a2afcf2dd0925c88ccb55e169b971105277883ae2ccba0c", + "packages/artplayer/src/setting/subtitleOffset.ts": "86513835d4e542ac39e9d551507473e3e14c71fd0d5ea725267008ecbff6ab83", + "packages/artplayer/src/setting/types.ts": "799e7adeac76c4a327201ec66f10d8f25f92387409f1e5e65f265df7711973e1", + "packages/artplayer/src/setting/update.ts": "3725fd69b369e4a345b1657ab559a915ab967c20088a093e288ffa7370cda264", + "packages/artplayer/src/source/listen.ts": "c0596b98258c1544c8e4b762509646428450e56588da36908cb8583b8b716c37", + "packages/artplayer/src/source/operation.ts": "a6cb65594a5b28247e3a6889fe0a2f47a34aeb08cdde5f0125800a87862cd559", + "packages/artplayer/src/source/restore-position.ts": "35d3fabf5415606a0bcf4c5f6c519d8b005a63ce1f1aeef67c75d0b37925266d", + "packages/artplayer/src/source/switch.ts": "16f5418d73a1d6e89fbb797afcd79af13857861ba25cca9046c16b70ad31d431", + "packages/artplayer/src/source/types.ts": "2c5963861640ee938f557f89f68815f4311147842526d41bc6288edd0e079860", + "packages/artplayer/src/storage.js": "92067265b7f1104c4680e27e35726cf033811c6551e7c38d66028f2dd5300491", + "packages/artplayer/src/style/artplayer.less": "4e8513138d5d10c05b66986977d24ed17f1de3c0df3816dec6d90db7a97b5da3", + "packages/artplayer/src/style/aspectRatio.less": "091931a0cdc83e65a669332811ef3276b85bca9e55f7fff42aa46893d728c1ef", + "packages/artplayer/src/style/backdrop.less": "6c2cd0fa200d1f3525df98c3c56dbdc553445724aece3feb0386949245813343", + "packages/artplayer/src/style/bottom.less": "6fb307d8449fd04b804d5e72ea0f175f8aa9c9dd2bf1efbf756f800b39ac97ab", + "packages/artplayer/src/style/contextmenu.less": "70f6c7e26dc96652b659c7bf6fdad92737ed477dea69d253c57dc7266c76586d", + "packages/artplayer/src/style/controls.less": "eb6d4bf4e4ff903d724d45f3ff60f0cf10c02e622fba195555a8179100cdce87", + "packages/artplayer/src/style/danmuku.less": "e4215ee9fa2f1d0599e7311a2415cc975138265b7c6af0448d27d21b6c9e3511", + "packages/artplayer/src/style/flip.less": "5d3c7a81df9be455c2f683ebf48f39597d218dc2144addacb72ee1736bac3b7f", + "packages/artplayer/src/style/fullscreen.less": "dd350d3a0fc556d59b622a53c786b8c2a583e8fb28176e4b9e91baff90479496", + "packages/artplayer/src/style/fullscreenWeb.less": "d74e785c2fbbb2976e131620e751326f622f2916eceff9f2333059ca3296cdc9", + "packages/artplayer/src/style/hideCursor.less": "09a4607c8b0005dc199828172aa8dda395f861e407769b9696d793476c4a7823", + "packages/artplayer/src/style/hint.less": "ae9f3115dfdb1e2d7b8249497c080e6a25f9667f915f6e89820338d67bbc2d85", + "packages/artplayer/src/style/icon.less": "52d8f75c1d193e6160f57ca6997c3f9135adad8eb2338ed60c1eb8e5fe443be5", + "packages/artplayer/src/style/index.less": "ec67999b458d5545a4f17eeda922872823d655da012fa69113902629ad847548", + "packages/artplayer/src/style/index.ts": "856afc037ffcd4d18c4b54901ddbb30e310014553fe9d19560e34fb54b8378c1", + "packages/artplayer/src/style/info.less": "fa56d1b8c8936218e581b2426026e4ba85cd5fea20d045c4f69aca96be4059be", + "packages/artplayer/src/style/inject.ts": "9cddbe51b5de0da74f27c045ab982b509c3854cc6b81eeb02a6b974914760a4d", + "packages/artplayer/src/style/layers.less": "9653c581190bb22d60a706109819cd010908898740701c9526957b5682991c5f", + "packages/artplayer/src/style/loading.less": "185b0f05274196ba71fdb1d088b55af568f3342a495490c99c3f0e058a40659e", + "packages/artplayer/src/style/mask.less": "d1239a171b71ea6184cb4aee6660d74d6ffc0c48f7c47c3cf5fbe52d2e93ac92", + "packages/artplayer/src/style/mini.less": "c8537df19c1d615419a8396db5846b4de05f61e61df8c0ed89613f0051b81e38", + "packages/artplayer/src/style/mixins.less": "c6be95aa682f266749fe37cb89796fbec6488abc537174f817da79bdac6e00b5", + "packages/artplayer/src/style/mobile.less": "ff3f64fca5d2dd7ddd50385d88d9b2fa1a645909488ab7a0978ba4f1670b7c0e", + "packages/artplayer/src/style/notice.less": "72a935c0effc557a9d7ab3baccb2c3b77fc3a1783450b4e3178a40a5325fe369", + "packages/artplayer/src/style/plugins.less": "589d05e12a62e04fe848b36ba748433d23f0b909a04e861b1d6737f2799be183", + "packages/artplayer/src/style/poster.less": "36b38fe138f8c9537ff4e93f7ec4f2dbdba1ec41d243d741ddf1da7c6581e546", + "packages/artplayer/src/style/progress.less": "59b9d95d49dbcb1be40752d7086239b6de5925b0574da231199d999e22ff4990", + "packages/artplayer/src/style/selector.less": "295012ba379a7e957a24476616a0c3623d6a06e82ebbdaa45b916dd6412d7f4f", + "packages/artplayer/src/style/setting.less": "743837b3c84fc5fee40120598bd484c10bd4202b371002709c269a700919dda2", + "packages/artplayer/src/style/subtitle.less": "273cacb63ec0214ba434dcf19a4a455dbbdd408fb2d1749de4878804c1371e41", + "packages/artplayer/src/style/variables.less": "703739b2bdfc77bfde063d8788ef6b6a55b8730764baae8e7d755b7c54d8ecc7", + "packages/artplayer/src/style/video.less": "b89c6f6e27592d49825c68c9ab98d46e81cb1e5add855863f89d19637f98e35f", + "packages/artplayer/src/style/volume.less": "a3954794a9478d3872202b90d349c873cbb51639dcd7d1e3d73a55ce635fcd99", + "packages/artplayer/src/subtitle/index.ts": "b4ead680dc82fa47c53d1ec7e5fb8bf94abbf55730d5d1130ad8d544cb42adc8", + "packages/artplayer/src/subtitle/parse.ts": "7db540c5edb1d2312eed82757fd15a7ce6a28996ba20d0087e56730f21dede74", + "packages/artplayer/src/subtitle/render.ts": "96493fc35680af635a8db225a8bf002208df79ed48b1d4ee6cc73587543add5c", + "packages/artplayer/src/subtitle/request.ts": "543c964571bd5ab984bc1adc9f64a8917dd134ed2892ad10b30ed9c859f34119", + "packages/artplayer/src/subtitle/state.ts": "9f79b982d66747170bc39bdaf99b65676310965f23da62a4dec15547c756a56b", + "packages/artplayer/src/subtitle/track.ts": "707f4c43af4ebf4b87521f6f577168460e739274d0cec28b9efe5704d2540d18", + "packages/artplayer/src/subtitle/types.ts": "e56db829d7588f3a5dfafd6e8377f93f0892cfe442710be3740e1136812dd2bd", + "packages/artplayer/src/template/html.ts": "351c472bfd01fa5ba1a4e347ed31bd5faaf823d9b4c5cab1ce8c651e3b175021", + "packages/artplayer/src/template/nodes.ts": "1572746a636647e4d313cc8752d3a110ff81fddb390ad7b0feb6a0db0d42b9d4", + "packages/artplayer/src/template/types.ts": "23f67e78ee43f9ad9099c94f28e51c6113b167603ffbbcf2d6ca2b68cc40b803", + "packages/artplayer/src/template.ts": "05c1499adc5dce27addf5761bec58d803f526d9b5b62c367c631e4cf2991391d", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/utils/compatibility.js": "51290838ef62be8e4251f4db8ecdd45a626cecd8c732e4e53a1c55df8d454a13", + "packages/artplayer/src/utils/component.ts": "d04a66213406ae3223326c2d470363e197dd1540519caa632f9d06378af989cc", + "packages/artplayer/src/utils/dom.js": "fd6148ff85ee97607de54652f0f1e4cb5158f628a2d0951f1946a21f2b4e0008", + "packages/artplayer/src/utils/emitter.ts": "26a93d3ff35b53e71a5f3bb22c252a854559d8151ede50a66a28d9eefae6c008", + "packages/artplayer/src/utils/error.ts": "ba303c7d4e4228919088f9d608fa364596f5853ee646eda2008deee354866f38", + "packages/artplayer/src/utils/file.ts": "ea71d7fc0e818d473bf5a596211ba9d571e4febdf1878014eadefa8d0a98d4cc", + "packages/artplayer/src/utils/format.ts": "891df5b7542b713aef46bf2b93924f42e68eee574afd802db3e6c62ff2655ede", + "packages/artplayer/src/utils/index.ts": "5211af833dddb2937d25dcc772740d62f9d5c5039ce5505bffff0796d4afd756", + "packages/artplayer/src/utils/property.ts": "c737d4582a4382f4038d12dafdf8b43418e508c9b8b859b2f0cc17c20f370343", + "packages/artplayer/src/utils/subtitle.ts": "f058851d11a418e321a8a498472b67fa535fec2c7b5d3df739b6b4f263d00337", + "packages/artplayer/src/utils/time.ts": "b8ce3d50865f6c343e8e3ce9f5c87de565a87b4e9fbcbccbe7030e30e80b93fe" + }, + "tests": { + "test/auto-playback.test.js": "2d61bffa99bf7acab58f263fb60cb50fef8b1d450d3ea22a4f1eef8066b162a0", + "test/browser/auto-playback.spec.js": "39d9258fb808ef42dfbd38836572335a5c759d99cc1b0ecc1b635a2d7cb3b0fe", + "test/browser/builtin-layers.spec.js": "4efa0ebe413cbf0ca9b06074ce73ead337136bc477c4f8fda6665be0504a31eb", + "test/browser/chapter.spec.js": "d1332c5264bea179d4fd4ec3274eb0db28340bffbda3ffd37d80fc6fb636dca2", + "test/browser/components.spec.js": "2be381b052b69baa3b4ae9cf2582593b9d611158e709e056aaa5df3cf969bef4", + "test/browser/declarations.spec.js": "7340de5f8e34f71cf8d7dbf5f428c3e1c20677a44cc5f561199c9e55d21dc44a", + "test/browser/display-mini.spec.js": "eecb351ef6c1b4d5a96c682e9d9b4507260473b10159bad0b918af277c2c58f3", + "test/browser/display-native.spec.js": "557f0613a23c8da819d55a62acd5ae47340f16cfb4f91bb9778f7984b8887e49", + "test/browser/display-orientation.spec.js": "754bb231c4ef3f634235269aed0588d118ccc9bcbb1bd734f4356cd4222119a8", + "test/browser/display-pip-webkit.spec.js": "8169cee87dad40ecc4b1c1b0dbf2a6667e0b54197f889cfb4f8b3044cdd703cf", + "test/browser/display-pip.spec.js": "562f25b2e27c4644981d5e95f54bdc1a887ec051a10fe5e91ccad3ae22c8238d", + "test/browser/display-sizing.spec.js": "04912463007d1fa53a5d5048a88e7fcb9c0238a4e20e215e11a3dfe381ad74da", + "test/browser/display-video-fullscreen.spec.js": "961b21a5965d230e8ab8d7cdf7c72914c8c5f9526408a83ff0552cc263225ccb", + "test/browser/display-web.spec.js": "50bdbbb4988e47e34a4cbb08184a68b0000e2dcf34bf60192267648045b3aca0", + "test/browser/emitter.spec.js": "abf5a850835d1a5580d611a0777c0cdf225a6aa796a63b58096f8646007e5870", + "test/browser/event-scheduling.spec.js": "4ebd5dab23ca8e49580bd1dc3234e612cbae36b735c7c9401d168059eae11c5c", + "test/browser/fast-forward.spec.js": "5b884fae1cd48cb592c2004a8149890aed4741ac0a92b1e415e47b94411bb368", + "test/browser/fixtures.js": "313414b8958eb5b03a2da8595fa0bbf6bfdc01484373898c6cb7179545df175d", + "test/browser/gesture.spec.js": "9301a91220e5cccf1023918580111bf5287f811a51c0b51e7ed71797cb018575", + "test/browser/global-events.spec.js": "67ef2bc32419f17bb10ff40f7d9e542c110f2202028e5a17d58780e2cc6cf5f3", + "test/browser/hotkey.spec.js": "a6565949f25d702aeb33ef8ebbddf2ed995d67f09a47c7bfaa20010da34dfa1c", + "test/browser/input-closeout.spec.js": "6ede540965e404c58cf71a23dabb6be9ab2b107e75d5937e6d63b11dbf11cf98", + "test/browser/lifecycle.spec.js": "7726535769bdf01a57d15d562bad9b3bb2cce0d979b7b0def6cbcf77bd72f453", + "test/browser/listener-registry.spec.js": "54c40eebcd818342e92f875cb639d31d1fa0a0fc95897de2cbfbbd4df793ac94", + "test/browser/media/declaration-cues.vtt": "5d149d4e641ce41cbb83376835c03daf1fb89f3b9f568fa59e064d51e2b57704", + "test/browser/media/pattern.mp4": "0ad1d7ad286aec6e0fa9e27fc1e487e7277df2e603e30040fb942365763d0233", + "test/browser/media/pattern.webm": "9d3c2b3dec9581a599de2d6732992ef7846790e0d1368e6e131bd339b39e984f", + "test/browser/media/thumbnail-grid.svg": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "test/browser/media-events.spec.js": "3f5c719facfb97498e6f254117fc4d7d2d91e7f0d53efeab6d877e107dac174b", + "test/browser/media-hosts.spec.js": "543e974f5bb89116a688defb2c1e4afdc72bb6cf4b1bf9838d0e837e661d7845", + "test/browser/notice.spec.js": "2b57c1307aace558aae0c4d8d4434a473780eb9d70c6cf62962147f476bdc94b", + "test/browser/options.spec.js": "17733db5056f04f829ecaa925b021d339d0f6f6960cfb8bd277c68cf8c4e119a", + "test/browser/playback-properties.spec.js": "14e0774bf272cca78d203fef9c343b9b2eac5c30ffbe5c354b00640e1cd9627c", + "test/browser/playback.spec.js": "5cc5df6f3968f3e834a6b2bc2c76c3c1c4ec5e7bda5ee3e99aa7394d24ac7e18", + "test/browser/player.html": "4037c6eadc5da176f9dd67b2b517acb06c8cb2246c841316df26c660e55584b4", + "test/browser/plugins.spec.js": "526c58db1ae2080cf76a13b542e502b4847b23f07e8cd012f40129dda3358a00", + "test/browser/pointer-events.spec.js": "fa789898942d6eeffcb1f8867af46abcdb1dc8a515470ffdb18e89e8fafc4985", + "test/browser/progress-quality.spec.js": "824596e3f0f1a7d8304ca7fed38de4f00b2f967eb87fd48346ad714fbb2e280f", + "test/browser/prompt-components.spec.js": "2513a31306bb17b713aca2f9bc44f045ce34ac547482b4507955b0f1f14484ed", + "test/browser/README.md": "1d0df52c26a7d817ed8655b1e57855dab6a603c5c9cf69c1b0718ebf69213ed7", + "test/browser/resource-scope.spec.js": "0196bd9943c1ce2f6560f87156cd0de47606579c1a736bd46d4943179a121d3f", + "test/browser/screenshot.spec.js": "a2b49fbd8616533fc351892c1f6687d588d2bc9350fda4be5475decb97d77a0e", + "test/browser/server.mjs": "2b36e65ed9248f334b6dfb2d54a22cf5a26b3b531d7eb1f93392e38bb14d10cc", + "test/browser/setting-interaction.spec.js": "030266515b16e1bf8677b30e7748f6a6451b10eba541c5ead9a54b5e57bb05b6", + "test/browser/setting-ownership.spec.js": "ef345200701ef826faa7c3aca564726bc9fad6587cc0af091c579d78ee7f3b4e", + "test/browser/setting-update.spec.js": "2f61a9790ebbdb0f3d86adfc2f9bce5e789806af2517403a47d5c02f1eddd1b1", + "test/browser/setting.spec.js": "19acfd07cb6316381e3bce61e0ae284303aeafc8fca14e1657d73568553c5bb6", + "test/browser/source.spec.js": "8bbd3b0eba2dda89f8b5f484468e916a34e2e53319f3ed3106116db51436ffd1", + "test/browser/subtitle-lifecycle.spec.js": "ba91719ccdc9e539aee252d80deaba622fd6e5cb30cdd74697658af1e49dfd58", + "test/browser/template-resources.spec.js": "993ce9876ae9d49f291af4173ffa34276f9b8972828e8d42b8789c5ee512ac6d", + "test/browser/thumbnails.spec.js": "bc00e6fe6eb6987bd36193f26c69e2377249b53f41dfc1474dd44d6e833a2c09", + "test/browser/utils.spec.js": "e7f1739938791a6d19ec2cdf544f57c69ad7caaaa6f379128b3676d73d8611b1", + "test/build-docs.test.js": "4382e9f445118ac02984425673c84b0678f598cc03ac418ec2bf3b0b2bad23d2", + "test/builtin-layers.test.js": "0ff767aadbfc7c142dc03e64891dd000b651e812509488f474dcf01ca5d0df05", + "test/chapter.test.js": "59dc68c79d13c89c59c6134af58bf6bc0f6149d1a8f14b3c7934c8f3051606b8", + "test/component-resources.test.js": "70a9520d48cf52fe38c53b5cdff33a03fa860ed25c1b2af870aae5d0d2db63d4", + "test/contracts/emitter.js": "243e3b3b41c14b78cc6e6990e983afacbdab92d0590584124ab5166edf5ddad0", + "test/core-vendor.test.js": "394e17fac91bc3110a284609b08d55c9993ce32e701b34ed8476cf3a1eba5eb6", + "test/dash-control.test.js": "2a123bbd93659c053ab206f09ab489d04380b222885179203c0bfb401590b35d", + "test/display-mini.test.js": "7e3d1a88dc0145c49b68c91d75a6f2444dc224fc73ba6921712bc1647d2582c1", + "test/display-native.test.js": "416738577500ac34e832fb43c9b17b84c4b39ffbd8f2c745fb9e48a7b2525ed6", + "test/display-orientation.test.js": "d9d789962f92aac1cd38af782bd24adffd17d3650ea2a431967af891d5249254", + "test/display-pip.test.js": "aba0510a9afd53b689c266a849449d8256d94a5fe9f823832f88b8798c75db5f", + "test/display-sizing.test.js": "e6ce3dcfa1d96f9200cf9ab6c08f001e032f6d973d2b47c6792e5c18ed64f7fc", + "test/display-video-fullscreen.test.js": "2310d4434e37af92083ac4bba1cf8668f5d440cad2ad2fb1a51168771b4b6d60", + "test/esm.test.js": "324576fff9291ca27a8ccd5137dcda1f85e02709117c285890c44d42743af389", + "test/event-scheduling.test.js": "65faab59cef6223140808bc310871853610fe3944ea0ab882173037726ddc258", + "test/fast-forward.test.js": "81172dc0fadbf62cf88904fb7a54d131f848602a0fdfe3be93a37fcf4ca7b389", + "test/gesture.test.js": "77235aa134d380a2bb39e572e41bd33b02f6c86ebe72426e55da4b00a5701f4e", + "test/global-events.test.js": "12494982e1846b6d6f6062eb209b7c1218c87a8b2ffb8342b5515ed91da2d337", + "test/helpers/load.js": "78b16024851fa7c55ff34bbe1bdfac8d8c444b7d0d2ff1421dbd6e9b6629a0f1", + "test/helpers/playback.js": "04cc009a6231295d0ff1c4fde347df8878dc355cf2e74efe48582d359d2e2fd6", + "test/helpers.test.js": "4dc1ea43a94ee0a790ec73329bdb35311fceff9c54aa7e3c7dad1046f1f504f5", + "test/hotkey.test.js": "b647a4552ce43591f532d6295bf6d2034d7c301a2a9dae88cdb1b77e651ad5b5", + "test/i18n.test.js": "0a4c1904195f49520bde50b9e9db92694eff05a3d6eaeb62a38225a38653585e", + "test/instance-lifecycle.test.js": "710a41549954b3812ed7193a3515d9a4c8f354816a96657f3ef03ae32599f0ae", + "test/listener-registry.test.js": "07dcdb1945e530a3928b28a3758d22eca0db70bf4a00dd7e0527a56ef407c133", + "test/media-events.test.js": "498505a80b2de35408f5c603b4a8877eb492a2ff818a854d8cc1ca9b2af2135c", + "test/media-hosts.test.js": "6bca83248d83f01dda3e7997e3d93faf193e8b57ac7b77c3232c6ef504b4774e", + "test/notice.test.js": "c8622608041aac4ba4dbbc5362a4513ba279456e04d49755926f7f26efdca66d", + "test/options.test.js": "88f2473c99ecaa62a509a06a9a3ce7a1ec94dea2e1c5e200feb128bd967b0bf3", + "test/package/known-types.json": "838be763ffcdc34f803c5bb0599804ff73bc5e8dbb7c5f26259c1a3a5f54386f", + "test/package/README.md": "b920234abdb0d75e7c7111a24328989030a0e826120555232d7ab1223af8791f", + "test/package/runtime.cjs": "51107b04a5b92679f909369e7fc6e0ba33cc2a10e862c06d0249e32b722c144c", + "test/package-check.test.js": "8c61a40956ce9ad8bd611c3e56980ebafdaa9eecb242b4b398b154bb6cecf76c", + "test/playback-properties.test.js": "834b6b70d876dfc24d23a9bd46bbf18f5347d0dea359971887ab2ededbaae78f", + "test/playback.test.js": "af40485704227e0a9ec50cf4ea1ddbd2ff964288aabac31f55575c17cf726b86", + "test/plugins.test.js": "e79015cf10da6f80d59d42cf58ee8a75908847d55aaa549346b1a9c8e7551740", + "test/pointer-events.test.js": "8eccc6b72f025183cb93f1bbc2c03e42a98e1a3bdf6c03e8609c1b2fc9c2ea2d", + "test/progress.test.js": "3f6472aec1b2534d894d05477b19d77404c064e3d448531a005786f75a947b2f", + "test/prompt-components.test.js": "ece7c6cd964fdc92f36416fba1a6898ce111527127fe9793ac3b2978993b2576", + "test/public-behavior.test.js": "a69ef36fcfb4b8408ef4ad10d9a062c07508c35517bfd4dbd902c8c9a1f51864", + "test/README.md": "ebf53d92cdc1ecf3db04169a70821683529caf55b69776630dc8d31febdf7cc7", + "test/resource-scope.test.js": "4da8b8acc1802b63e6797f6a58e6f5f93737a11e0632c24d5a6b1a94d96d931c", + "test/screenshot.test.js": "740e879c9159c75e62240d37e3a327facb228f54b0b531e9da375c1f184abb24", + "test/setting-layout.test.js": "a7da46075bd478182559b9af4817b128eb9f9c219b6032d77fd437370f2a3563", + "test/setting-model.test.js": "8b3914c1c756ec9d25fb4cccd592071fe95e4f85816b59c172e6e32761cc163e", + "test/setting-resources.test.js": "1f3749da962e9101be07ebe3e633adfb6b56767a3ca6b64bb349563f276eb139", + "test/source.test.js": "7a388e9bb9389212b2fe3d859a1f3ba04a585490c1dc1fc2020bb8bd3e011e7d", + "test/ssr.test.js": "dcb99a02c9a7fcf8943c7621846b75a5f803b786a80bf6db40c12f0bc0f85ea8", + "test/subtitle.test.js": "b4dd24d74fe3b37ea80bed15aebb07d6d477c66db4d3d3a93dfdf6592ed2abb5", + "test/template-resources.test.js": "24ae3141bb7463d440a88b3079e024241ac0dd2cc9a4a22beb5973b08f4b137b", + "test/thumbnails.test.js": "367882200a3898cce718379f95bb80706d9d5ee06e8d8e3624acada118ccc41c", + "test/toolchain.test.js": "7c15579e37f531e4d762dda05622a9c8047ec5e8f22e25a46ad95f69e0026829", + "test/types/auto-playback.ts": "3af10afc38be6eb0d6a8c9f82f76b6b046ab0b0439a22c1318fab5557a2157e4", + "test/types/browser.ts": "b4c67febf37bdb2295f9ee178c2b6969788f3693c215ccf4ae8b85dfb6a98439", + "test/types/builtin-layers.ts": "4bf0c661011e15bb3f620e0e4bf7b51ca381c420dda261fcd59988cafd2e53c8", + "test/types/chapter-exports.ts": "165bc3ea422bd0dd63b143fef0b73916cf33548aa839ddf4a1ddab500877c04a", + "test/types/chapter-options.ts": "8ae16ff704befdcf5303012d15d108bad4aa7dab4d62da9c02cff4776680fe60", + "test/types/commonjs.cts": "4096c569923fe5646d4787c11fe421884b0c592682d6c585a73745ebf5ef15b1", + "test/types/components.ts": "e705f0c3efdf531e0eb4a5f733332c141e7bddf2450024cd71ea67bb3efc5b24", + "test/types/declaration-inputs.ts": "24279eec4ed375febc6f791cf40913d290ec8b62f2a67a62288476b14b0bedfe", + "test/types/declaration-legacy.ts": "1ee51cbcbcde133d4df17af424b1fc478bdf45d673db5981dd2d1e67b54e9b32", + "test/types/display-mini.ts": "e4b0e053681eda6d4db97a6a84781149146d37a3f51ee67d5c4aad281072fa65", + "test/types/display-orientation.ts": "4c93125b488e73f568c7af3a267dec187599da054599c9e50d95e4d827e9fd34", + "test/types/display-pip.ts": "7c12d5e92730a93cc803b78faf9a856fd34d8ccdc4d85e057571a048fd8ae978", + "test/types/display-sizing.ts": "cd0b79fb7c53516dd86ecc6566b4969793633bcf7ffa0126c48788a3f7c615d8", + "test/types/display-web.ts": "801d5b42efd879ff1b65f52cbed4a355b52cf2327b5a1ba9320c62935026777e", + "test/types/emitter-source.ts": "d6111dc541deabbe952446a6bbd99bfe2ec3dc23c097d042cb08ddc7d5a0cfb8", + "test/types/events-source.ts": "504d33f54d995c245ea759a08ec55085f38f22707c39e45d26ddfdce261911f5", + "test/types/fast-forward.ts": "bd724069d82a78b8f9264f73ac3d7862f27b2bb161936a49763812e5d5966246", + "test/types/gesture.ts": "3fb8fd3d895738443bedab2c00b1afda1009fcee5695555d25b73b9bcea61d8f", + "test/types/hotkey.ts": "bc08aa59a8359a86e49cc95f880ae09d5c90a501d4d0ddae7d7467e90b042ef7", + "test/types/known-diagnostics.json": "8d3200355e82501beb0891eb9cbb5fe90919ccc1e436a09abe5cb62e707ce266", + "test/types/language-value.ts": "84352425836a03681a5578d277bdbd02131f0079cce778788ecbb256d72eed68", + "test/types/media-events.ts": "7c7869877de7d4f8b74fd3c05e703345afd90ed47c581eb65a655fb7dc8b651e", + "test/types/media-hosts.ts": "d5ef7166683bed51a2e4395d03315ea5bcbfb4e0c93b942961febe1a45d55573", + "test/types/notice.ts": "f896ea15c1dc1f71e7018e3a00e7276f415b9ff58fb6058d8767cac9438a047a", + "test/types/options-source.ts": "1bb15ec10dc92af1e5d2a32b70e76961b314aa559c7971c31c2a4b1c75fabf75", + "test/types/playback-properties.ts": "ac71544fcd9a16f6a5ef00566b47a26daf7128dbb92d9ccefff1f3451619f4a4", + "test/types/playback-public.ts": "368fda3fd82c35437fac9212ac736e7b9a35cd283405e6c56ea9e15e30a16ff3", + "test/types/plugins-public.ts": "bd06fa0f883fc22da8efe34e9a20329fb096954595741d1a559b0ddb6a54064f", + "test/types/plugins-source.ts": "6d3410d9000eb94128374d021e559fd5963bfb76625f0ffdf54dee389c3f8390", + "test/types/prompt-components.ts": "ee577d2d7a148767c929131d641bfbadf5e42c2aa178451a704bef0d815e67fa", + "test/types/public.ts": "67d63abebd3ba678707828a93d8f8826a9756532cfb9044f2c777dacc9c3eb84", + "test/types/resource-scope.ts": "a8c056914e8529c871891ed672030248d359a19f8571a5ac5a5f18952ea5def0", + "test/types/screenshot.ts": "f329d9b897e9e9e4190ebc6ededfe55ccd0bebf796683615af103c19cf6b3947", + "test/types/setting-manager.ts": "27e3687a89909ea6f97aa842347cb8fbcd6f8ce5cf779a24d5dabad3eff8dc5c", + "test/types/setting-model.ts": "ba024ffeae26428d06f07f98f62f211db94ef8b259251f9f424a4203f1187c7b", + "test/types/source.ts": "0cd6c84c3a7a107c8ece4b2594a192b8a25ef2190dfb21f732c2f6704446e708", + "test/types/subtitle-manager.ts": "c813fbb8f87efb00683d35ef872378c3801ec840572b5dc639a7adf9c1a5ba3b", + "test/types/template-resources.ts": "a2b77f6ee6d9b03d8b1d8040def11808bc01178473e511e64475828c2f9de747", + "test/types/thumbnails.ts": "2b01c655ad30be3e9ef6732d13f85dbdf32cf71c734d63537bdb0f82ac69350c", + "test/types/utils-source.ts": "764b8d18ec7fd575f44d9d86add339d792c6ee084656d9361a1dbbd6131b446c", + "test/types.plugin.test.ts": "d698e283a6e636003e3149523094f4e2fb307b51dffdc0ce66df76b3bf558ed4", + "test/types.test.ts": "445de50bf829ae58b3904a16a4a26a05454c16a76c72403985755d16923065e4", + "test/utils.test.js": "ad43c90a5fa2109380e0c5164833722e6d3c2d9c3c9e439ce16030eccc7983a3", + "test/utils.test.ts": "f77a28984a1168f1bbf52566ec43a34677c37cd77e57ce51ae40e93ad7cf30b4", + "package.json": "81906d9bd78bade6a45b391b12d3f4407807aff9c6170e235b3c3ba3e2cf0bd3", + "playwright.config.js": "df2384f5626252ec933725867e400ec22eb92bc5e6f04873059b32decf2f2d56" + }, + "ci": { + "command": "yarn ci:check", + "passed": 421, + "unit": 392, + "engineering": 4, + "baseline": 25, + "strictSourceFiles": 207, + "logSha256": "f8585e2156a21f76df7502b7075002153b6864280f50cc7efa0ad76ba7c0d028" + }, + "packageOutput": "refactor/.cache/packages/run-bmh0dN", + "packages": [ + { + "name": "artplayer", + "version": "5.4.1", + "archive": "artplayer.tgz", + "sha256": "b1e53e5a4560fea6018b2e3972986597f7b6055a8e6252f8a210eaafe888f205", + "files": { + "package/ARCHITECTURE.md": "d53537750cfa82818e2309eaeeac62c436197bffe1292f4f4f30f0decede37fc", + "package/README.md": "1e185e65f67fc2081b4182bbc6c4558ea05b6e3fa3acc5dd0c3ac7df1d542b09", + "package/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7", + "package/dist/artplayer.js": "b9d544cd88ca676085facc6a67d6da744b9f28f4ff4622fd6beab1cd9444e659", + "package/dist/artplayer.legacy.js": "78bc02363b7c959c533acbea89f1220538b2bccaad6a5dd4bbefb4586eff4d49", + "package/dist/artplayer.mjs": "18e7ce286e53a486f226659aa5798a447ce4f43c704799b97ad0f87324a14830", + "package/dist/i18n/ar.js": "5885c469efc9f07aafd6a4aa6698edae2c2683f42497ebbe15374130f9b6e2c7", + "package/dist/i18n/ar.mjs": "a275cf39ae2317ea1cea73b65ba5451a909b34a881d35920391cef2ff0d6a86f", + "package/dist/i18n/cs.js": "5adef10fadb219948eb5e58e204207ca0afdd2dd941a08d9455fd302ef2447cc", + "package/dist/i18n/cs.mjs": "2d274b61c2be9a472a3cc19dfa775e6209867f8d1d5a9116923f075446f47969", + "package/dist/i18n/es.js": "4c6662edce1398d0fe285978df83b271cce23e4f24e0e6a9d24a5b8a6845839b", + "package/dist/i18n/es.mjs": "09c0806a979feb4ae0e3ff32dbee9fd435847d3a66f80b6768ff69ab63289696", + "package/dist/i18n/fa.js": "db37cade9454df0b829c514e088d4d9175199faaff2b4a7838e6a401741131fe", + "package/dist/i18n/fa.mjs": "83290582155ee2a7a08a8c9cf8c2903545e78260e81a2a091092f3fbe61b4dd0", + "package/dist/i18n/fr.js": "54eee11fdf245e9882cb1f440f8909ccb8112f2e10722447cb313cab4752abea", + "package/dist/i18n/fr.mjs": "621844a04365da3d9e5d225d64e233d322cb9fd9c1ffcc2db77e5d7e0e78ea8e", + "package/dist/i18n/id.js": "5d4ee91a123c417b5b2e84890d85f416444389bdcd12c40d49073e1061796463", + "package/dist/i18n/id.mjs": "ffca08de9515704ef160dd902534df4b4113ff3f62b37f70330264d27daf5c34", + "package/dist/i18n/pl.js": "47e0d39623896436722439c758488ec660752c56a0294375bf0fce4f3b2aa27b", + "package/dist/i18n/pl.mjs": "05fbb3b2d09b44b5d3a237ea35a1f6865d45c2985e32b517dec4a00670cddebc", + "package/dist/i18n/ru.js": "3af3b15b1554579352b9b1ecfc8ac27abb584a5af9bcc7a8369a813c55df8834", + "package/dist/i18n/ru.mjs": "12281df03fc45c40ab8ad2a7dd8bbbab35f086dadd7e51f35e27826fff16e1ce", + "package/dist/i18n/tr.js": "0f8da88d4f770d9ec2e83311bbd6cc6ecfc0b2bbb3997f8db8eea8b795746967", + "package/dist/i18n/tr.mjs": "ea533927a7f32b3124177e87d9d5adbd279dc80efca7b11ad94696b3b47f7e94", + "package/dist/i18n/vi.js": "e3302f5c90f3e7df4bf8667c17598d0e46b66b31aab0d94fa70f3e617b5277c0", + "package/dist/i18n/vi.mjs": "f7a0ce8d821bff93354be31922a73be854a685e14170e8875cd5375f155e8737", + "package/dist/i18n/zh-tw.js": "13446c81dccf57e6b5d2be0a55b8ef6a668c6b8005ef4a497439557d6ccb16ec", + "package/dist/i18n/zh-tw.mjs": "730ae246aef8cffb34d7ba3b48aefab38fa812cf84ea7ebbd827f8639ee7eba7", + "package/package.json": "38fa5a41fe142c34ba52ce4ecd7cc81f25a7aba5adbe9e8fab843caedbddc15c", + "package/types/COMPATIBILITY.md": "72f619eb708e18040d12e0fbc5ce79f80bb22967687fa0d5afae6f2c6eae6d00", + "package/types/README.md": "93438f6009fc8017147ff4293e78849c102acce9aecc3d196ff135151081ff27", + "package/types/artplayer.d.cts": "a40ac7abd689b270e95eb0c3b70d67e1897b422d3d85d68f59173936bf80c332", + "package/types/artplayer.d.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "package/types/artplayer.d.ts": "b57d9ac0a6f7a0215288ea286fedaf73043ac15557a3d82fc4b905f6d006f092", + "package/types/component.d.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "package/types/config.d.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "package/types/cssVar.d.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "package/types/emitter.d.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "package/types/events.d.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "package/types/i18n.d.ts": "3e14759caf71f97f01650839248c8737c42d2c2979dabc43ad92b724da648708", + "package/types/icons.d.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "package/types/language.d.cts": "1c9e0c47fae3c2d68c3e144d95a55071318a03bb31554dd049109efd3d0f95a4", + "package/types/language.d.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "package/types/legacy/language.d.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "package/types/option.d.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "package/types/playback.d.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "package/types/player.d.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "package/types/plugin.d.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "package/types/quality.d.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "package/types/setting.d.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "package/types/subtitle.d.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "package/types/template.d.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "package/types/utils.d.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6" + } + }, + { + "name": "artplayer-plugin-chapter", + "version": "1.1.0", + "archive": "artplayer-plugin-chapter.tgz", + "sha256": "96da0e5b2e9ddaad8945b3f1284bcadafaac83bc9810ca0f01dca101b29991e8", + "files": { + "package/ARCHITECTURE.md": "20743bad87a174b0450e0d876b6aa6b2a9f47df296d479511ce7cc9298fdb57c", + "package/README.md": "b95400ff3d525621a15268bb56a2d353aacaaadefde7e735d7abd91a34edd96f", + "package/dist/artplayer-plugin-chapter.js": "6ac3dfe28f46084ac7caedd571b1a97dcee3cf9d708112f1b8bbd6566e1dc5c5", + "package/dist/artplayer-plugin-chapter.legacy.js": "6d9bff885412169e701670961aa00c2e46c4b42c9b9647ff4e6d198777d2a359", + "package/dist/artplayer-plugin-chapter.mjs": "26415cecab2c0198c566cef0232e20123413782d5bad7534a32939b3298617af", + "package/package.json": "24eec6907b3218439189adab6af3f932c1497c47c2d41209311c01042b07fd4f", + "package/types/artplayer-plugin-chapter.d.cts": "4f07514b37453cd6cea8e5aa28fa018ff31738e0d423c11a3b5eccd50ed30bcc", + "package/types/artplayer-plugin-chapter.d.mts": "610179754db36276e161a07bccf4eaba8b4480f053e716a2bcc5a1574871a171", + "package/types/artplayer-plugin-chapter.d.ts": "581aa2862e709601c87a23585f54a969ebd350be56a7469a31ff53f1311b578d" + } + } + ], + "runtime": [ + "DIST.cjs", + "DIST.cjs-legacy", + "DIST.esm", + "DIST.esm-default-only", + "DIST.esm-legacy", + "DIST.global-core", + "DIST.amd-core", + "DIST.global-core-legacy", + "DIST.amd-core-legacy", + "DIST.global-chapter", + "DIST.amd-chapter", + "DIST.global-chapter-legacy", + "DIST.amd-chapter-legacy", + "SSR.import-template", + "SSR.constructor-browser-only", + "DIST.i18n-cjs-esm-global", + "DIST.exports-boundary", + "DIST.direct-esm-file", + "EVENT.lazy-registry", + "EVENT.symbol-number-channels", + "EVENT.context-removal", + "EVENT.once-throw-consumed", + "EVENT.chain-context-arguments", + "EVENT.once-reentry", + "EVENT.dispatch-snapshot", + "EVENT.off-original-once", + "EVENT.throw-propagation" + ], + "types": [ + { + "compiler": "5.9.3", + "mode": "node10-commonjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-cjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "bundler-esm", + "diagnostics": [] + }, + { + "compiler": "4.3.5", + "mode": "node10-commonjs", + "diagnostics": [] + }, + { + "compiler": "5.9.3", + "mode": "nodenext-esm", + "diagnostics": [] + } + ], + "i18n": { + "package/dist/i18n/ar.js": "5885c469efc9f07aafd6a4aa6698edae2c2683f42497ebbe15374130f9b6e2c7", + "package/dist/i18n/ar.mjs": "a275cf39ae2317ea1cea73b65ba5451a909b34a881d35920391cef2ff0d6a86f", + "package/dist/i18n/cs.js": "5adef10fadb219948eb5e58e204207ca0afdd2dd941a08d9455fd302ef2447cc", + "package/dist/i18n/cs.mjs": "2d274b61c2be9a472a3cc19dfa775e6209867f8d1d5a9116923f075446f47969", + "package/dist/i18n/es.js": "4c6662edce1398d0fe285978df83b271cce23e4f24e0e6a9d24a5b8a6845839b", + "package/dist/i18n/es.mjs": "09c0806a979feb4ae0e3ff32dbee9fd435847d3a66f80b6768ff69ab63289696", + "package/dist/i18n/fa.js": "db37cade9454df0b829c514e088d4d9175199faaff2b4a7838e6a401741131fe", + "package/dist/i18n/fa.mjs": "83290582155ee2a7a08a8c9cf8c2903545e78260e81a2a091092f3fbe61b4dd0", + "package/dist/i18n/fr.js": "54eee11fdf245e9882cb1f440f8909ccb8112f2e10722447cb313cab4752abea", + "package/dist/i18n/fr.mjs": "621844a04365da3d9e5d225d64e233d322cb9fd9c1ffcc2db77e5d7e0e78ea8e", + "package/dist/i18n/id.js": "5d4ee91a123c417b5b2e84890d85f416444389bdcd12c40d49073e1061796463", + "package/dist/i18n/id.mjs": "ffca08de9515704ef160dd902534df4b4113ff3f62b37f70330264d27daf5c34", + "package/dist/i18n/pl.js": "47e0d39623896436722439c758488ec660752c56a0294375bf0fce4f3b2aa27b", + "package/dist/i18n/pl.mjs": "05fbb3b2d09b44b5d3a237ea35a1f6865d45c2985e32b517dec4a00670cddebc", + "package/dist/i18n/ru.js": "3af3b15b1554579352b9b1ecfc8ac27abb584a5af9bcc7a8369a813c55df8834", + "package/dist/i18n/ru.mjs": "12281df03fc45c40ab8ad2a7dd8bbbab35f086dadd7e51f35e27826fff16e1ce", + "package/dist/i18n/tr.js": "0f8da88d4f770d9ec2e83311bbd6cc6ecfc0b2bbb3997f8db8eea8b795746967", + "package/dist/i18n/tr.mjs": "ea533927a7f32b3124177e87d9d5adbd279dc80efca7b11ad94696b3b47f7e94", + "package/dist/i18n/vi.js": "e3302f5c90f3e7df4bf8667c17598d0e46b66b31aab0d94fa70f3e617b5277c0", + "package/dist/i18n/vi.mjs": "f7a0ce8d821bff93354be31922a73be854a685e14170e8875cd5375f155e8737", + "package/dist/i18n/zh-tw.js": "13446c81dccf57e6b5d2be0a55b8ef6a668c6b8005ef4a497439557d6ccb16ec", + "package/dist/i18n/zh-tw.mjs": "730ae246aef8cffb34d7ba3b48aefab38fa812cf84ea7ebbd827f8639ee7eba7" + }, + "vendors": { + "sources": [ + { + "file": "refactor/baselines/core-vendor/screenfull-6.0.2.txt", + "url": "https://raw.githubusercontent.com/sindresorhus/screenfull/v6.0.2/index.js", + "sha256": "4246711b342018b0f257f8fa6047f240a21af6218c7e79cab5c662e810bb3e01" + }, + { + "file": "refactor/baselines/core-vendor/screenfull-license.txt", + "url": "https://raw.githubusercontent.com/sindresorhus/screenfull/v6.0.2/license", + "sha256": "5c932d88256b4ab958f64a856fa48e8bd1f55bc1d96b8149c65689e0c61789d3" + }, + { + "file": "refactor/baselines/core-vendor/hint-2.7.0.txt", + "url": "https://raw.githubusercontent.com/chinchang/hint.css/v2.7.0/hint.css", + "sha256": "a804fa4b607167e579b39d192f1a29d2b27226097094e0351f2d46ac8ebaa864" + }, + { + "file": "refactor/baselines/core-vendor/hint-license.txt", + "url": "https://raw.githubusercontent.com/chinchang/hint.css/v2.7.0/LICENSE", + "sha256": "55cee0a0645d18366eaa0cd21208c224568e14c38b7894e0f9ff537702ff8ea0" + } + ], + "local": { + "packages/artplayer/src/libs/screenfull.js": "2332b50c0c6364d5c99080be0f5739255e4b9e465d2cca40f761adce9a1908f8", + "packages/artplayer/src/style/hint.less": "e2dc4940e6b212d8da75a404fd5ff1ad894008457677bc37554c6b64b735bc31", + "packages/artplayer/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7" + } + }, + "browser": { + "stats": { + "startTime": "2026-09-11T06:11:22.992Z", + "duration": 358495.496, + "expected": 1458, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "member": "artplayer.js", + "sha256": "b9d544cd88ca676085facc6a67d6da744b9f28f4ff4622fd6beab1cd9444e659", + "featureCases": 129, + "featureCounts": { + "screenshot.spec.js": 39, + "thumbnails.spec.js": 24, + "progress-quality.spec.js": 42, + "source.spec.js": 24 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": { + "chromium": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.044496, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "firefox": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.170845, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "webkit": { + "capability": { + "enabled": false, + "request": false, + "exit": false + }, + "playback": null + } + }, + "knownResumeRejections": [ + { + "browser": "chromium", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "chromium", + "core": "candidate", + "rejections": [] + }, + { + "browser": "firefox", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "firefox", + "core": "candidate", + "rejections": [] + }, + { + "browser": "webkit", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "webkit", + "core": "candidate", + "rejections": [] + } + ], + "knownScreenshotRejections": [ + { + "browser": "chromium", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "chromium", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + }, + { + "browser": "firefox", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "firefox", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + }, + { + "browser": "webkit", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "webkit", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + } + ], + "blobCapabilities": [ + { + "browser": "chromium", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "chromium", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "firefox", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "firefox", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "webkit", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 0, + "error": 4 + }, + { + "extension": "webm", + "width": 0, + "error": 4 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": false + } + }, + { + "browser": "webkit", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 0, + "error": 4 + }, + { + "extension": "webm", + "width": 0, + "error": 4 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": false + } + } + ], + "qualityEvents": [ + { + "browser": "chromium", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.163741, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.163741, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "pause", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "chromium", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.149589, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.149589, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "pause", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "firefox", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.416666, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.416666, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "firefox", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.416666, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.416666, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "webkit", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.2799448, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.2799448, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2.0013082, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2.0013082, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2.0013082, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2.0013082, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2.0013082, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0013082, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2.0013082, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0013082, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 0.0014563, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 0.0014563, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "webkit", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.5414584, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.5414584, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2.0032528, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2.0032528, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2.0032528, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 0.0017575, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2.0032528, + "time": 0.0017575, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0032528, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2.0061344, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "chromium", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "canplay", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "chromium", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 2, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4, + "paused": true, + "seeking": false + } + }, + { + "browser": "firefox", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "canplay", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "firefox", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 2, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4, + "paused": true, + "seeking": false + } + }, + { + "browser": "webkit", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3.0024047, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "canplay", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3.0024047, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3.0024047, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3.0024047, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 0.0019335, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeked", + "time": 3.0024047, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3.0024047, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3.0044887, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3.0044887, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "webkit", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4.0021785, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2.0019598, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2.0019598, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 0.0004563, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4.0021785, + "paused": true, + "seeking": false + } + } + ], + "cases": [ + { + "id": "3c9d5ff5a17ae653dea9-f4ec85bf2b8fccbf87d3", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-92813800e1301b551fd5", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-c9ceaa1dfcf855c601b8", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e3ad9a2e558a2a865aa1", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1e6334e252a4eaa99157", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-949f11341529012e52e6", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-25c2b76fcc6c397aa5c0", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4f5f4ed634525c07b8dc", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1f1fc11f543db6e79ce8", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-d005b6ae9b0d6728bf8c", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ee0861705ad7987b9373", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-486fd375ad053eadbec8", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1ccde517b70725215290", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-114616f87a72c9199052", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-d45701b9ec2e94b1c2a0", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4d016c4954c8ac6cd389", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ff618818b5add9a867f0", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-532ba0fa22ce76077251", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-545631e0fcab6e19f14e", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ad4abc5fde8cf38cefcf", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ec0620ff5c9501117ca4", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e6b4bc21c6783ac134ad", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ea18bdf25cac41af6e2e", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-6c12e77cc7c16d1f2b89", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-f020f7ee612d0431af8b", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1e8bc6f4219030568692", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e0e498eb32391ec00ddb", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-0db526164287c9cc7775", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e2207b0298c6dd9adc1a", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4066cb1df299d5885460", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-c7af31684e3e62c64702", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-726bde899520b514a36c", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-b89c5b026f849456ba91", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-458e99a71a6974d07a80", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-597946b7614265121e43", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-8520c4db170de4de357b", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-f70ab3d8a77a9f8fc061", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-be9f42770a55bc5fa01b", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-2d0bd1e8ff578b45e6be", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-23eeb147e099fabf6613", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-09605c2a70067e7bc3f7", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-6ff8f2f1a7c9a48d69a4", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ac54090c4c2cf5fdc028", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-fd6c5318117c46dd0942", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-51837a568fcb8a51ca77", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e250a78531a8c3d95feb", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-58433fd5f9d1792004a9", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-8a8eab049510e21abb09", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-0c6a909338c7a7e4ee81", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e44e5236ce97dbcc66db", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e218dab15f99202a9d9b", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f15b34474cf3deddb46c", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-68feafc04a4e200bdbbf", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d4a9b70e95a88f5f1b6c", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3bb4aa4e8591f74e9b51", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-77661f6e8549e2f2b0f9", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-fdef85438132665e82d5", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-7830d06c46b9c5ba6161", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a15c4c84c5b25cf34822", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e181d716af04e58eab65", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-282f85fc06d22f36392e", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a5586b42e67bb73c8576", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-45123d301b41869a88d6", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d401b1da991706ec9c93", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f198b861d3aeb3aec6dc", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e736294669adfc2fbd2f", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-1ea861945628ec3c983e", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e5aa6981246d2e9207f7", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-b181ca104e1c603cf7b8", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-2d43188e99ff2f841723", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-0f34df57efafa8c0edcf", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e30bae571949edeb2a20", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-aa47bf8b002eaa057b68", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-957389ac7668163258d2", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3bd3803675891e50e1ae", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-acf581cc432a521849b5", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3eb4f85a9aa1ae1d0ca8", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f7eb5ce9abd5de8ed3f4", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-ff8e57c46b92463eb08b", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a145acfa8d4c0614b1f2", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3d2a53683618e68ad9e0", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-98127aaa83cf106f5466", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-5dde60f90d9a6c95eceb", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-904fdf6574fa22097ec1", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-16541fd5ca5023a4e37a", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3637c50e1b3c01c6f660", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d47ad23d299af2e963b9", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-c3f87c91054205687e8f", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-db0f475014584baf27ad", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-c3f57d25a9d377e5ee53", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-13db7df9f8d700edda79", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-af27eb5638cea6dfe907", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-14c8ec42e6b63b71f7af", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b9949b48fb7cde7ed81", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2474cead0e45468fdf72", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-92f6a6d9a13ed0db69b7", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c38f55e5356c80555777", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ce5a4349c94e7573f2df", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-745cf7ee3dc9fc8920ea", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7034aff5865b19493d48", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3f7f11168066bc1135dd", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-98f452e8fc88900fbf7e", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c075e9d7be551f55dc98", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2bedc05faa553d9d5e75", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2d30e8fbce3826e3c15d", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0a87800d172dcd9435bd", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf7e525a2755f0c86bea", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-e4470972e51039dd2948", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-259434dce8ad5217c100", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b3ff84e07f9b6519b6d", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-03a359bf96cac72eec10", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3e3a0590e83bc657c777", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a94d3e2e3468e36b53c4", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a4513ef73bb7d291b1de", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-907cb350996072e49f76", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1f07c4052b68dcd5fcb6", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-dfbf83aa28cd6f99e6fe", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf995dadc1257e9111fd", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf0c802aa1332ce3f50c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8828838dbabcde8784a4", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-d78fda3b4a4f188bca8f", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-4997157ab3e3b52575df", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8dca6d7565c27e3cf00c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0dc7ef53e5e6c1c6a095", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-41d8436843ab4e0c4a53", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-22beee8392c7138d3eef", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-db259a3d649f557bdd8d", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-6ee40eab9446590238f7", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ac09580cff29b5c26244", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-191c4adbf7f0bfd11d22", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1d69886cc1563158b162", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ccd2c30f32a17586ae47", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b64859461b5705d1cf09", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cddd0b156a2290520d0", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a0ff31c497eb06cfdeb4", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-48a8c2fa6b32442681fc", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ae60beaef7bc0cc1c93", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b405a3930560f4a322ad", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23975233833f7314852d", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a2216a5ae190e64c0c28", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-fb9f50f4c4f1cf9a81f6", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-537c7bebe8e335d5ad67", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c9beea42f671df625472", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ba81907a4dbfb985f88", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-72fc63307e889563b0c8", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-955901b7c9b5f75c7b1b", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-05c9a93bd36ae4d71ecb", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-75d44a2ac5d30638ab32", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8bea5b2d30fc513648e3", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5e1987406b361d07632e", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-0444b7d85afc918256d7", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2f11ca271cc2f6668307", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b2817b31801e2c0549f4", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c0ae2825f95023de5382", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b0fd67600676be07f53a", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-646cffec899839d783a5", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a4bacc2b948ae9988139", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5de7dc1781c68d66d249", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e2e82a24bc140d731d62", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e771059bdaf24920387", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a67e3762e19c71f868db", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e199356f63d8d0e7e9a2", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-40af3bb8e336fdc2335a", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-621ba9de5d94c05b5cf7", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8317098f87d1859e2dd5", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1c8e447ad7f0fa9e8eaf", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bfbc2bed73e613bd99c8", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d36a9d234b493b84426f", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bd1fba69aa773e1f9339", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d3a7712862581da5e75c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2107d278212d36d8da0d", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6b4fbf1d3182b04d96c1", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-04f3c73d8294ca07e6d6", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8ca066bc5b5eae539a24", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d330fa833123b6b20ae", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4c8fd972f78dd9f2f4f5", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d48bb7baf38a31478a96", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-374314906befc5bd4abb", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2c8af0a3cc8135d1ecb9", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-ccba8bf8a8ae879bfe04", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-71c2187dfae3d083b25f", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-9cbfad2cb618fc3df484", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-479da8672c58208a8f64", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d058a213fa9dc91b39f", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-de54752fbbd7c23b614f", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4f31edb98158d9461c54", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f28b63981b091141e37e", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-84ece502b0a7e2f6b7b3", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b4e97f806f7889922a7a", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2743285543496df7fe1b", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d6434aa47c57afe2cba2", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6dde4465bb116870696e", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f07afacdccdf8d37a3bf", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b9585d2981c5e97120e9", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e94b71940033ec64bfb2", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b501659d6692e6a3aef6", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-605545662d878960f7e0", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-62a855d83edae78c8e0c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e5ad7ffd21eb01026e3c", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cdbb2d211601ad9049b", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a1482fe33812e30491bd", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1b4a508565aad47f08a0", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-eed9dfd6f3a3915a8ab5", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7b1c657eabadad7a4e0b", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e9a8def3dbc766cbe9d", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-226371bcad54f04cadac", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-593c07ca263ec7a933ff", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-664754e838f49dc96b98", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-195208b0571472607e96", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f85d899f5dfcccac78e5", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-92f3e716e64a7953a41d", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1aff62157f9fbb1f88fa", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4a9550c051b51fc07942", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23bc5dfcd88b2bdfca32", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-14920589fd5937fe2097", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c22d9f44fdf7f96acb27", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-bce9960eb782bf3b388d", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3d865d3ab8a953516b83", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3971824465d64033c64a", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-784699458b9db440715d", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-e56018edc0c598cfe3a6", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a0ff3ef97b2bbf67fef0", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c38fd837350d34f82b4d", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-75441bab4ed44b490b3f", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-d07660cba382135f5e45", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c8126a2ca83e05a31885", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a4be546819cfd9b17a99", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-43b0ce05e60dabcf63cb", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-215c4e43e0c210b6c91e", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f51783956841921f653a", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-060b7fef9ab61ca8b51f", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e0701300b28eb93d84b2", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3ce10fb9e5feb9de0209", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4470a8c5dcdf58209d68", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f0b08a105464db873a3c", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-77370983ec73972d14d0", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-cd81168e76f3e6f8034e", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4b38710a4241fb8efe81", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f08ea1ba290c5e0de00", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-932ce5acf10f04835f38", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6f12d4261b9f612c4afd", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3e31af20014f27ee9e5b", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8a5dcabf07024f483997", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5ca7623e1e9824c6ccc6", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6b3e80d3ab9d74293e49", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a469168f1d396f999be8", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a555e0648a8c5972e35b", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71749fdef4307b96761d", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4edbd5dc212ac30a7bee", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-83c2f8a16d078a06d1ae", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f48f4cc7fc5d5e9e98c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f413428a3ac2b2788921", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03f107aa3c92549e8cec", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c63150bb39f74f89e359", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d1bedef93dbb2da29830", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7ac118b7169027c52d4a", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e6d71f296f035bd569a0", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-641c8ca6813a23b668ea", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1da7888e6f7a6eb19da5", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d25b39ad88db7e7b2bff", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3d8d63a748da48094a7d", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5c17ee11f56d60e5daf8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-979bc6ec3ee848383b3d", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a51cb8dd4bd7141ba7c3", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b8361baced0cd1c4884b", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4a7f7248dd0e4bb4d117", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f1dbddcb8b6c55bf6abf", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c28aa23669da794975fe", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d74f1148dcffcc4ba48c", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d2c53e913102a1af553f", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-96841fb451ce9297d393", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7c96036f21956e3c646c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2ffb342b36c816963ff6", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-87a697176faffed75607", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8ec24e59d1f42fe9d061", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d263205b93ce3716eed1", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0f43609b9bcf28f089a3", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5448bcd8bd74bca095fa", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e9ece5718b190162c6bd", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03a8016bb2aaaf868aeb", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2e1de5378e019cdbb636", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b32fa9f007198c281028", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f515d4587be9d12105c4", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3afffa70279f302e77e8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1d8ce60246227b370e0e", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71ebf721d07c19796847", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-672938aad25b617e5f32", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0435322e0776c1c6db98", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-23ae836ca899325453cc", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5d87bb95ffd4bf65a4f3", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-0e97734020dcc6df9f26", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8bacf1c1c56de38bdcbf", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-51e147e0684036397c1e", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-59dd6298bfbfea94c275", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8c03ebd32e75e51f8e34", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-f4f0db9972fcc34e2ab8", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e09e6f9d356868edfd1e", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7968deae0894a7a41745", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d2ce1a7a9b2ffa66c042", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-2d2e74a3704d6964ff64", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9f45e376ea3da4b17c32", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-44525e439ead5cf1926b", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-13923f8d94a0d0ae4937", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-b30f9705bca57697114f", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-a7d18ff2f641f5cbf514", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e0a0990679eba59f084f", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d07e0dccd2ae40c36625", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-588c0d140bf9efd60a8a", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7d51b759d72f50c2e069", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9aa04acd042f2f815772", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-83c5a739fd19c1ee758e", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1be5ce38e6088062d978", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-266740492e18fc860ae6", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5201d0b8a57c2e862249", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-40e808dd1c844558cac5", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-691006a324af76b53d61", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-3a3389d22af8979f8eeb", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-c40ad10afeb67ea2e850", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-10149aeb19bf6697c9b7", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1c6ef5e75874838d7120", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7ebd0a99b0afcb231926", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-dc5e7d775e8ad4bec7f4", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e4d66d69d8df88578432", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9c425dfa5bfae0c980c2", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-17eda50816e6fbbbca7e", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-efabd841d061bb9e2536", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1f196ca428edacef09ee", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-4ae95e66ac42d7d03f9e", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-6c413f210385d70a7d80", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-86d59b7185aae72ca502", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9a9e65a49548f6b4d6a9", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-509e6f68a4e4efa344a5", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7f99bc001b5cb7f460ac", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-39784f83c5a20ae25922", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ae72eb701fecb9af3759", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c51f1e6e8e3e150cf656", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93d2a37ad53cbfa50f40", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e1fe2e4b9b734ba3d131", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f72eb06a65f80253993d", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7ce46c729250e79cb277", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-150ad3f2de69d36e8b82", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-130924bf85ce0603c3c2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-76381e5bda48a5ade3a2", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-a0ff15ba8484c82eb5d4", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1dd95d3d390501835602", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-4895669ba1966f650b48", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad42062f96fd6eff1e57", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f3aed2b29f46acf70e9c", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-d4a7ab2fb9f82bf30b31", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1aa42586b0131c02286a", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad1af31ee3dfc38e3f6f", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e6fe305f0c0d3313abc7", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-cf1964446ac3f3a005d5", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7bfca3da1efa390f1d78", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-3bb82b015b925c65648f", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c0677c484632220c9e08", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-2d734612eafbf347a12a", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-9317141fd45591056bf4", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-48e2f8d5a7ed9f6bb5a0", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e20a77918392d00be03d", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-de4bddf17cef4be77029", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93ccbb4b069002b19fa2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-0874de284439b96ad2c4", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3de9b990facdeff0476c", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-749a7d338b2101206765", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e6382df01316fb281fa", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3bc55ca3eb9f410ec0e5", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-90f2213c5aab99e4e570", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-1dfa2ee5c94403260245", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-86b43820f5b552d786cc", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3dd543ca3a3090d34fbd", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-c8c02cdc6e6c0fc1420d", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-9a4914e43bb12fbeb582", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-769b87498109362f84fd", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e4973914f06c39b6698", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-083974800f2e8879ae1b", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-641a2dccf8325c290c99", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-4ae457363eab61ca9ae6", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-8194bd99f36b6e951031", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-fb2e3177eb20d90269fc", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-2b7df84230e1938edd1d", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-ab2589367119fda8a5c2", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-50ff4f070fa19d28d259", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-e3c66306c7b25f4f4e08", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-aa481f1919609650e0a3", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-5f4c93857986beeeb8a1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-bd3d36fb7c393b6fb340", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-711513ba84f86888eabb", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-218ffe39dd11365c7b9f", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-39b746d120824d46ea24", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7faad1910240a59dd0d1", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-25a6bf8bad817690412d", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b29b1c45e6d1ec961272", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-667bbcd209351537a529", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-69c72083a6301a7b0a95", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-967a82e04705cb8ce7f1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4b3a751945fffd4f1a50", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-d7bd4e5eaff49ff3f6bc", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0130a4a91c9404610c5d", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-6bb9d58f98fdcd85523e", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-38e55045d1be4acd5358", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-3b5e09ff69da4caa4ced", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-83bac7c7daa4e1fb0eee", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0c5ae0e780b7c4cd4531", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b025eb13913d88dafadf", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-8afabec893b951bc9dca", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-1347f52c5334f122e18b", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-338fd2cfd69b416e5e22", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-9b82c9a55c0a272c73dd", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-e2033bcf8e8df5d25107", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-820a88dbf4c7c26b97b7", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4bf4e63de030442894fd", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b3c6572e746e10e018ea", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7b9ff7b1d7be3cd2c923", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-33f5644884ec9ba86bcc", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-2b06e449e9aee6d0450e", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6941bd46497d1d2ed300", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fe227b73432db99c992", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-c0d916d83a69c0da121a", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-bafeb7f5931093c7a39a", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-cc32f7d91ce9e4df9fc0", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0ebaecb2cd423a62fcf1", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-63d5f364fb9be03dfb3d", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-4e88cd81c30b7e5827c8", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6e8ac8042e4aa05ddbb9", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e86d33c92dc30d00cf21", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-b7a4cf05e951b7de5920", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-d8b9352760cb4971e37d", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8fef1588177f24706032", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e50eb3463d090abc7b88", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-ccb72602fd5954f2946b", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9b9158caa8753869e593", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8a3807010e3dda6b493c", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-aa894c121cbb637c2356", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-1a2ebfdf05d5e3422606", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-dacf4da548671cffcf41", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-3fb0d0152310ce81c940", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-a2863c68ee28f3519445", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9a88c32f828a7664851f", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0d55461371288f7574df", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-daaefa1bb396ff5f0509", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-f092d45564e8b3510bda", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-643e209f256d1a250a16", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fb7121ab78997abbe47", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-b7e30679e943616dfef3", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-41b8387d30bd3355cdea", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9fbdd4ca5d22c59ccd22", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-208f9783e628fcb9f8f6", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-9b25a8ef63de7b4dc979", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-b6eaa1095fe80688f08c", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-217eac71a398847de922", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13fb46b81b245d60cb62", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-2388222367857a3e66e2", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13542a5bca0f6c66c1d4", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-55a303d76fff18e9c543", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-aa7ce7a489558e5015bd", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a07eddfabd5626cd0a2a", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-be81b8fbab088b300863", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-219d49c53f695202afa4", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-7c345ddfdfbc22609add", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a266ccd310d1805953af", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a4537e5ee57ecc6df48e", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-8789c7a223602cf16bff", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-3083605efadc1ebb2817", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-d14a5ea50291afe6f9de", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-d8ab6eb3399b84992a2f", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-550cab25cd4472ab5404", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-815457e6e43f6215cf16", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fb5d2acca03e53a05fa9", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-938d058c513b2c6e4a7b", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc2f4dbeb12688fc0d09", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-13a224af21b3d0914046", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0139c3c03ae78094f003", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-56fcf9d4ecc6dd2b5317", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb9a8e784bc0eed2746d", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-f8713bb4e572bbcdfa80", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-db015bbeedac5adcbd10", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-19ecc671e1e026bc0ded", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9ef90c68539232ed41a5", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-21cad0e9cdd6d2bfd1b1", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cecc49e625d4d5249b11", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb05d7f99e674170cef7", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9646aff44447cc995bf8", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bdce42f9d74c3175e0d4", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fdfa7d6a3e6cba0ab22d", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7218f7cbdbf7c782e370", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc08e8366aa5d34a9c29", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80abc0538891ca5f3aa1", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6d04590538d38c42aad5", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-c57605f5ef7b09cc636e", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0ba87022d3f706fdff30", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fe1595dc54e07363e691", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4297141ebb2129c56d83", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-63c383aab40510893259", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-8b1e8a0ed4dff57437e9", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9fdb2090b41f1f3ff3c6", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-23d2a65968478f02d44b", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a20b1cb4c50409198ac8", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-07e5b86c2ea67d5bfe00", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-021c130be876d25ba481", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-842e4f5ea371dde0e5c2", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-137445c9986c9c51f2b2", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-da0df43eb60cf30984ca", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-2200c9b0e251b0d7c3df", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80f4f73c29520d56a77a", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-24afcb40cac5af9d1385", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e3c4d42cfd2be629006", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e9de1c8e6c2f74726a21", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a7b2b5adde5a53dbe684", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-b70a7b7a9d964994eb6a", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-226a392ef76eb6584e8c", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-683943286d8f1c511779", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e87d954b29f0e537aafa", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6c492f1a4ee91737fb44", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-222bf68318bf2fa781e4", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4abcc05151f508b6b38a", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e62178933620bc510f18", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-936b9f3b6aa4eaa086bd", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af01df3c5e6334b2804", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-37632dea3a3b0bacf658", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af0c468750891cc0795", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7c85395365aabb2689de", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4096b3070bc74225ccef", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-45821ce9036c86d58429", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-2b3339054c6014e3d92c", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-1f11bfc1f0db92a746b3", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-5dcfac157f8728da6350", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e69e56ade45d1c34c23", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-df9185e3b4b991a41e64", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-ed9673608bfce2021867", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-24b54879cbf233713158", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-88ac928201db18372b56", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-e6d95084fc692fda4982", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-c596a9468fae531af4fe", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-35933d1aa16aed20c273", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-284569d9920b0e711743", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-f133edb484cefef36fa5", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b6865d33ac15fe202ee9", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-874d84ca789695182779", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a4af7d5968980731d353", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-46ec1b4d191ce6ce2b87", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c065a965bf03c20c92e9", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5a43a2d9dd07eb718eac", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5c900727f4df105d31e1", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-48f5ae6cdf42faf667b0", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-8ab1ef6cc7e44699a093", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-823f4e17aad9a4475863", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7a655be064429dee0a96", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-acc7f1cafcbeef593883", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-4b319da242a0d8c88898", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a2ac88d6cf9bcb87bc6b", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-26f0718fb72ab6480f46", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-9fe68a142a0bc1358130", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-808e795ad0ae6b29162a", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7579b31713d2e73709f3", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b22bfeda45eb2ca888e7", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-cbf8c58deb5fb97b5f71", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-49920d5cdcd992e18848", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-89197327fa985823badb", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-39a5048a03780f5926dd", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-38816d0b0af580ec7ae0", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-fb11c3a2d7114629dfc1", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-04ab8fdb013a043672b5", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c674c60cca295235cf91", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-773eca70690d387d203a", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-3a3ae1248ea885530ab7", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8e78a04173cccd6a36fe", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-a5d86368d43103420d7e", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-37939cfe8cdabb73cae6", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-1261a6dd4dab94de87f9", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-97b919d98fb476bb06ad", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-92124b7cd341179d274e", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-9ea4fd31ac9552af5a78", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-3fac470389adaae7428e", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8029cb83aea256718e7d", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-cd89fd95afb4cecc1aaa", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8785f5d4b2aa76ed07f3", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-18a0b3d713eac5837acc", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-b8c630f860ba3c65d17d", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-cfdd6a0d764cdbe399f4", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-32d7e4cc4e00529b2fd3", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-1d6536787cf98d1d0f6b", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-add54e1d17434e14d73f", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-35b044daa0c8a9b1d282", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0960e6b2d6129f891aa7", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0cfd5bb77ac4577c8fd7", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-aaa9953db4c7813bad2e", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-30502caabab5c68b70fb", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-ef92c054fd960df4e187", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-d93b70a360c3c6bd1597", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-f67c125dd85f543cb490", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-b98acd23c9bb5e10da08", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-2d2899f9a9959e416ac0", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-ad5f774f8715bed9a669", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-37294e057cda968b3313", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8779782ddc0db5031b0c", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0ebcac3609144ca1a60b", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-461f5dd6653ab5f2a639", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-27a5bff23ff7f1de8dd7", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-497b96f591affc76d55e", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-161d08b4110420b80ac5", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c204080bd3b07a435032", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9926a5b91c5984e3b054", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6cc5ee1c72355fdb1396", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-60b0c86e91e11633d921", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-7720022e29c29701e505", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5cf5d68bdd537fd238e6", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-dc4dd75dcb489b80e3f7", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fde552e9529a19d3fecb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-a7eecc22cacd33b910b2", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-965cae8eb7530de807fe", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-187c124ce8e69535b346", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-4aa95e812cf8a32b7adb", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-0b25f726ad05ae471db3", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-b943b423ff6eae4207d8", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1de19e97f5545df7afba", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eeca99dfbfffba631604", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bb9d55b4fcc0d96aa0c", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f08813139950541c5009", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fb6ded7b3f2a84801a6f", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-244a33407a1a4f812e79", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-532e0d74c736bd1a0a96", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f2e118615ee7bb5a6215", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1a9c3a775cd64374bbb4", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-362578108b38e76fbb38", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-13e3feb76468dac21311", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1bfbe29327bd8d169e61", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-aec7df62b58d89b641b9", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-3f5d5b7cfda98d08d6f3", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-38d36f45d72a4173bca7", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1874e2851c159cb95e46", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd0415b8257f201f89f4", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-382b12a6bab3d4b449f1", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-bcf78818601a8279511c", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6919f1e24909ceb2e9c2", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-032298add8fa5c9e6900", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9eeb960c866cb8e40ae7", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-495621812ca11295f6c4", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-278ac9215c6ee4ef7a0e", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-281de4e437f228cfbf71", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-295d34734b65043ad9f1", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eccf52e9ad978c3fb6f0", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-997c6976d105bb92e34b", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f8ac31a8f379e827afa6", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2696dcfa7d78664906eb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c987918ce4081b93f4a5", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-ca7249b272a4ee995262", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-31189dc5c67888379803", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2095690dc9b524b59f2e", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd3da8b80bde24b740c6", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bc8d77279a092208982", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-617565d43b891af783fe", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f9616507688ef54da419", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-26f0e410fe8fbef993e4", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-82f480adbb99a326dbde", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5125ea2213ff5db2e37e", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-826b6613db8e2561c1f9", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-a0fa0283e2778dc5de31", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-fa9c790ee5f9cddb03f6", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-50d0f3b11ab1c6d2a851", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-58c86f200056ced2c1fd", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-ef8e8b36cd6be9ade13c", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-412a59f5e374b192ab8f", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-7bea54a023db77650f45", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f2a1eea4a9da71d32455", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-0ba262110508d87e2629", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-89a9d197048808466148", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-cabbe9eb64dd98cf1577", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5f6824deb87c02f599b8", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ec4b2c508a72550ea58b", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-310aaace35717117379f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d69b68b0bdcc53067f53", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1a588135d6cc568e6fa", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97e1208644b9fa58b8b1", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-09675477605b25710801", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9e893625c48fdfb954fa", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d6b81653bb60630a3599", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-66a15a5984ee4598f0fa", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d7563229ff93d6112f7a", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d51274ed9cc2dbcfb578", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c737f670669e27522d3", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-8995ac2dfb98da407afb", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-01938547b760ce9813a9", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03fd75c773964be30538", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e759bd25c03f8a5d10c", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-98f620bde5cb9a1b371c", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-0764e8c8458e141bc8f2", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-59ab8baf180ad899b67f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2bf2947fd3d500d7172c", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-87e5729cd74cd61fb7c3", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-46a350c4c851b9f21238", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e8564bdb7bf0592a134", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-17ef0769f5ab192ba955", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-43c293f7c92733bcc08b", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e24f37c60c9773759771", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e502fb517997f1b53153", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-04fe566dc8e712f78ad3", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1083b5c3aaa666a25b5", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-965d4a265b14ec72626b", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-aad49f66089770417b5c", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-afaa58fa5e14ad72db35", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c460f1702b1887cb0943", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-eb991a205aeec0eecc91", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-bcd222ce2c4830ef345e", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9183819e25f74564c41f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c757941b4feb418e86a", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-342135d4e67724c3cf83", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97ae305550aa393060bd", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-7a2bffaadd6727862592", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fa81266d048708984784", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9b9974717b4576aa1ae4", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-58b7be0d4b52aa9fccb4", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fcb2ab222414744b8ea5", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e6130ef57b5ab5661f42", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ebadf97bdc5e9f45affa", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9ee63e8b728f62bd983f", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-021200f38ed02bb50845", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03c49c3e845e96f8e76b", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-1bf7e7b8230dff7a356f", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e1ffd301af299b9846be", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1ed76b5f6a82de9d068b", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-3cefbcbec7deeff53d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-69355e4dc46467b0a9eb", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d94e9fc7c4dba97cc53f", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-61c4eabc80173b1e442a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-71d443a2b6af5518b178", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-59cb2417e70f961c50e2", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-9c1d85713fc8613fc6fd", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-7c6a370020654bfcada6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-30aba1a1bb1b8501b0db", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-15709a7d6ee1e1e37d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1b85f275ededd6b4ce29", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d7c211503e05f9db4594", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-f8c63f06543266f0373c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-55df032d48093a9a7a98", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-43883bd2151838bff08a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-96cfaa6a8f4b9da28c64", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d322bdc5916e8bb4e882", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b6a7c315b0b983e8044", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d5dc97a19584f2c0bd7c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-509d99c428ef04fb2e49", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-fac2aa15d600bc1bf552", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b23a746569631c03db4", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-bbd046deabc0ca1172f6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-d1cba7c810d80b340f02", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b18e0bd87418016b019f", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-f640c192434bf9a64a7f", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-af04f2118c29852ac4d0", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6bbd26e23fb3429993b3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-78efe4e7a850b2a90ebb", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-dd98a66249e18d35e4ec", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7e56c82040d8213b52fc", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7587ab0e8e449207ed24", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-5da1a688dbe2217facb7", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-489c3bd67ceac85c7d79", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4d1c0bbb0d31efac6702", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-83a5f6f72a73e749b6fd", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c60ed5afa38f7991685c", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-1961de75defdc952a8f3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-351ed5a2908f4cc9619c", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7954fe1c578a54eebf8c", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-36154f67953190d1bfba", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6522dbb08c1b075a5ec0", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-76e298b978895f180911", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-77285e408518bdd6dee8", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c8f1d687675a279a00cb", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-3d38bfd5b7b08646ebfe", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-70526633595037330da8", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-e00d282a9b13f205b9a9", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-ca150c7e341afc79085b", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-de68c38b7c4aa90447d4", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4bf9b7e006db011964e1", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b81bcd76f642b8cd1cb6", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6a1c655a7541e2c283c5", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-33ab58a217e5ed46af64", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-6c3e26795bad7ad08640", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-081e4a3c2efab5a6a4f8", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-48f3dc84a4b45ece0f66", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-bd8e568d3c301593236b", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20205da01df1b6d1275", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cd03a72feb502b43128a", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c084c9d9f3321e48be59", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-291a97e5971de8da34fa", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-96ad9b36215f1db666df", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0ff5f41421512bce0682", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-85d3c1a084877cb32e68", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-9a764add8106b570a9fb", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-4f6c3e8455782e5592a1", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-321e89c016aaf0a04e89", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-3835036f94dea4e826e2", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cda798777baabd4bf688", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-685f7f019e46ba558b9a", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-640ede7d3ff202fea200", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-254917f54cf2302cd6ae", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-36849c7e4b2167768c04", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-ac5d5c862592ff76b6c7", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c3ffd08e95c46586ed24", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-46ca3a1867d4e79ccf78", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-330b06a4b4886d69f8a2", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-7ea574653c71793cdc59", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-494fdf7a643287f6e9f6", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20b9efe52074aba9a9e", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f720c3dec109e51e7e33", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c7e1c0f20ca436a64e31", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c10d09a36296547cce19", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-65b87ddd974d9095cd99", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f923d3845a11b464c735", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-71e88fe06828c0aaaa52", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0e43bca78fe1615e1188", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-74b76fae26483153575e", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-f81f74c17d54e135812b", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-cb7cf3d37546dfaaa25e", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ad243930eba7bbfca9ec", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4f06979d10a0cc73f0e4", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-73b72e27dc0e279e1dfc", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a391ecf6be83e360d5af", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9886e61b50b0325f00b6", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-7661cdbadada621ddbdb", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-534b6a21f22d52437946", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-964c3e167f81d6c4b540", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-b8af7f6e76d64a404611", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-26e289678f8318df9985", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a31d40ad896888983990", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-41f669bbff76dba08542", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-94ccef7d1b2712b3a8c7", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-0acfeccae2fa10a364bb", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-804bbc5c45a32217b23a", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-e1687b8c29a364456ced", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9de93a65641998f55bfb", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ae29a326f7d6b9244c7a", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5642c616032ffdffac35", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-75b1d9674a6663bf2d6e", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-1e45a2a5dde8e9ffc1f1", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-fea8a7011bdffae81cb6", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4d2842dff07972329923", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5235450a56f738efeecd", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-6d06c3705c2addbb8090", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1707b8b14a6deb4b2b1d", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-c052ddece9958e0555fb", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1723a11b47d130206b98", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-b93e8a95aa929ea2ae0c", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-60bb8e6ab68260d8c6fd", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-55abe99fef6857550456", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-0f49d1285226348634c0", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-24f58619d642db14fea8", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-68c445671e9adf88066c", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-aad4d2901d12bdf01915", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-24762ce6b234dc12214f", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-be32d3483148f5f64ac8", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-7f558c384fd9099689d5", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-ac74dedfe39f4659eed2", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1bab1b46912eda1af15c", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-da995b98b89d9fb5bf58", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-774e4aaab03d5b44bb2c", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c498914bc58cd712c4ff", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-568bc11275e9d7dce946", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-52e1a6cf49f647554379", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1e837e265e2ff83fc673", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-81bf5cedf663307d9ade", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-6a9cd51e3dfdc9b290b7", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-fc77ab576b2048180b27", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-23a5ea128a8390a8f174", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-70f2c8b45eb47ba6b09e", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-bc8a0cfecef9b3a54ce1", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c1b5af0a680287efd190", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-460e036a9ebf06309ac6", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-3ea62e47446dd5fd1382", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-7c4f53d04de946f4262f", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-52494aa0b96ed978f8b0", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-b5bb4f5eedeea74c067b", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-38fb23b594ae4f3db0fe", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-9f81a06a638bac718bd0", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-6af186ecb30ec790a0ea", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-b5a62d7e6d4583de7dcb", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c5cfaab74d04578f892f", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-06538701168e8ae2e9c1", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-be4d6b65a904ba3a6a08", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-e065097fdf992aa65df0", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-e4d45b9bd192de637872", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-a0cf1e8d9be71232b3ea", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-9e144dec84b139541490", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1840748750e30e4a000b", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-78fe676015d6e8dbc0d0", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a24e837c0a70d9648453", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-802ef8362a0f403ae08d", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-70abbec3c9dd6b888e1c", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c0ab35af2770dd5f4806", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-e72fde2e2a57668fa47c", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a4df961c9062ebada00d", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-73e6bcb78301864d09a0", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0f38da640b1ce0c5e360", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-08a820c1f1e532774cc1", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0a6080d5d9c551bbbfef", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-d47adcf0c29980498c19", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c1239d4ad067319ee2a3", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-229449f9f5a2f8fa7963", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-52e7670a5b3a053c6e55", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-7ddc0ea00c170012b4d6", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-dbf437be2f34861c5a0e", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-3c389ca847ff1e4c75bc", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6542b91dece2a74614df", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-51b208ac054e2eb00b26", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-4f6db3993845b9ba2985", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-bf0574101b74e333abfc", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-b8e3d4f14c5274942e99", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-aa029ef04ccaa364abaf", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-884e7e97cc7f4601b9b1", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89a5f36c70aeb1aeb725", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6e80e6040b5d820ea851", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89b1e6f236f0b07b34e9", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-76c423a2c23281a89f4f", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-f1b89a3a449ec92c4a02", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-846a43d5c11f461bc706", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-923d4b452977986e35eb", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-3751522702f6c4040d89", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-7c1ede28fdbca2fdb036", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e71806ec46cfa3c8830", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-308b7034593f3aface7c", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-824de270447cd0289399", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e405967fd041e7bd63c", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-73ef3504117f77184a3f", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-273a8c96e455bc2cb3a5", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-421ad6f29b1e4edba558", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9848ba9b5bdc87b7080d", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-fd0af30740777b8fa6f6", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-caf25f6ee3ed380b66a5", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-1694c548d47a5dfd7321", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-4a613122854d4efeab25", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ce9ca8b3a37a93a751e0", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-a86fc2f76d5a0e73dc92", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ed069932d1cecddc62ca", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9a9f8fea7676c3fb1f03", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7bb2424006b234f72e6a", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-f7838ff686e269e64cbc", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-22b53afce3b44c0e3b56", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7de925a1d5f347027a30", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-d4bffb27232bd134e0ba", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-115453f0cb1f2df25c13", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-576425b00e3b37a5f55e", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-6ddec59a6b7a73444874", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-c4a665637742c22fe6db", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-05c7aa4a035cd53f615b", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ff797d35cf4226a8908c", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b321c5b060f24c0dcf7c", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-86838248a63b8cb598e4", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f74d56109a0a98dbcf37", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f2cd78f5c336b7b5a29b", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-687bbd5c29aeaa2087ee", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8e37462e4a700a9d032d", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8b838317977126c72896", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-c162cdb14c052116404d", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0b01ed5f487c653ef5e6", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3faf3b0b78cb6e5a7916", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3cc483840fcb60da6de7", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-886e669450b0aa293cc8", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-5d9e035f106d302fa65a", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-850f54c586f39ff9ed15", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b9482406e41527269426", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-472f4ce1e106982a41f2", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-e4b709b61462b8d189d1", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-9d3f428ef8c764b1ff11", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-6fb2012cd72d02b2a069", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-17106154f47c826afcb7", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-49817d29e2e8721cf6b9", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0aa0a59420e90b9113f5", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-cf318af31bbcbc8c0d29", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-7172a28011c10712e8f9", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-db2b94c7c74a6265c7e6", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ed084452ce2ddeee614c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-deb5a4dc1d9142fb059c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-bd60bf10694d5c9d5bc8", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-fb4286b068bc0600cff6", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-0a2362b7454728723ffe", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e1e8d2a13c11230aa98c", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-47d80491960fd6ea310b", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5ca838b0d7d085b3171c", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-ceb18a89995a5f524bb5", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f3da7e372dfc4ca08dab", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d426008fb62238e11f84", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e5234b4868a1e6e63259", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5667dcada09f02da7767", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a5936ea729b375a90d68", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-851c77d2899e902efa36", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e931cfa2f01226c7342a", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-453ae6bd59490dfdbe39", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5c3b6be93f5a02202cd5", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-b23fad659ff994ab889d", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-cde96d244964d5994409", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f107c907c4348a32aca1", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-509e830745c3354e14d5", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-db2ce4b07c8501ec9f3b", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d382cb7aaf3e4dde02bd", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a965986d79fb4bca3819", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d78bdabf74a8b242644a", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-0491300e9f273d3b74ec", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-48709e4bb5bb0b63a00f", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-c6cead770cbf3fc9518b", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-080efc54b0dc8e811ea5", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-74973a25c3c43bce8cce", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a7a44dde52914c0071c9", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-12553b7460cc2837bdf5", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f55cae9cd9533c38a7a6", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f59d61c02b2c7a09133a", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-b1303a1aac807b19eb1e", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-92b87c696643ea1b04d4", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-7b2b019dd3c609469cdd", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-ad7b2bc9685eb10c11ca", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-72f9c4bf010a680a10e7", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-c64c6ba986cbf48dfa3a", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f58e0b20838b9a4ca914", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-fbcabd7c5459bef81b01", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5921d852f120985f8dae", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f30bd17b38dd9cb41e29", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-28f56886e057fff9a3f8", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0be7c63e66376c943a21", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-05804eaad67a72e87c55", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b06f1498b7addfe2ec70", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-689d97b4f6669135b2e3", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-a2fd0175220b1e48556b", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-db16da3b81fc24a094c5", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-a9cb86d09b5c5ba6e279", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-59103ebfd820f1f0b009", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-54c7e588d7908084d50b", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-bc478d4f6cdfd249d99f", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1f2b13ee7a4cdd84a1d0", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-76f259dd6574072ee661", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0feef2cd41b3a85c35e0", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-d8119eeec24c94a622c6", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-22a3a24869893190be61", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-7ae0cd8fff2cdb8b3288", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1982bb505636ac42295e", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-12622dc301433cc56db7", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-dee150aae3c0b6a546cf", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-5f4c5d30efd32f347e43", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-93329700c4d82fce10c1", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-6d645addce5b71832bff", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-24c9df9b1239a0816afc", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-5df66bf73307b0227fab", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-87c0ad6802e891c610fd", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-004bb5a4c7ce279a2068", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-244372a5806f894f72dd", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-65259994b4e78a13c1be", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-491aa709b5562551e288", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-bff86af42468bb73da3d", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0f23572f241895417714", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-7e0edac74ab36445f5bd", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b5b78f66f3a7517f8a56", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-08a7960db28b8ad2d7dd", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1d3540e3cdf5ee8762fa", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-3ab1714598d9893fe55d", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-aa150262c59632010cd4", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-6e283408eac06976995a", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-9ac12bfa0c8d453d385f", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1bdc05386ecfa31c62ad", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-4158474585ac03f92470", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-70a1f30aa14cad71fa3f", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b0db93e6a8a0402e442d", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-579ceb3ec7e0e7c2a058", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-9bc90e10e6b91381b1dc", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-14c472cf2848797472e8", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-d3fa95cf4dedc7407cd9", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-45f5a568a618398c2003", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-df9c2bbb8d025d633416", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0a6dee5b9d177600d5a8", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-8f64836f1c03f8d717e4", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-b4214300e6ac634d4655", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-792a2dbdf0f914f96ecd", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-22a5ed94932418b4b372", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-a632ad23423ba0506c16", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-77348d8cffa16737f1dd", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-623fad4c93a929006ed5", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9e300009a29a3180767b", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-4bd04bd342c6bdf7a25b", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-e0a456d9599734bf4dcf", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-103e07624403b62f7105", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-d07a101b915332333405", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f9ac6b159f7b68e08d1f", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-8f9455d971851037e69b", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-2ee0a5945c50d9e45f02", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f19f61a7a1c98a24d88c", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-65dd2ec52a2eb98f201a", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-6b93df0891d1e9824971", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-50103daef0af74cb00cc", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-26c20a0c8613a9c27c04", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-95ac367f79cfe12d6100", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0fa775711c5f64752304", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-ee450bc7384fa2bf264f", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-c9c9cf5e121268cd3c46", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-ca43428c5f3aaaeb4a6b", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9f3df52110132996acf1", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-d6a14bd3846cace85be0", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f815992e0057af92552e", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-c1936aa08e32e5571887", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-e4a6e8d9ad57f6261d57", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-64493da78eb55d39fce4", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0658f99f3c9a04fd2918", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-43884fe589ffc5240a6c", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-de63a41620e9a6fbb8a6", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9c57f1479f12611e3650", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-db263e0db17b09f39961", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-fa5dfd957b26f3982f9b", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eecbfcd48fd0b44da4", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7c987ef852f16f3323dc", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-b1e49c1b67e35ce90df3", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-a42dee36a9b3d9c4fa0c", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-bb6dd2a13ef876f27f20", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-f4bc95d33fa3669f089e", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-821001884db4778713ae", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-180bf4aaa10c590bd599", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-e6a6a636533e1ae93dfd", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c80ec0bb00165ef911a5", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-1ca51d9b23c4840440c6", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7529bbc5da7ba02e9881", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-249074f810c94193958f", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-5d6d4df808eaf0e9b59d", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-2fea8a03da06a8d155fc", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eebdf7a1b26709a4af", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c6f3f4dbe1114df7bca4", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3b6abffecd638d7e143f", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-435c729ed77736ac49bf", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-b1d56ff1e9d1586f27b1", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f48f91aa1d16a05778d3", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2f0d8d05fb5628452b73", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3237a1637bb73b6d11bd", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-87851356a1e1b9a04832", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7a52d540da49d844c3dd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2d1be2095bee8967662e", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9e91549ca39177fdc341", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9c6b842be6a0229603b2", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-da73608d2f06c5869eb0", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04000d17fec631057431", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-eafb41732c2d02fa92d6", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f1387f78049e2f96216d", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04bbff86779db8d424a5", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3cc599e6ea966ac42f1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-6c81f2fe32d5bf59df14", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-01382f9e44ebfe71cd1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7d7a52a1212aaa3903f9", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-e0bc3bdb9684a0cd782f", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-135d698a416df763c37a", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-5d1ce52c24eb280eaa53", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-cde9321fcd4606c1b6fd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3b4d510589021541d752", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-cf920f57a2f13b3ad575", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-57486584167b26522115", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00fb29fdb678665bd82a", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f41eb20d274264176967", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5ffb3fde2da7d4420c6c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-bf7338a3096200f9f48b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5d99a0f5b38ea58db833", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-15130b33d5a769fe6a32", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f4a165db0eeee2fbb2fb", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1e6f34f81abd19db2f8d", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5e430ce64b390617ee3", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-dadb0014a2da497a555c", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e14fb1f8f441e37f3b6a", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5fb5476b00f686e7097", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6ef2f1516fd5d9e51fc1", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1142eddf3eb99d81c770", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6f65c65f97d09691ecf3", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-b2bb869e9bfc30126140", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f7de42ba4922f372e409", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8b0033bf3124c2381b88", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ee91e94bc145ebbc752c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-0a784e55b980e4a768ea", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-53895d4a405ab4764718", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5a3db1f978360503899f", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ad82945116d93adc0ee9", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-34b194f9407279f8831a", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9dc273025bda0344f5c4", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1ada9c348b31da0129ce", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-fa685e4dcb072c9ea0ee", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-884c6de7c5b0cd3f6143", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8c085c86b98980387cca", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1d032d41a8812068669c", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-88075bd9b821bc49ad85", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e60dc36054298fb611da", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-a97693c8c3afea09a84e", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-878e0cb15d6a04d11f7b", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7d1e13e2a9ee5204d11b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7c59dad85dabf535d30b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8310d1a5474799c482fd", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-22b4165ec09c3e56b7e0", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-91e7fe297e8a037196c1", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3d9bb69b9a2c4e7a5f37", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-047950c0a6d89c18dc10", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9682b6f0bf28f0a6701e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-4c2944013559cfa3aa5e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-2f87e96dc17cd24bf360", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00da5bc0a7813116c372", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-d666f9cbd2bc867bad9f", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd5a610bd634cf860947", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-17ad59cd7db68e82d4e2", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-745d515c00e5ef36e018", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-cf379c3ac3906fdbd530", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-b7c2d17089053cba66fb", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-903dd2547aeab4333b8b", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd7bc21d13c67bacec65", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0cda73e045d032d47ee8", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2b2f887e4b2b9c1be8f0", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-c5b5c2f93a4e9a66cf63", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-357f232d33a60db07e3c", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7785bf4b3b17c1ff68a0", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3b960308df208119cf5f", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-a39e2d52b8853c5c18d0", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-65fd62ceac4a2b0de679", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f0a0ba282ce64661d749", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-544d30d9ac046c59b7d8", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-019ac6cec34bd5492707", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8f9ac72827bec9ca6d46", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f9edbb240e681f54990d", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-925ded2c1bd757ab65e0", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-494124c7cb25ce9c8484", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08ff1fea641c1071ce3e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-5fc0cb0bafacd337621d", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bda80a9e217d5482e64f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-42a6aad1e0fdb0089e55", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d6fe57647819834649e", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-76c4d4bf464d081a3736", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0f1cce7dc1de17a45a59", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-db50125db4f2a490fdbe", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bc0f9dca801bd308ea8f", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67f07edf6c0a08c6b68d", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-14422e8869a16392d3c8", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-58025407c8f1521df7d4", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-74c1f1904ce6d8baadb1", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2ec13de1e4838fba9146", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6a86cf5a20b7f1eeb2fa", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-eae7ba2c99c1bda33c80", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7525b67820217feb9c11", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-681bae4b93740ef5f0c5", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-90603a7bbeaac3ebac92", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1c9713c42a024b95bd44", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-13bd01f6910054eb3295", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88dfa403dc0f8ba0f199", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-93362782d6cd1c9b38e5", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-151d89deff8c82884589", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-af17e6f132f3601b9340", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-fd13688753dec32d87cf", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08bb1d125afe61dbdd5f", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6718d686298503531939", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0443b81b66ee434750e0", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67266454faaf86e9f82e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-30daf2d7d1aa4885ac63", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4939a26ab7be1b67bcf0", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f95651ee1387c941a464", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-54aa82fad20e6cdd81d7", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88ef3f5c7107b92df586", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f5a885749ae7733db165", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-18a5161d5a026f9fba04", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-98ca74f8f55d4b15d8a1", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-50cee2adb9a3c61f0dc6", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6bff7e83b5206fa9d91d", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8173f024a9d58630ef0a", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-da9ef20e377375a16f83", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b831b27287c07fcc40", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-691d00f15d0081cb59f7", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-845ac433ce41eb556d00", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0a674a144ccfb1d95b83", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e565aafcc819b2450df7", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-29089ac1a04857021285", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8ee8efd4c48b9758c274", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6acbb8df373136b70a54", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b30dc9529bcc05872a", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d4a2e7780e6d0550948", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3db8330bddd94096be58", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-38ee4ebbf8170b376a1a", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-51b82f8cec6133b560b9", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d2164eb08268dd10fa6", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-9bf6091babe12c0829ab", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-714d3a7f292b207efea6", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3aea2df8043c6a6e28a9", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-79d4c0f92c8e7ce5074b", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e83b0e3f4aa0610fd15f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d1ddd2034d35cc4620e", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-524159ddf174094337a1", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-ba7af307dca325c42461", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-833e9ff88cc7391a59b8", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6782edd72d6da4a4ad8d", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f252bd2fc447577759b0", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-3cfca19d21391eac95e4", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f888935069d847b893e1", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-8a27b9c33276ed364b5a", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6e57082f8837ec98eb4a", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d249488159d1321fd2bb", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-df992af2e935cf8992c4", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-80521267c3361388a69c", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-32b0ab4acd28e0f0c843", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2a9cd3695fb54d9983eb", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-e7b06471c09b919d19a9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d4cb7cdf6b423439b579", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f9ef3279fa413557bf74", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-4493fdd9f9a0b065a5d9", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-ff9db48194323087ff35", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-b3f7622fc945984018c1", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-9007396b1c807988496b", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-7720ba65254587e4220f", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-0dfab8dfb052a78725c9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-eb73224c6fba7201b543", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2206320b5471e792b324", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-42d36054a79412ea814c", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8a5fef92ae9112a22e17", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7c15928bbf9cf5446364", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3e105514fdcdf2109560", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b17f3a99113bcd921376", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-5a386ba920946118f5b9", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f152343084d96e444c25", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-19e34f584147a850810d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e6b47b2e4f1d89fdc1fd", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c54ff96a656f8f7e0614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-209d6e601169222401ec", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-0224c5f81d88e9a76abd", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bbf01adc9fea833a654f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-df809aca00e2b669dace", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-016cc1640e3b3d043bee", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-07dc4321a38968280cbb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7334ec778cda78e83768", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4a0c98327b25b0f53349", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3d4383aae663249070b4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ac1f881dcd7c9ea6b614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2fc6f4437794b5fcae1a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-affdcf01df5b548e74c3", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e69a2633d1da5da0a033", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-eed34e3a1de997f80105", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-6f3db740e84bd4583de0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75a2ce3c50f0326338d6", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-40d428be335e78a03d78", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1e51854f9804aaa89760", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f0bedbeadb96666727d5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ef9c82e81e4bc84eb35a", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a206e4dec77195448b2e", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b6a8e78c8bade555f99f", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1da818cd320f200493dc", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-37e8784fe2be118a89cb", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-baf78a292febd2d0253b", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2f67378d9be913549ee4", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ce42453036328047efb1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8354c7d516c210cb683f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c2c4c0e141302c3cef1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03df75134609c4dfbf10", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-23e94238a1be63a9aedb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-306ec942a307ac4b332a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-27ea66e30846c6c35d1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1ff068f72f09e1062c71", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-49268197eca684b03b23", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-45d66a58f8ace121aa3e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d55737ce84e01c268c81", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-de5ebfc899aee6d78694", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-80a4fc6eab4db076a7ce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d11efb83fe4bb3c07013", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8b874818fa453c7e6f49", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-644e384fedb167647bc1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-97913b921f13e91b4542", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-315d8c53bcd83acda5c2", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d511fccbe7e54abf3fce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bf9ed48af22e7dec6f9d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d8cac70b11a66ba978c8", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0d22129fdcac1480ab5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75861334d0fffb96d413", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4d9c22a343ef35f5b877", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ae3ab743fb1aecf74832", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e402f7c34fc93b9cb6be", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-946b1205dfcbfb6f7daf", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bd0e7d1620bf7e83e671", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-54c89f9444bb550d9372", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0913a2d6fc2540d8a18", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03dbb2c377fe45aa14c0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-066d3480dcdc71e8a4e9", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18cf581403b35016dd5b", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c7b04385144f290eee56", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18e90e6d63836e36b04f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-350e2e7d4721dc11ee0a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8ebec3e26df820a018bc", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-da28a74d360e5e5f4da8", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b87e2eed66add761c939", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1eb214dd7fb6d08cd588", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a9c047aa7f9899ee2e91", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ed84cf26fe663abba84e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b975a9d80a73ee2c5318", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2325734fcbe9f19ef38f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-53fa73e3d56972e17fb4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-68d9c42770fb755ff944", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-bf645b1a65cbfaea5769", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-9d765289d32be33b1358", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-aa26d2ab16bfa364ede5", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e05941de94496050665", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-07b5247e88feb728a1ea", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c585b499b392d1f3125b", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-807c73d105e8d88f3691", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-3a8724253f4ed9d64051", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0c1741b96b329426a59c", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-842c1a319c8ec887e2da", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e3cc6ce8bb29447e4aa", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3157016a1f4a564e4e36", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0bf30ca101daa48f2926", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-f15c420a1fe6dde01ad5", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-d062fb6e304335da8017", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ab3a301f236c4211d0b0", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-db1474abf9d021d54190", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3fad5bde9035571dfeb1", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-527a6a05cfabdad5e934", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-06d2174f2fcf7425f220", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-84b620f68a13175455c6", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65451ddd2f6fb97e5b62", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-91327ada1dd05e2a6298", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ea62643a3c6b46fbb710", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-122f023f6398972e230c", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-651f98b0f143502c508d", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65bebbe49c153c2d5f16", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-51c0c54a3382808aa510", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3670c81ddbb8cd20a30b", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-9d3c02ac24a72b007bac", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-62ac1fcd49c58719b731", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-a0a212ed633e0fcae542", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-fdf8e58e63293f008154", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-6749a7d57a0a08031b98", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c71eda7665d7fe280226", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0f9982e28da4776b41df", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-0b84034df4da7a0602cb", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-27b7b29e95483cbd0627", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-c501a3337d7f3459c0bd", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7590e561a95171418094", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-ef943cb95bbec2be8e9f", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-35d168c9c28975e08fe1", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-15f9f09a8e027b4f1453", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7ac5238b9dd76e5bd284", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-cbdca6544e577990fbe6", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-ae0fe968cf56f04deadf", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3ea053475afbb979f768", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-e717f553b51ae759828d", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-36518c4875e5c6c5eb4d", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-e4dbbda8c6e5556ff597", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3aa635296202313cceb6", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7889e72271358857e901", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-80303351d5af14d7bcba", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-6303b616b2bb5f58f229", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-b18b5d8413c96e250a43", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-cdb048780d3502ba5f34", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3cd51c32262f07831a10", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-bdd8944a779d3e0838d2", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3ea1350b66dcf3b9e182", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7e155f3c5195944a8163", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-47bf44da43f7ea630c57", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-94a91f70513a4f3a0536", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8bed1f155fdd13a8d676", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-76ae798ce585defae260", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-940ea42ed81a2e76857e", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-fe6258362fcc32df0641", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-3976dbe5125baf9596ea", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-e85621f95b6a8e48ca8c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8aa46f4bdea9ab2db828", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8da0c6598ba3b3f02663", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-d7bcbbb91d28521d7e10", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-737ee111c8455e9547dd", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-0a0f67812bab08126d1c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-dbbe30e49f81e686c544", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-81ecbd7fd933b26d5381", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "901250e5b1d03fae9f224a84330c21ba5f73a7038f6b3b39fc059e2a20016b7b" + }, + "legacyBrowser": { + "stats": { + "startTime": "2026-09-11T06:18:04.003Z", + "duration": 348563.66, + "expected": 1458, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "member": "artplayer.legacy.js", + "sha256": "78bc02363b7c959c533acbea89f1220538b2bccaad6a5dd4bbefb4586eff4d49", + "featureCases": 129, + "featureCounts": { + "screenshot.spec.js": 39, + "thumbnails.spec.js": 24, + "progress-quality.spec.js": 42, + "source.spec.js": 24 + }, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "nativePip": { + "chromium": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.030777, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "firefox": { + "capability": { + "enabled": true, + "request": true, + "exit": true + }, + "playback": { + "window": { + "width": 320, + "height": 180 + }, + "currentTime": 0.170062, + "events": [ + "video:loadedmetadata", + "ready", + "video:playing" + ] + } + }, + "webkit": { + "capability": { + "enabled": false, + "request": false, + "exit": false + }, + "playback": null + } + }, + "knownResumeRejections": [ + { + "browser": "chromium", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "chromium", + "core": "candidate", + "rejections": [] + }, + { + "browser": "firefox", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "firefox", + "core": "candidate", + "rejections": [] + }, + { + "browser": "webkit", + "core": "published", + "rejections": [ + { + "name": "Error", + "message": "controlled play rejection", + "same": true + }, + { + "name": "Error", + "message": "controlled play rejection", + "same": true + } + ] + }, + { + "browser": "webkit", + "core": "candidate", + "rejections": [] + } + ], + "knownScreenshotRejections": [ + { + "browser": "chromium", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "chromium", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + }, + { + "browser": "firefox", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "firefox", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + }, + { + "browser": "webkit", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "webkit", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "rejections": [] + } + ], + "blobCapabilities": [ + { + "browser": "chromium", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "chromium", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "firefox", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "firefox", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 320, + "error": 0 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": true + } + }, + { + "browser": "webkit", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 0, + "error": 4 + }, + { + "extension": "webm", + "width": 0, + "error": 4 + } + ], + "ownership": { + "afterSwitch": "TypeError", + "afterDestroy": "TypeError", + "revoked": 1, + "size": 251538, + "assigned": true, + "decodedBlob": false + } + }, + { + "browser": "webkit", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "native": [ + { + "extension": "mp4", + "width": 0, + "error": 4 + }, + { + "extension": "webm", + "width": 0, + "error": 4 + } + ], + "ownership": { + "afterSwitch": 251538, + "afterDestroy": 251538, + "revoked": 0, + "size": 251538, + "assigned": true, + "decodedBlob": false + } + } + ], + "qualityEvents": [ + { + "browser": "chromium", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.147891, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.147891, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "pause", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "chromium", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.148883, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.148883, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "firefox", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.427199, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.427199, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "firefox", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.422141, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.422141, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "webkit", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.2818284, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.2818284, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2.0020388, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2.0020388, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2.0020388, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2.0020388, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 2.0020388, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0020388, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2.0020388, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0020388, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 0.0006425, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 0.0006425, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "webkit", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "events": [ + { + "key": "playbackRate", + "value": 1.5, + "time": 0.5189017, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2, + "time": 0.5189017, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeking", + "time": 2, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "seeked", + "time": 2.0019109, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "src", + "value": "/test/pattern.mp4?quality=A", + "time": 2.0019109, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "event": "ratechange", + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4" + }, + { + "key": "currentTime", + "value": 2.0019109, + "time": 0, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "loadedmetadata", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "playbackRate", + "value": 1.5, + "time": 0.0012139, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "key": "currentTime", + "value": 2.0019109, + "time": 0.0012139, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "canplay", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "ratechange", + "time": 2.0019109, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeking", + "time": 2.0025077, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + }, + { + "event": "seeked", + "time": 2.0025077, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?quality=A" + } + ] + }, + { + "browser": "chromium", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "canplay", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "chromium", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 2, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4, + "paused": true, + "seeking": false + } + }, + { + "browser": "firefox", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "canplay", + "time": 3, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "firefox", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 2, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4, + "paused": true, + "seeking": false + } + }, + { + "browser": "webkit", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "events": { + "beforeSwitch": { + "time": 3.0016665, + "seeking": false, + "paused": true + }, + "mediaEvents": [ + { + "name": "seeking", + "time": 3, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "seeked", + "time": 3.0016665, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=initial" + }, + { + "name": "loadedmetadata", + "time": 3.0016665, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3.0016665, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 0.0011001, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeked", + "time": 3.0016665, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "canplay", + "time": 3.0016665, + "seeking": true, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + }, + { + "name": "seeking", + "time": 3.0035397, + "seeking": false, + "source": "http://127.0.0.1:8084/test/pattern.mp4?custom=next" + } + ], + "calls": [ + { + "thisIdentity": true, + "ownerIdentity": true, + "videoIdentity": true, + "count": 3, + "url": "/test/pattern.mp4?custom=next" + } + ], + "restart": [ + "/test/pattern.mp4?custom=next" + ], + "time": 3.0035397, + "rate": 1.5, + "ratio": "16:9", + "paused": true, + "error": 0 + } + }, + { + "browser": "webkit", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "events": { + "overrides": 1, + "seeks": [ + { + "time": 4, + "seeking": true + }, + { + "time": 4.0006753, + "seeking": false + } + ], + "writes": [ + { + "name": "currentTime", + "value": 2.0021689, + "before": 0, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 2.0021689, + "seeking": true + }, + { + "name": "currentTime", + "value": 4, + "before": 0.0013593, + "seeking": false + }, + { + "name": "currentTime:after", + "value": 4, + "seeking": true + } + ], + "time": 4.0006753, + "paused": true, + "seeking": false + } + } + ], + "cases": [ + { + "id": "3c9d5ff5a17ae653dea9-f4ec85bf2b8fccbf87d3", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-92813800e1301b551fd5", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-c9ceaa1dfcf855c601b8", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e3ad9a2e558a2a865aa1", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1e6334e252a4eaa99157", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-949f11341529012e52e6", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-25c2b76fcc6c397aa5c0", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4f5f4ed634525c07b8dc", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1f1fc11f543db6e79ce8", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-d005b6ae9b0d6728bf8c", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ee0861705ad7987b9373", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-486fd375ad053eadbec8", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1ccde517b70725215290", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-114616f87a72c9199052", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-d45701b9ec2e94b1c2a0", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4d016c4954c8ac6cd389", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ff618818b5add9a867f0", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-532ba0fa22ce76077251", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-545631e0fcab6e19f14e", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ad4abc5fde8cf38cefcf", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ec0620ff5c9501117ca4", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e6b4bc21c6783ac134ad", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ea18bdf25cac41af6e2e", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-6c12e77cc7c16d1f2b89", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-f020f7ee612d0431af8b", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-1e8bc6f4219030568692", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e0e498eb32391ec00ddb", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-0db526164287c9cc7775", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-e2207b0298c6dd9adc1a", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-4066cb1df299d5885460", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-c7af31684e3e62c64702", + "file": "auto-playback.spec.js", + "title": "published: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-726bde899520b514a36c", + "file": "auto-playback.spec.js", + "title": "published: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-b89c5b026f849456ba91", + "file": "auto-playback.spec.js", + "title": "published: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-458e99a71a6974d07a80", + "file": "auto-playback.spec.js", + "title": "published: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-597946b7614265121e43", + "file": "auto-playback.spec.js", + "title": "published: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-8520c4db170de4de357b", + "file": "auto-playback.spec.js", + "title": "candidate: resume close and playback rejection preserve the UI contract", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-f70ab3d8a77a9f8fc061", + "file": "auto-playback.spec.js", + "title": "candidate: resume API retains storage envelope, ID lookup and deletion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-be9f42770a55bc5fa01b", + "file": "auto-playback.spec.js", + "title": "candidate: resume button seeks and plays actual video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-2d0bd1e8ff578b45e6be", + "file": "auto-playback.spec.js", + "title": "candidate: repeated restart leaves one effective click for the current resume target", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-23eeb147e099fabf6613", + "file": "auto-playback.spec.js", + "title": "candidate: restart below threshold invalidates the old prompt click", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-09605c2a70067e7bc3f7", + "file": "auto-playback.spec.js", + "title": "candidate: restart cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-6ff8f2f1a7c9a48d69a4", + "file": "auto-playback.spec.js", + "title": "candidate: source cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-ac54090c4c2cf5fdc028", + "file": "auto-playback.spec.js", + "title": "candidate: remove cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-fd6c5318117c46dd0942", + "file": "auto-playback.spec.js", + "title": "candidate: destroy cancels obsolete resume timers and subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "3c9d5ff5a17ae653dea9-51837a568fcb8a51ca77", + "file": "auto-playback.spec.js", + "title": "candidate: destruction inside seek prevents resume playback continuation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e250a78531a8c3d95feb", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-58433fd5f9d1792004a9", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-8a8eab049510e21abb09", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-0c6a909338c7a7e4ee81", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e44e5236ce97dbcc66db", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e218dab15f99202a9d9b", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f15b34474cf3deddb46c", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-68feafc04a4e200bdbbf", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d4a9b70e95a88f5f1b6c", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3bb4aa4e8591f74e9b51", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-77661f6e8549e2f2b0f9", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-fdef85438132665e82d5", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-7830d06c46b9c5ba6161", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a15c4c84c5b25cf34822", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e181d716af04e58eab65", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-282f85fc06d22f36392e", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a5586b42e67bb73c8576", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-45123d301b41869a88d6", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d401b1da991706ec9c93", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f198b861d3aeb3aec6dc", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e736294669adfc2fbd2f", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-1ea861945628ec3c983e", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e5aa6981246d2e9207f7", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-b181ca104e1c603cf7b8", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-2d43188e99ff2f841723", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-0f34df57efafa8c0edcf", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-e30bae571949edeb2a20", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-aa47bf8b002eaa057b68", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-957389ac7668163258d2", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3bd3803675891e50e1ae", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-acf581cc432a521849b5", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3eb4f85a9aa1ae1d0ca8", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-f7eb5ce9abd5de8ed3f4", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-ff8e57c46b92463eb08b", + "file": "builtin-layers.spec.js", + "title": "published: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-a145acfa8d4c0614b1f2", + "file": "builtin-layers.spec.js", + "title": "published: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3d2a53683618e68ad9e0", + "file": "builtin-layers.spec.js", + "title": "published: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-98127aaa83cf106f5466", + "file": "builtin-layers.spec.js", + "title": "published: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-5dde60f90d9a6c95eceb", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-904fdf6574fa22097ec1", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=true live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-16541fd5ca5023a4e37a", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=true conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-3637c50e1b3c01c6f660", + "file": "builtin-layers.spec.js", + "title": "candidate: builtin availability keeps mobile=false live=false conditions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-d47ad23d299af2e963b9", + "file": "builtin-layers.spec.js", + "title": "candidate: lock keeps public state, repeated events, DOM classes and icon switching", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-c3f87c91054205687e8f", + "file": "builtin-layers.spec.js", + "title": "candidate: removed lock icons stop observing the still-usable plugin state API", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-db0f475014584baf27ad", + "file": "builtin-layers.spec.js", + "title": "candidate: miniature progress follows the control event without adding public state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "cad532275e083421260e-c3f57d25a9d377e5ee53", + "file": "builtin-layers.spec.js", + "title": "candidate: retained builtin setters and events do not mutate a destroyed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-13db7df9f8d700edda79", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-af27eb5638cea6dfe907", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-14c8ec42e6b63b71f7af", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b9949b48fb7cde7ed81", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2474cead0e45468fdf72", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-92f6a6d9a13ed0db69b7", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c38f55e5356c80555777", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ce5a4349c94e7573f2df", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-745cf7ee3dc9fc8920ea", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7034aff5865b19493d48", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3f7f11168066bc1135dd", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-98f452e8fc88900fbf7e", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-c075e9d7be551f55dc98", + "file": "chapter.spec.js", + "title": "published-only observations: blank title, NaN and once-only metadata are historical defects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2bedc05faa553d9d5e75", + "file": "chapter.spec.js", + "title": "candidate clears titles on blank chapters, zero hover and replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-2d30e8fbce3826e3c15d", + "file": "chapter.spec.js", + "title": "candidate rejects NaN and can recover after an invalid update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0a87800d172dcd9435bd", + "file": "chapter.spec.js", + "title": "candidate releases only its listeners and DOM across multiple instances and early destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf7e525a2755f0c86bea", + "file": "chapter.spec.js", + "title": "candidate ignores pending metadata initialization after immediate destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-e4470972e51039dd2948", + "file": "chapter.spec.js", + "title": "candidate deduplicates stylesheet injection while the document is loading", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-259434dce8ad5217c100", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-7b3ff84e07f9b6519b6d", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-03a359bf96cac72eec10", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-3e3a0590e83bc657c777", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a94d3e2e3468e36b53c4", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-a4513ef73bb7d291b1de", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-907cb350996072e49f76", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1f07c4052b68dcd5fcb6", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-dfbf83aa28cd6f99e6fe", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf995dadc1257e9111fd", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-cf0c802aa1332ce3f50c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8828838dbabcde8784a4", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-d78fda3b4a4f188bca8f", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-4997157ab3e3b52575df", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-8dca6d7565c27e3cf00c", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-0dc7ef53e5e6c1c6a095", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-41d8436843ab4e0c4a53", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-22beee8392c7138d3eef", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-db259a3d649f557bdd8d", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-6ee40eab9446590238f7", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ac09580cff29b5c26244", + "file": "chapter.spec.js", + "title": "factory, registration, input normalization and safe title text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-191c4adbf7f0bfd11d22", + "file": "chapter.spec.js", + "title": "progress bars, real hover, title edges and boundary seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-1d69886cc1563158b162", + "file": "chapter.spec.js", + "title": "sync update, Infinity, object identity, empty lists and invalid data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "aa892263c892083d7932-ccd2c30f32a17586ae47", + "file": "chapter.spec.js", + "title": "explicit source update and core-owned destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b64859461b5705d1cf09", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cddd0b156a2290520d0", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a0ff31c497eb06cfdeb4", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-48a8c2fa6b32442681fc", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ae60beaef7bc0cc1c93", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b405a3930560f4a322ad", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23975233833f7314852d", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a2216a5ae190e64c0c28", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-fb9f50f4c4f1cf9a81f6", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-537c7bebe8e335d5ad67", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c9beea42f671df625472", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1ba81907a4dbfb985f88", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-72fc63307e889563b0c8", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-955901b7c9b5f75c7b1b", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-05c9a93bd36ae4d71ecb", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-75d44a2ac5d30638ab32", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8bea5b2d30fc513648e3", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5e1987406b361d07632e", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-0444b7d85afc918256d7", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2f11ca271cc2f6668307", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b2817b31801e2c0549f4", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c0ae2825f95023de5382", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b0fd67600676be07f53a", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-646cffec899839d783a5", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a4bacc2b948ae9988139", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-5de7dc1781c68d66d249", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e2e82a24bc140d731d62", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e771059bdaf24920387", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a67e3762e19c71f868db", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e199356f63d8d0e7e9a2", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-40af3bb8e336fdc2335a", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-621ba9de5d94c05b5cf7", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8317098f87d1859e2dd5", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1c8e447ad7f0fa9e8eaf", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bfbc2bed73e613bd99c8", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d36a9d234b493b84426f", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-bd1fba69aa773e1f9339", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d3a7712862581da5e75c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2107d278212d36d8da0d", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6b4fbf1d3182b04d96c1", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-04f3c73d8294ca07e6d6", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-8ca066bc5b5eae539a24", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d330fa833123b6b20ae", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4c8fd972f78dd9f2f4f5", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d48bb7baf38a31478a96", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-374314906befc5bd4abb", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2c8af0a3cc8135d1ecb9", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-ccba8bf8a8ae879bfe04", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-71c2187dfae3d083b25f", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-9cbfad2cb618fc3df484", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-479da8672c58208a8f64", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6d058a213fa9dc91b39f", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-de54752fbbd7c23b614f", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4f31edb98158d9461c54", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f28b63981b091141e37e", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-84ece502b0a7e2f6b7b3", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b4e97f806f7889922a7a", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-2743285543496df7fe1b", + "file": "components.spec.js", + "title": "candidate: control layout follows resize and removal with observer fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-d6434aa47c57afe2cba2", + "file": "components.spec.js", + "title": "published: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-6dde4465bb116870696e", + "file": "components.spec.js", + "title": "published: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f07afacdccdf8d37a3bf", + "file": "components.spec.js", + "title": "published: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b9585d2981c5e97120e9", + "file": "components.spec.js", + "title": "published: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e94b71940033ec64bfb2", + "file": "components.spec.js", + "title": "published: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-b501659d6692e6a3aef6", + "file": "components.spec.js", + "title": "published: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-605545662d878960f7e0", + "file": "components.spec.js", + "title": "published: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-62a855d83edae78c8e0c", + "file": "components.spec.js", + "title": "published: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-e5ad7ffd21eb01026e3c", + "file": "components.spec.js", + "title": "published: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1cdbb2d211601ad9049b", + "file": "components.spec.js", + "title": "published: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-a1482fe33812e30491bd", + "file": "components.spec.js", + "title": "published: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1b4a508565aad47f08a0", + "file": "components.spec.js", + "title": "published: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-eed9dfd6f3a3915a8ab5", + "file": "components.spec.js", + "title": "published: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7b1c657eabadad7a4e0b", + "file": "components.spec.js", + "title": "candidate: selector background clicks and rejection ownership are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-7e9a8def3dbc766cbe9d", + "file": "components.spec.js", + "title": "candidate: beforeUnmount errors remain retryable and detached nodes can be removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-226371bcad54f04cadac", + "file": "components.spec.js", + "title": "candidate: failed mounted reentry preserves its successful replacement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-593c07ca263ec7a933ff", + "file": "components.spec.js", + "title": "candidate: context menu builtin selection and owned updates preserve state", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-664754e838f49dc96b98", + "file": "components.spec.js", + "title": "candidate: a prototype-named component keeps the registry prototype intact", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-195208b0571472607e96", + "file": "components.spec.js", + "title": "candidate: component factories, ordering, bound methods and update hooks retain contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-f85d899f5dfcccac78e5", + "file": "components.spec.js", + "title": "candidate: removed builtin time and volume controls stop owned effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-92f3e716e64a7953a41d", + "file": "components.spec.js", + "title": "candidate: selector items can be reused by an update without changing getter flags", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-1aff62157f9fbb1f88fa", + "file": "components.spec.js", + "title": "candidate: async selector results cannot overwrite a newer choice or removed entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-4a9550c051b51fc07942", + "file": "components.spec.js", + "title": "candidate: a failed mounted hook rolls back its DOM alias and listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-23bc5dfcd88b2bdfca32", + "file": "components.spec.js", + "title": "candidate: reentrant beforeUnmount removes only once", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-14920589fd5937fe2097", + "file": "components.spec.js", + "title": "candidate: narrow controls stay inside the player without hiding buttons", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "5d82eb8ae2e037f56f4c-c22d9f44fdf7f96acb27", + "file": "components.spec.js", + "title": "candidate: progress markers treat text as data and removed drags cannot seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-bce9960eb782bf3b388d", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3d865d3ab8a953516b83", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-3971824465d64033c64a", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-784699458b9db440715d", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-e56018edc0c598cfe3a6", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a0ff3ef97b2bbf67fef0", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c38fd837350d34f82b4d", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-75441bab4ed44b490b3f", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-d07660cba382135f5e45", + "file": "declarations.spec.js", + "title": "published: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-c8126a2ca83e05a31885", + "file": "declarations.spec.js", + "title": "published: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-a4be546819cfd9b17a99", + "file": "declarations.spec.js", + "title": "candidate: plugin, toggle, setting and static runtime return contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1b65efa5561c4984e2b6-43b0ce05e60dabcf63cb", + "file": "declarations.spec.js", + "title": "candidate: native subtitle update events carry cue arrays", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-215c4e43e0c210b6c91e", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f51783956841921f653a", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-060b7fef9ab61ca8b51f", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e0701300b28eb93d84b2", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3ce10fb9e5feb9de0209", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4470a8c5dcdf58209d68", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f0b08a105464db873a3c", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-77370983ec73972d14d0", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-cd81168e76f3e6f8034e", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4b38710a4241fb8efe81", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f08ea1ba290c5e0de00", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-932ce5acf10f04835f38", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6f12d4261b9f612c4afd", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3e31af20014f27ee9e5b", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8a5dcabf07024f483997", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5ca7623e1e9824c6ccc6", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-6b3e80d3ab9d74293e49", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a469168f1d396f999be8", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a555e0648a8c5972e35b", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71749fdef4307b96761d", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4edbd5dc212ac30a7bee", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-83c2f8a16d078a06d1ae", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3f48f4cc7fc5d5e9e98c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f413428a3ac2b2788921", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03f107aa3c92549e8cec", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c63150bb39f74f89e359", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d1bedef93dbb2da29830", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7ac118b7169027c52d4a", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e6d71f296f035bd569a0", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-641c8ca6813a23b668ea", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1da7888e6f7a6eb19da5", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d25b39ad88db7e7b2bff", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3d8d63a748da48094a7d", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5c17ee11f56d60e5daf8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-979bc6ec3ee848383b3d", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-a51cb8dd4bd7141ba7c3", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b8361baced0cd1c4884b", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-4a7f7248dd0e4bb4d117", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f1dbddcb8b6c55bf6abf", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-c28aa23669da794975fe", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d74f1148dcffcc4ba48c", + "file": "display-mini.spec.js", + "title": "published: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d2c53e913102a1af553f", + "file": "display-mini.spec.js", + "title": "published: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-96841fb451ce9297d393", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-7c96036f21956e3c646c", + "file": "display-mini.spec.js", + "title": "published: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2ffb342b36c816963ff6", + "file": "display-mini.spec.js", + "title": "candidate: mini retains first-entry and reuse DOM order and display", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-87a697176faffed75607", + "file": "display-mini.spec.js", + "title": "candidate: mini restores the original video parent and sibling after repeated entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-8ec24e59d1f42fe9d061", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=false removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-d263205b93ce3716eed1", + "file": "display-mini.spec.js", + "title": "candidate: destroying active mini removeHtml=true removes the owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0f43609b9bcf28f089a3", + "file": "display-mini.spec.js", + "title": "candidate: hiding mini cancels drag and later document events cannot persist a hidden popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-5448bcd8bd74bca095fa", + "file": "display-mini.spec.js", + "title": "candidate: mini remains in the viewport on small screens", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-e9ece5718b190162c6bd", + "file": "display-mini.spec.js", + "title": "candidate: mini drag stores the actual position and playback buttons remain usable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-03a8016bb2aaaf868aeb", + "file": "display-mini.spec.js", + "title": "candidate: mini exit failure keeps the active video and can restore on retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-2e1de5378e019cdbb636", + "file": "display-mini.spec.js", + "title": "candidate: mini reentry during restoration retains the new placement snapshot", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-b32fa9f007198c281028", + "file": "display-mini.spec.js", + "title": "candidate: mini construction hide releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-f515d4587be9d12105c4", + "file": "display-mini.spec.js", + "title": "candidate: mini construction destroy releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-3afffa70279f302e77e8", + "file": "display-mini.spec.js", + "title": "candidate: mini construction fail releases incomplete UI and restores the video", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-1d8ce60246227b370e0e", + "file": "display-mini.spec.js", + "title": "candidate: mini preserves a caller-owned popup on destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-71ebf721d07c19796847", + "file": "display-mini.spec.js", + "title": "candidate: reentrant mini creation allocates only one owned popup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-672938aad25b617e5f32", + "file": "display-mini.spec.js", + "title": "candidate: mini switches to body web fullscreen and restores the original video placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7fe83a2e91ec089f5974-0435322e0776c1c6db98", + "file": "display-mini.spec.js", + "title": "candidate: destroying a mini drag removes its document subscriptions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-23ae836ca899325453cc", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5d87bb95ffd4bf65a4f3", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-0e97734020dcc6df9f26", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8bacf1c1c56de38bdcbf", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-51e147e0684036397c1e", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-59dd6298bfbfea94c275", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-8c03ebd32e75e51f8e34", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-f4f0db9972fcc34e2ab8", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e09e6f9d356868edfd1e", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7968deae0894a7a41745", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d2ce1a7a9b2ffa66c042", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-2d2e74a3704d6964ff64", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9f45e376ea3da4b17c32", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-44525e439ead5cf1926b", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-13923f8d94a0d0ae4937", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-b30f9705bca57697114f", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-a7d18ff2f641f5cbf514", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e0a0990679eba59f084f", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-d07e0dccd2ae40c36625", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-588c0d140bf9efd60a8a", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7d51b759d72f50c2e069", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9aa04acd042f2f815772", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-83c5a739fd19c1ee758e", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1be5ce38e6088062d978", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-266740492e18fc860ae6", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-5201d0b8a57c2e862249", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-40e808dd1c844558cac5", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-691006a324af76b53d61", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-3a3389d22af8979f8eeb", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-c40ad10afeb67ea2e850", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-10149aeb19bf6697c9b7", + "file": "display-native.spec.js", + "title": "candidate: void exit waits for the owned video to leave and accepts another owner as completion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1c6ef5e75874838d7120", + "file": "display-native.spec.js", + "title": "published: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7ebd0a99b0afcb231926", + "file": "display-native.spec.js", + "title": "published: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-dc5e7d775e8ad4bec7f4", + "file": "display-native.spec.js", + "title": "published: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-e4d66d69d8df88578432", + "file": "display-native.spec.js", + "title": "candidate: native fullscreen belongs to its player and other players cannot exit it", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9c425dfa5bfae0c980c2", + "file": "display-native.spec.js", + "title": "candidate: destroyed players stop receiving later native fullscreen events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-17eda50816e6fbbbca7e", + "file": "display-native.spec.js", + "title": "candidate: rejected native fullscreen request removes its temporary change listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-efabd841d061bb9e2536", + "file": "display-native.spec.js", + "title": "candidate: fullscreen assignment rejection shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-1f196ca428edacef09ee", + "file": "display-native.spec.js", + "title": "candidate: reentrant entry preserves real fullscreen UI and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-4ae95e66ac42d7d03f9e", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-6c413f210385d70a7d80", + "file": "display-native.spec.js", + "title": "candidate: pending native entry promise-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-86d59b7185aae72ca502", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-exit releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-9a9e65a49548f6b4d6a9", + "file": "display-native.spec.js", + "title": "candidate: pending native entry void-destroy releases a late own entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-509e6f68a4e4efa344a5", + "file": "display-native.spec.js", + "title": "candidate: cancelling an actual native request in the initiating click releases fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea14eaab73c72643e734-7f99bc001b5cb7f460ac", + "file": "display-native.spec.js", + "title": "candidate: rejected exit retains actual fullscreen state and can be retried", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-39784f83c5a20ae25922", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ae72eb701fecb9af3759", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c51f1e6e8e3e150cf656", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93d2a37ad53cbfa50f40", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e1fe2e4b9b734ba3d131", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f72eb06a65f80253993d", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7ce46c729250e79cb277", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-150ad3f2de69d36e8b82", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-130924bf85ce0603c3c2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-76381e5bda48a5ade3a2", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-a0ff15ba8484c82eb5d4", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1dd95d3d390501835602", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-4895669ba1966f650b48", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad42062f96fd6eff1e57", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-f3aed2b29f46acf70e9c", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-d4a7ab2fb9f82bf30b31", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-1aa42586b0131c02286a", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-ad1af31ee3dfc38e3f6f", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e6fe305f0c0d3313abc7", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-cf1964446ac3f3a005d5", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-7bfca3da1efa390f1d78", + "file": "display-orientation.spec.js", + "title": "candidate: a cancelled rotation timer cannot rotate a later fullscreen session early", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-3bb82b015b925c65648f", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-c0677c484632220c9e08", + "file": "display-orientation.spec.js", + "title": "candidate: rotation destruction restores styles and cancels subscriptions removeHtml=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-2d734612eafbf347a12a", + "file": "display-orientation.spec.js", + "title": "candidate: destroying a pending rotation removes its timer and produces no late resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-9317141fd45591056bf4", + "file": "display-orientation.spec.js", + "title": "candidate: rotated playback supports ratio and flip changes before restoring normal layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-48e2f8d5a7ed9f6bb5a0", + "file": "display-orientation.spec.js", + "title": "candidate: repeated web fullscreen retains rotated dimensions and final styles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-e20a77918392d00be03d", + "file": "display-orientation.spec.js", + "title": "published: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-de4bddf17cef4be77029", + "file": "display-orientation.spec.js", + "title": "published: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-93ccbb4b069002b19fa2", + "file": "display-orientation.spec.js", + "title": "candidate: rotated web fullscreen restores original inline geometry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82e9aa99dafaec340dc9-0874de284439b96ad2c4", + "file": "display-orientation.spec.js", + "title": "candidate: late orientation lock after fullscreen exit does not reactivate the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3de9b990facdeff0476c", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-749a7d338b2101206765", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e6382df01316fb281fa", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3bc55ca3eb9f410ec0e5", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-90f2213c5aab99e4e570", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-1dfa2ee5c94403260245", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-86b43820f5b552d786cc", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3dd543ca3a3090d34fbd", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-c8c02cdc6e6c0fc1420d", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-9a4914e43bb12fbeb582", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-769b87498109362f84fd", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-3e4973914f06c39b6698", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-083974800f2e8879ae1b", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-641a2dccf8325c290c99", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-4ae457363eab61ca9ae6", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-8194bd99f36b6e951031", + "file": "display-pip-webkit.spec.js", + "title": "published: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-fb2e3177eb20d90269fc", + "file": "display-pip-webkit.spec.js", + "title": "published: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-2b7df84230e1938edd1d", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP keeps boolean state and repeated synchronous setter events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-ab2589367119fda8a5c2", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP follows native UI transitions", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-50ff4f070fa19d28d259", + "file": "display-pip-webkit.spec.js", + "title": "candidate: destroying WebKit PiP returns presentation to inline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1894451b6add403294b1-e3c66306c7b25f4f4e08", + "file": "display-pip-webkit.spec.js", + "title": "candidate: WebKit PiP pending entry is cleaned up after destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-aa481f1919609650e0a3", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-5f4c93857986beeeb8a1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-bd3d36fb7c393b6fb340", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-711513ba84f86888eabb", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-218ffe39dd11365c7b9f", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-39b746d120824d46ea24", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7faad1910240a59dd0d1", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-25a6bf8bad817690412d", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b29b1c45e6d1ec961272", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-667bbcd209351537a529", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-69c72083a6301a7b0a95", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-967a82e04705cb8ce7f1", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4b3a751945fffd4f1a50", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-d7bd4e5eaff49ff3f6bc", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0130a4a91c9404610c5d", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-6bb9d58f98fdcd85523e", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-38e55045d1be4acd5358", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-3b5e09ff69da4caa4ced", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-83bac7c7daa4e1fb0eee", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-0c5ae0e780b7c4cd4531", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b025eb13913d88dafadf", + "file": "display-pip.spec.js", + "title": "published: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-8afabec893b951bc9dca", + "file": "display-pip.spec.js", + "title": "published: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-1347f52c5334f122e18b", + "file": "display-pip.spec.js", + "title": "published: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-338fd2cfd69b416e5e22", + "file": "display-pip.spec.js", + "title": "candidate: native PiP preserves element/null getter, void setter and boolean events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-9b82c9a55c0a272c73dd", + "file": "display-pip.spec.js", + "title": "candidate: a player cannot report or exit another video's PiP", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-e2033bcf8e8df5d25107", + "file": "display-pip.spec.js", + "title": "candidate: destroy releases active PiP without a late player event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-820a88dbf4c7c26b97b7", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP cancel releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-4bf4e63de030442894fd", + "file": "display-pip.spec.js", + "title": "candidate: pending PiP destroy releases late native entry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-b3c6572e746e10e018ea", + "file": "display-pip.spec.js", + "title": "candidate: rejected PiP assignment shows notice without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f61d061d69b9fc65156a-7b9ff7b1d7be3cd2c923", + "file": "display-pip.spec.js", + "title": "candidate: actual native PiP gesture and playback or explicit unsupported capability", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-33f5644884ec9ba86bcc", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-2b06e449e9aee6d0450e", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6941bd46497d1d2ed300", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fe227b73432db99c992", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-c0d916d83a69c0da121a", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-bafeb7f5931093c7a39a", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-cc32f7d91ce9e4df9fc0", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0ebaecb2cd423a62fcf1", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-63d5f364fb9be03dfb3d", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-4e88cd81c30b7e5827c8", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-6e8ac8042e4aa05ddbb9", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e86d33c92dc30d00cf21", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-b7a4cf05e951b7de5920", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-d8b9352760cb4971e37d", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8fef1588177f24706032", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-e50eb3463d090abc7b88", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-ccb72602fd5954f2946b", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9b9158caa8753869e593", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-8a3807010e3dda6b493c", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-aa894c121cbb637c2356", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-1a2ebfdf05d5e3422606", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-dacf4da548671cffcf41", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-3fb0d0152310ce81c940", + "file": "display-sizing.spec.js", + "title": "published: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-a2863c68ee28f3519445", + "file": "display-sizing.spec.js", + "title": "candidate: sizing methods remain detachable own properties and ratio parsing retains legacy coercion", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9a88c32f828a7664851f", + "file": "display-sizing.spec.js", + "title": "candidate: hidden containers defer sizing and recover after becoming visible", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-0d55461371288f7574df", + "file": "display-sizing.spec.js", + "title": "candidate: malformed ratios preserve layout while retaining notices, datasets and events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-daaefa1bb396ff5f0509", + "file": "display-sizing.spec.js", + "title": "candidate: retained display setters and sizing methods do not write or emit after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-f092d45564e8b3510bda", + "file": "display-sizing.spec.js", + "title": "published: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-643e209f256d1a250a16", + "file": "display-sizing.spec.js", + "title": "published: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-7fb7121ab78997abbe47", + "file": "display-sizing.spec.js", + "title": "published: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-b7e30679e943616dfef3", + "file": "display-sizing.spec.js", + "title": "candidate: sizing preserves valid geometry, return values and emitted measurements", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-41b8387d30bd3355cdea", + "file": "display-sizing.spec.js", + "title": "candidate: aspect ratio and flip preserve dataset, notices and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c1d78ac5d79cafa26733-9fbdd4ca5d22c59ccd22", + "file": "display-sizing.spec.js", + "title": "candidate: unresolved media dimensions do not partially change layout or emit NaN height", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-208f9783e628fcb9f8f6", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-9b25a8ef63de7b4dc979", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-b6eaa1095fe80688f08c", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-217eac71a398847de922", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13fb46b81b245d60cb62", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-2388222367857a3e66e2", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-13542a5bca0f6c66c1d4", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-55a303d76fff18e9c543", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-aa7ce7a489558e5015bd", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a07eddfabd5626cd0a2a", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-be81b8fbab088b300863", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-219d49c53f695202afa4", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-7c345ddfdfbc22609add", + "file": "display-video-fullscreen.spec.js", + "title": "published: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a266ccd310d1805953af", + "file": "display-video-fullscreen.spec.js", + "title": "published: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-a4537e5ee57ecc6df48e", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen reads its native video state and deduplicates signals", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-8789c7a223602cf16bff", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: destroying video-only fullscreen releases native presentation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-3083605efadc1ebb2817", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: cancelled video-only entry after destroy is released without late player events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "7d5f843a3eb7268e468a-d14a5ea50291afe6f9de", + "file": "display-video-fullscreen.spec.js", + "title": "candidate: video-only fullscreen preserves synchronous errors and supports exit retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-d8ab6eb3399b84992a2f", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-550cab25cd4472ab5404", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-815457e6e43f6215cf16", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fb5d2acca03e53a05fa9", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-938d058c513b2c6e4a7b", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc2f4dbeb12688fc0d09", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-13a224af21b3d0914046", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0139c3c03ae78094f003", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-56fcf9d4ecc6dd2b5317", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb9a8e784bc0eed2746d", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-f8713bb4e572bbcdfa80", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-db015bbeedac5adcbd10", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-19ecc671e1e026bc0ded", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9ef90c68539232ed41a5", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-21cad0e9cdd6d2bfd1b1", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cecc49e625d4d5249b11", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bb05d7f99e674170cef7", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9646aff44447cc995bf8", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-bdce42f9d74c3175e0d4", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fdfa7d6a3e6cba0ab22d", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7218f7cbdbf7c782e370", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-cc08e8366aa5d34a9c29", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80abc0538891ca5f3aa1", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6d04590538d38c42aad5", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-c57605f5ef7b09cc636e", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-0ba87022d3f706fdff30", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-fe1595dc54e07363e691", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4297141ebb2129c56d83", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-63c383aab40510893259", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-8b1e8a0ed4dff57437e9", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-9fdb2090b41f1f3ff3c6", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-23d2a65968478f02d44b", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a20b1cb4c50409198ac8", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-07e5b86c2ea67d5bfe00", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-021c130be876d25ba481", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-842e4f5ea371dde0e5c2", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-137445c9986c9c51f2b2", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-da0df43eb60cf30984ca", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-2200c9b0e251b0d7c3df", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-80f4f73c29520d56a77a", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-24afcb40cac5af9d1385", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e3c4d42cfd2be629006", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e9de1c8e6c2f74726a21", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-a7b2b5adde5a53dbe684", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=false movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-b70a7b7a9d964994eb6a", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-226a392ef76eb6584e8c", + "file": "display-web.spec.js", + "title": "candidate: failed destroy restoration cannot orphan the player removeHtml=true movedBeforeThrow=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-683943286d8f1c511779", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener can exit without stale resize or overwritten restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e87d954b29f0e537aafa", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen listener destroy restores ownership without post-destroy resize", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6c492f1a4ee91737fb44", + "file": "display-web.spec.js", + "title": "candidate: a failed body move restores style and keeps its original error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-222bf68318bf2fa781e4", + "file": "display-web.spec.js", + "title": "candidate: a failed web fullscreen exit can retry restoring the original placement", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4abcc05151f508b6b38a", + "file": "display-web.spec.js", + "title": "candidate: reentry during web fullscreen restoration preserves the newer active mode", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-e62178933620bc510f18", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-936b9f3b6aa4eaa086bd", + "file": "display-web.spec.js", + "title": "published: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af01df3c5e6334b2804", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-37632dea3a3b0bacf658", + "file": "display-web.spec.js", + "title": "published: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-6af0c468750891cc0795", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-7c85395365aabb2689de", + "file": "display-web.spec.js", + "title": "published: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4096b3070bc74225ccef", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (empty)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-45821ce9036c86d58429", + "file": "display-web.spec.js", + "title": "candidate: web fullscreen restores initial style after repeated entry (width: 70%; height: 80%; color: red;)", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-2b3339054c6014e3d92c", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-1f11bfc1f0db92a746b3", + "file": "display-web.spec.js", + "title": "candidate: body fullscreen restores original parent and sibling when flag changes=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-5dcfac157f8728da6350", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=false restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "fe39740769f1a80c4f29-4e69e56ade45d1c34c23", + "file": "display-web.spec.js", + "title": "candidate: destroy while web fullscreen removeHtml=true restores DOM ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-df9185e3b4b991a41e64", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-ed9673608bfce2021867", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-24b54879cbf233713158", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-88ac928201db18372b56", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-e6d95084fc692fda4982", + "file": "emitter.spec.js", + "title": "published: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "19da3f572420d2785adf-c596a9468fae531af4fe", + "file": "emitter.spec.js", + "title": "candidate: emitter event names and once across nested dispatch", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-35933d1aa16aed20c273", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-284569d9920b0e711743", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-f133edb484cefef36fa5", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b6865d33ac15fe202ee9", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-874d84ca789695182779", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a4af7d5968980731d353", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-46ec1b4d191ce6ce2b87", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c065a965bf03c20c92e9", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5a43a2d9dd07eb718eac", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-5c900727f4df105d31e1", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-48f5ae6cdf42faf667b0", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-8ab1ef6cc7e44699a093", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-823f4e17aad9a4475863", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7a655be064429dee0a96", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-acc7f1cafcbeef593883", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-4b319da242a0d8c88898", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-a2ac88d6cf9bcb87bc6b", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-26f0718fb72ab6480f46", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-9fe68a142a0bc1358130", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-808e795ad0ae6b29162a", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-7579b31713d2e73709f3", + "file": "event-scheduling.spec.js", + "title": "published: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-b22bfeda45eb2ca888e7", + "file": "event-scheduling.spec.js", + "title": "published: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-cbf8c58deb5fb97b5f71", + "file": "event-scheduling.spec.js", + "title": "published: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-49920d5cdcd992e18848", + "file": "event-scheduling.spec.js", + "title": "published: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-89197327fa985823badb", + "file": "event-scheduling.spec.js", + "title": "published: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-39a5048a03780f5926dd", + "file": "event-scheduling.spec.js", + "title": "candidate: actual animation frames follow playback and stop after destruction inside raf", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-38816d0b0af580ec7ae0", + "file": "event-scheduling.spec.js", + "title": "candidate: Events keeps its public fields, prototype and detached native methods", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-fb11c3a2d7114629dfc1", + "file": "event-scheduling.spec.js", + "title": "candidate: screen orientation dispatch works when onchange has no assigned handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-04ab8fdb013a043672b5", + "file": "event-scheduling.spec.js", + "title": "candidate: destruction releases the scroll throttle reset timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "59b4b40899245db75bb9-c674c60cca295235cf91", + "file": "event-scheduling.spec.js", + "title": "candidate: view visibility uses the container's current iframe viewport", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-773eca70690d387d203a", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-3a3ae1248ea885530ab7", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8e78a04173cccd6a36fe", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-a5d86368d43103420d7e", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-37939cfe8cdabb73cae6", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-1261a6dd4dab94de87f9", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-97b919d98fb476bb06ad", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-92124b7cd341179d274e", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-9ea4fd31ac9552af5a78", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-3fac470389adaae7428e", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8029cb83aea256718e7d", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-cd89fd95afb4cecc1aaa", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8785f5d4b2aa76ed07f3", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-18a0b3d713eac5837acc", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-b8c630f860ba3c65d17d", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-cfdd6a0d764cdbe399f4", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-32d7e4cc4e00529b2fd3", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-1d6536787cf98d1d0f6b", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-add54e1d17434e14d73f", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-35b044daa0c8a9b1d282", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0960e6b2d6129f891aa7", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0cfd5bb77ac4577c8fd7", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-aaa9953db4c7813bad2e", + "file": "fast-forward.spec.js", + "title": "published: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-30502caabab5c68b70fb", + "file": "fast-forward.spec.js", + "title": "published: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-ef92c054fd960df4e187", + "file": "fast-forward.spec.js", + "title": "published: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-d93b70a360c3c6bd1597", + "file": "fast-forward.spec.js", + "title": "candidate: native source reset retains its default playback rate behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-f67c125dd85f543cb490", + "file": "fast-forward.spec.js", + "title": "candidate: long press accelerates real playback and restores its prior rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-b98acd23c9bb5e10da08", + "file": "fast-forward.spec.js", + "title": "candidate: touchcancel releases an active long press", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-2d2899f9a9959e416ac0", + "file": "fast-forward.spec.js", + "title": "candidate: lock restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-ad5f774f8715bed9a669", + "file": "fast-forward.spec.js", + "title": "candidate: pause restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-37294e057cda968b3313", + "file": "fast-forward.spec.js", + "title": "candidate: source restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-8779782ddc0db5031b0c", + "file": "fast-forward.spec.js", + "title": "candidate: destroy restores the active long-press rate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "16345742e1dbdb423076-0ebcac3609144ca1a60b", + "file": "fast-forward.spec.js", + "title": "candidate: repeated pending touches own a single timer which destruction cancels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-461f5dd6653ab5f2a639", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-27a5bff23ff7f1de8dd7", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-497b96f591affc76d55e", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-161d08b4110420b80ac5", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c204080bd3b07a435032", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9926a5b91c5984e3b054", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6cc5ee1c72355fdb1396", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-60b0c86e91e11633d921", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-7720022e29c29701e505", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5cf5d68bdd537fd238e6", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-dc4dd75dcb489b80e3f7", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fde552e9529a19d3fecb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-a7eecc22cacd33b910b2", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-965cae8eb7530de807fe", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-187c124ce8e69535b346", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-4aa95e812cf8a32b7adb", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-0b25f726ad05ae471db3", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-b943b423ff6eae4207d8", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1de19e97f5545df7afba", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eeca99dfbfffba631604", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bb9d55b4fcc0d96aa0c", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f08813139950541c5009", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fb6ded7b3f2a84801a6f", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-244a33407a1a4f812e79", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-532e0d74c736bd1a0a96", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f2e118615ee7bb5a6215", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1a9c3a775cd64374bbb4", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-362578108b38e76fbb38", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-13e3feb76468dac21311", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1bfbe29327bd8d169e61", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-aec7df62b58d89b641b9", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-3f5d5b7cfda98d08d6f3", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-38d36f45d72a4173bca7", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-1874e2851c159cb95e46", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd0415b8257f201f89f4", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-382b12a6bab3d4b449f1", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-bcf78818601a8279511c", + "file": "gesture.spec.js", + "title": "published: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-6919f1e24909ceb2e9c2", + "file": "gesture.spec.js", + "title": "published: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-032298add8fa5c9e6900", + "file": "gesture.spec.js", + "title": "published: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-9eeb960c866cb8e40ae7", + "file": "gesture.spec.js", + "title": "published: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-495621812ca11295f6c4", + "file": "gesture.spec.js", + "title": "published: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-278ac9215c6ee4ef7a0e", + "file": "gesture.spec.js", + "title": "published: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-281de4e437f228cfbf71", + "file": "gesture.spec.js", + "title": "published: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-295d34734b65043ad9f1", + "file": "gesture.spec.js", + "title": "published: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-eccf52e9ad978c3fb6f0", + "file": "gesture.spec.js", + "title": "published: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-997c6976d105bb92e34b", + "file": "gesture.spec.js", + "title": "candidate: a gesture before first play still issues the requested seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-f8ac31a8f379e827afa6", + "file": "gesture.spec.js", + "title": "candidate: progress touch keeps absolute position and bar-before-seek ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2696dcfa7d78664906eb", + "file": "gesture.spec.js", + "title": "candidate: destroy during absolute progress touch stops the following seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-c987918ce4081b93f4a5", + "file": "gesture.spec.js", + "title": "candidate: normal touch drag keeps seek/bar ordering and original touch identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-ca7249b272a4ee995262", + "file": "gesture.spec.js", + "title": "candidate: cancel invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-31189dc5c67888379803", + "file": "gesture.spec.js", + "title": "candidate: lock invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-2095690dc9b524b59f2e", + "file": "gesture.spec.js", + "title": "candidate: multitouch invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-fd3da8b80bde24b740c6", + "file": "gesture.spec.js", + "title": "candidate: identifier invalidates an in-progress gesture", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6fbda476a67413f954ca-5bc8d77279a092208982", + "file": "gesture.spec.js", + "title": "candidate: destroy from a touch seek callback prevents the later progress notification", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-617565d43b891af783fe", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f9616507688ef54da419", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-26f0e410fe8fbef993e4", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-82f480adbb99a326dbde", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5125ea2213ff5db2e37e", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-826b6613db8e2561c1f9", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-a0fa0283e2778dc5de31", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-fa9c790ee5f9cddb03f6", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-50d0f3b11ab1c6d2a851", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-58c86f200056ced2c1fd", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-ef8e8b36cd6be9ade13c", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-412a59f5e374b192ab8f", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-7bea54a023db77650f45", + "file": "global-events.spec.js", + "title": "candidate: rebind during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-f2a1eea4a9da71d32455", + "file": "global-events.spec.js", + "title": "candidate: destroy during native global registration cancels the interrupted binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-0ba262110508d87e2629", + "file": "global-events.spec.js", + "title": "published: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-89a9d197048808466148", + "file": "global-events.spec.js", + "title": "published: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-cabbe9eb64dd98cf1577", + "file": "global-events.spec.js", + "title": "candidate: global rebinding forwards original events once and releases the previous document", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ec4e1a8bda76411e0d95-5f6824deb87c02f599b8", + "file": "global-events.spec.js", + "title": "candidate: failed global rebinding keeps the previous document and removes partial new listeners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ec4b2c508a72550ea58b", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-310aaace35717117379f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d69b68b0bdcc53067f53", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1a588135d6cc568e6fa", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97e1208644b9fa58b8b1", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-09675477605b25710801", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9e893625c48fdfb954fa", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d6b81653bb60630a3599", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-66a15a5984ee4598f0fa", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d7563229ff93d6112f7a", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-d51274ed9cc2dbcfb578", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c737f670669e27522d3", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-8995ac2dfb98da407afb", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-01938547b760ce9813a9", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03fd75c773964be30538", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e759bd25c03f8a5d10c", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-98f620bde5cb9a1b371c", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-0764e8c8458e141bc8f2", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-59ab8baf180ad899b67f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2bf2947fd3d500d7172c", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-87e5729cd74cd61fb7c3", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-46a350c4c851b9f21238", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-4e8564bdb7bf0592a134", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-17ef0769f5ab192ba955", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-43c293f7c92733bcc08b", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e24f37c60c9773759771", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e502fb517997f1b53153", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-04fe566dc8e712f78ad3", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c1083b5c3aaa666a25b5", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-965d4a265b14ec72626b", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-aad49f66089770417b5c", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-afaa58fa5e14ad72db35", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-c460f1702b1887cb0943", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-eb991a205aeec0eecc91", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-bcd222ce2c4830ef345e", + "file": "hotkey.spec.js", + "title": "published: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9183819e25f74564c41f", + "file": "hotkey.spec.js", + "title": "published: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-2c757941b4feb418e86a", + "file": "hotkey.spec.js", + "title": "candidate: mobile keeps keyboard initialization opt-in through the existing init method", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-342135d4e67724c3cf83", + "file": "hotkey.spec.js", + "title": "candidate: prototype-named hotkeys do not crash or replace the keys prototype", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-97ae305550aa393060bd", + "file": "hotkey.spec.js", + "title": "candidate: native keyboard play/pause, seek, volume and web-fullscreen Escape retain their behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-7a2bffaadd6727862592", + "file": "hotkey.spec.js", + "title": "candidate: inherited editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fa81266d048708984784", + "file": "hotkey.spec.js", + "title": "candidate: plaintext editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9b9974717b4576aa1ae4", + "file": "hotkey.spec.js", + "title": "candidate: select editing and IME composition do not activate player shortcuts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-58b7be0d4b52aa9fccb4", + "file": "hotkey.spec.js", + "title": "candidate: destroying during a key callback stops remaining keys and notifications", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-fcb2ab222414744b8ea5", + "file": "hotkey.spec.js", + "title": "published: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e6130ef57b5ab5661f42", + "file": "hotkey.spec.js", + "title": "published: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-ebadf97bdc5e9f45affa", + "file": "hotkey.spec.js", + "title": "published: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-9ee63e8b728f62bd983f", + "file": "hotkey.spec.js", + "title": "published: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-021200f38ed02bb50845", + "file": "hotkey.spec.js", + "title": "candidate: hotkey registration retains chain, array identity, receiver and event order", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-03c49c3e845e96f8e76b", + "file": "hotkey.spec.js", + "title": "candidate: rebound document input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-1bf7e7b8230dff7a356f", + "file": "hotkey.spec.js", + "title": "candidate: shadow-root input retains typing instead of triggering a hotkey", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "24da4743f3e5db9f15e2-e1ffd301af299b9846be", + "file": "hotkey.spec.js", + "title": "candidate: repeated hotkey init does not multiply the keyboard subscription", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1ed76b5f6a82de9d068b", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-3cefbcbec7deeff53d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-69355e4dc46467b0a9eb", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d94e9fc7c4dba97cc53f", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-61c4eabc80173b1e442a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-71d443a2b6af5518b178", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-59cb2417e70f961c50e2", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-9c1d85713fc8613fc6fd", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-7c6a370020654bfcada6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-30aba1a1bb1b8501b0db", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-15709a7d6ee1e1e37d05", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-1b85f275ededd6b4ce29", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d7c211503e05f9db4594", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-f8c63f06543266f0373c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-55df032d48093a9a7a98", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-43883bd2151838bff08a", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-96cfaa6a8f4b9da28c64", + "file": "input-closeout.spec.js", + "title": "candidate closeout: restoring a removed default hotkey keeps identity and real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d322bdc5916e8bb4e882", + "file": "input-closeout.spec.js", + "title": "candidate closeout: a failed native removal remains retryable and releases its record", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b6a7c315b0b983e8044", + "file": "input-closeout.spec.js", + "title": "candidate closeout: destruction before native add returns cannot leave a late listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-d5dc97a19584f2c0bd7c", + "file": "input-closeout.spec.js", + "title": "candidate closeout: window registration failure restores the previous global binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-509d99c428ef04fb2e49", + "file": "input-closeout.spec.js", + "title": "candidate closeout: source changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-fac2aa15d600bc1bf552", + "file": "input-closeout.spec.js", + "title": "candidate closeout: rotation changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-5b23a746569631c03db4", + "file": "input-closeout.spec.js", + "title": "candidate closeout: geometry changes cancel the old gesture in the installed player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "dbbac41dc03fc4f485ce-bbd046deabc0ca1172f6", + "file": "input-closeout.spec.js", + "title": "candidate closeout: adopted viewport retains exact gap boundaries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-d1cba7c810d80b340f02", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b18e0bd87418016b019f", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-f640c192434bf9a64a7f", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-af04f2118c29852ac4d0", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6bbd26e23fb3429993b3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-78efe4e7a850b2a90ebb", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-dd98a66249e18d35e4ec", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7e56c82040d8213b52fc", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7587ab0e8e449207ed24", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-5da1a688dbe2217facb7", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-489c3bd67ceac85c7d79", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4d1c0bbb0d31efac6702", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-83a5f6f72a73e749b6fd", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c60ed5afa38f7991685c", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-1961de75defdc952a8f3", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-351ed5a2908f4cc9619c", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-7954fe1c578a54eebf8c", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-36154f67953190d1bfba", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6522dbb08c1b075a5ec0", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-76e298b978895f180911", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-77285e408518bdd6dee8", + "file": "lifecycle.spec.js", + "title": "published: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-c8f1d687675a279a00cb", + "file": "lifecycle.spec.js", + "title": "candidate: repeated destroy preserves other live instances", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-3d38bfd5b7b08646ebfe", + "file": "lifecycle.spec.js", + "title": "candidate: constructor plugin failure restores original DOM and clears resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-70526633595037330da8", + "file": "lifecycle.spec.js", + "title": "candidate: early proxy failure restores SSR nodes, attributes and text", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-e00d282a9b13f205b9a9", + "file": "lifecycle.spec.js", + "title": "candidate: reentrant destroy keeps sequence and does not repeat callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-ca150c7e341afc79085b", + "file": "lifecycle.spec.js", + "title": "candidate: destroying cancels queued resize, notice, RAF, reconnect and mounted work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-de68c38b7c4aa90447d4", + "file": "lifecycle.spec.js", + "title": "candidate: constructor can synchronously destroy without entering the registry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-4bf9b7e006db011964e1", + "file": "lifecycle.spec.js", + "title": "candidate: partial Events initialization releases listeners before its property is assigned", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-b81bcd76f642b8cd1cb6", + "file": "lifecycle.spec.js", + "title": "candidate: live resize still coalesces and destroy cancels the next burst", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "82f819fc370d5b5a8454-6a1c655a7541e2c283c5", + "file": "lifecycle.spec.js", + "title": "candidate: a container is reserved during reentrant initialization", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-33ab58a217e5ed46af64", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-6c3e26795bad7ad08640", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-081e4a3c2efab5a6a4f8", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-48f3dc84a4b45ece0f66", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-bd8e568d3c301593236b", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20205da01df1b6d1275", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cd03a72feb502b43128a", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c084c9d9f3321e48be59", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-291a97e5971de8da34fa", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-96ad9b36215f1db666df", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0ff5f41421512bce0682", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-85d3c1a084877cb32e68", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-9a764add8106b570a9fb", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-4f6c3e8455782e5592a1", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-321e89c016aaf0a04e89", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-3835036f94dea4e826e2", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-cda798777baabd4bf688", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-685f7f019e46ba558b9a", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-640ede7d3ff202fea200", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-254917f54cf2302cd6ae", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-36849c7e4b2167768c04", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-ac5d5c862592ff76b6c7", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c3ffd08e95c46586ed24", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-46ca3a1867d4e79ccf78", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-330b06a4b4886d69f8a2", + "file": "listener-registry.spec.js", + "title": "published: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-7ea574653c71793cdc59", + "file": "listener-registry.spec.js", + "title": "published: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-494fdf7a643287f6e9f6", + "file": "listener-registry.spec.js", + "title": "published: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-a20b9efe52074aba9a9e", + "file": "listener-registry.spec.js", + "title": "published: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f720c3dec109e51e7e33", + "file": "listener-registry.spec.js", + "title": "published: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c7e1c0f20ca436a64e31", + "file": "listener-registry.spec.js", + "title": "published: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-c10d09a36296547cce19", + "file": "listener-registry.spec.js", + "title": "candidate: null options preserve the native default and callbacks can be removed directly", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-65b87ddd974d9095cd99", + "file": "listener-registry.spec.js", + "title": "candidate: once and abort use native event identity and permit subsequent registration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-f923d3845a11b464c735", + "file": "listener-registry.spec.js", + "title": "candidate: direct event disposer preserves native callback identity and releases bookkeeping", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-71e88fe06828c0aaaa52", + "file": "listener-registry.spec.js", + "title": "candidate: changing capture options after registration cannot prevent cleanup", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-0e43bca78fe1615e1188", + "file": "listener-registry.spec.js", + "title": "candidate: partially failing array registration rolls back the listeners it created", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f12e0488909e2ebf88cf-74b76fae26483153575e", + "file": "listener-registry.spec.js", + "title": "candidate: registration throwing after native add does not leave an untracked listener", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-f81f74c17d54e135812b", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-cb7cf3d37546dfaaa25e", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ad243930eba7bbfca9ec", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4f06979d10a0cc73f0e4", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-73b72e27dc0e279e1dfc", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a391ecf6be83e360d5af", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9886e61b50b0325f00b6", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-7661cdbadada621ddbdb", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-534b6a21f22d52437946", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-964c3e167f81d6c4b540", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-b8af7f6e76d64a404611", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-26e289678f8318df9985", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-a31d40ad896888983990", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-41f669bbff76dba08542", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-94ccef7d1b2712b3a8c7", + "file": "media-events.spec.js", + "title": "published: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-0acfeccae2fa10a364bb", + "file": "media-events.spec.js", + "title": "published: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-804bbc5c45a32217b23a", + "file": "media-events.spec.js", + "title": "candidate: HTTP failure retries the updated option URL with the original event and one ready", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-e1687b8c29a364456ced", + "file": "media-events.spec.js", + "title": "candidate: replacing a failed source cancels candidate retries", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-9de93a65641998f55bfb", + "file": "media-events.spec.js", + "title": "candidate: rejected real-media switch still allows current-source reconnect", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-ae29a326f7d6b9244c7a", + "file": "media-events.spec.js", + "title": "published: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5642c616032ffdffac35", + "file": "media-events.spec.js", + "title": "candidate: destroying from first-ready controls prevents a candidate ghost ready event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-75b1d9674a6663bf2d6e", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-1e45a2a5dde8e9ffc1f1", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-fea8a7011bdffae81cb6", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-4d2842dff07972329923", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-5235450a56f738efeecd", + "file": "media-events.spec.js", + "title": "published: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "9a48fcf31fb0bf73c484-6d06c3705c2addbb8090", + "file": "media-events.spec.js", + "title": "candidate: metadata emits resize before mobile visibility changes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1707b8b14a6deb4b2b1d", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-c052ddece9958e0555fb", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-1723a11b47d130206b98", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-b93e8a95aa929ea2ae0c", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-60bb8e6ab68260d8c6fd", + "file": "media-hosts.spec.js", + "title": "published: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d88972cf079122a6832d-55abe99fef6857550456", + "file": "media-hosts.spec.js", + "title": "candidate: existing canvas proxy keeps media identity, playback and layout", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-0f49d1285226348634c0", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-24f58619d642db14fea8", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-68c445671e9adf88066c", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-aad4d2901d12bdf01915", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-24762ce6b234dc12214f", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-be32d3483148f5f64ac8", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-7f558c384fd9099689d5", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-ac74dedfe39f4659eed2", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1bab1b46912eda1af15c", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-da995b98b89d9fb5bf58", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-774e4aaab03d5b44bb2c", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c498914bc58cd712c4ff", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-568bc11275e9d7dce946", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-52e1a6cf49f647554379", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1e837e265e2ff83fc673", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-81bf5cedf663307d9ade", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-6a9cd51e3dfdc9b290b7", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-fc77ab576b2048180b27", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-23a5ea128a8390a8f174", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-70f2c8b45eb47ba6b09e", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-bc8a0cfecef9b3a54ce1", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c1b5af0a680287efd190", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-460e036a9ebf06309ac6", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-3ea62e47446dd5fd1382", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-7c4f53d04de946f4262f", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-52494aa0b96ed978f8b0", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-b5bb4f5eedeea74c067b", + "file": "notice.spec.js", + "title": "published: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-38fb23b594ae4f3db0fe", + "file": "notice.spec.js", + "title": "published: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-9f81a06a638bac718bd0", + "file": "notice.spec.js", + "title": "published: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-6af186ecb30ec790a0ea", + "file": "notice.spec.js", + "title": "published: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-b5a62d7e6d4583de7dcb", + "file": "notice.spec.js", + "title": "published: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-c5cfaab74d04578f892f", + "file": "notice.spec.js", + "title": "published: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-06538701168e8ae2e9c1", + "file": "notice.spec.js", + "title": "candidate: notice updates do not call a consumer override of destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-be4d6b65a904ba3a6a08", + "file": "notice.spec.js", + "title": "candidate: notice preserves public shape, Error text and false hide semantics", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-e065097fdf992aa65df0", + "file": "notice.spec.js", + "title": "candidate: notice expires naturally during real playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-e4d45b9bd192de637872", + "file": "notice.spec.js", + "title": "candidate: manual notice destroy permits reuse and does not hide its DOM", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-a0cf1e8d9be71232b3ea", + "file": "notice.spec.js", + "title": "candidate: destruction during notice text assignment cannot schedule a late timer", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-9e144dec84b139541490", + "file": "notice.spec.js", + "title": "candidate: expiry does not hide a notice installed during the clearing write", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "4f603535634d11d145e8-1840748750e30e4a000b", + "file": "notice.spec.js", + "title": "candidate: retained callbacks and assignments cannot revive destroyed notice resources", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-78fe676015d6e8dbc0d0", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a24e837c0a70d9648453", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-802ef8362a0f403ae08d", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-70abbec3c9dd6b888e1c", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c0ab35af2770dd5f4806", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-e72fde2e2a57668fa47c", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-a4df961c9062ebada00d", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-73e6bcb78301864d09a0", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0f38da640b1ce0c5e360", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-08a820c1f1e532774cc1", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-0a6080d5d9c551bbbfef", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-d47adcf0c29980498c19", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-c1239d4ad067319ee2a3", + "file": "options.spec.js", + "title": "published: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-229449f9f5a2f8fa7963", + "file": "options.spec.js", + "title": "published: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-52e7670a5b3a053c6e55", + "file": "options.spec.js", + "title": "published: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-7ddc0ea00c170012b4d6", + "file": "options.spec.js", + "title": "candidate: expanded option input preserves historical JS forms", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-dbf437be2f34861c5a0e", + "file": "options.spec.js", + "title": "candidate: configuration errors occur before mounting and preserve allocation timing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "51fb6f8c703f56762e96-3c389ca847ff1e4c75bc", + "file": "options.spec.js", + "title": "candidate: container identity, partial defaults, custom fields and normal callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6542b91dece2a74614df", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-51b208ac054e2eb00b26", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-4f6db3993845b9ba2985", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-bf0574101b74e333abfc", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-b8e3d4f14c5274942e99", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-aa029ef04ccaa364abaf", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-884e7e97cc7f4601b9b1", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89a5f36c70aeb1aeb725", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-6e80e6040b5d820ea851", + "file": "playback-properties.spec.js", + "title": "published: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-89b1e6f236f0b07b34e9", + "file": "playback-properties.spec.js", + "title": "published: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-76c423a2c23281a89f4f", + "file": "playback-properties.spec.js", + "title": "candidate: real media preserves timeline, volume, rate and property descriptors", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "28aa0cac6aacffd70d0a-f1b89a3a449ec92c4a02", + "file": "playback-properties.spec.js", + "title": "candidate: invalid time inputs and rate no-op retain native behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-846a43d5c11f461bc706", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-6fc43c2ad3b16ac57feb", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-923d4b452977986e35eb", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-3751522702f6c4040d89", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-7c1ede28fdbca2fdb036", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e71806ec46cfa3c8830", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-308b7034593f3aface7c", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-824de270447cd0289399", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-2e405967fd041e7bd63c", + "file": "playback.spec.js", + "title": "published: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-73ef3504117f77184a3f", + "file": "playback.spec.js", + "title": "candidate: real playback, pause, seek, switch and destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-273a8c96e455bc2cb3a5", + "file": "playback.spec.js", + "title": "controlled HTTP media failure emits a real video error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b4ed495288f4b512a8ac-421ad6f29b1e4edba558", + "file": "playback.spec.js", + "title": "Range, media identity and docs candidate routes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9848ba9b5bdc87b7080d", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-fd0af30740777b8fa6f6", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-caf25f6ee3ed380b66a5", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-1694c548d47a5dfd7321", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-4a613122854d4efeab25", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ce9ca8b3a37a93a751e0", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-a86fc2f76d5a0e73dc92", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-ed069932d1cecddc62ca", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-9a9f8fea7676c3fb1f03", + "file": "plugins.spec.js", + "title": "published: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7bb2424006b234f72e6a", + "file": "plugins.spec.js", + "title": "candidate: late plugin registration preserves fulfillment without reviving a closed candidate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-f7838ff686e269e64cbc", + "file": "plugins.spec.js", + "title": "candidate: a plugin that closes construction prevents subsequent factories", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-22b53afce3b44c0e3b56", + "file": "plugins.spec.js", + "title": "candidate: constructor-owned rejection is reported once without an unhandled rejection", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-7de925a1d5f347027a30", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-d4bffb27232bd134e0ba", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-115453f0cb1f2df25c13", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-576425b00e3b37a5f55e", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-6ddec59a6b7a73444874", + "file": "plugins.spec.js", + "title": "published: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "27752d8aa5ba1c387417-c4a665637742c22fe6db", + "file": "plugins.spec.js", + "title": "candidate: builtin order and live exclusions precede user plugins", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-05c7aa4a035cd53f615b", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ff797d35cf4226a8908c", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b321c5b060f24c0dcf7c", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-86838248a63b8cb598e4", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f74d56109a0a98dbcf37", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-f2cd78f5c336b7b5a29b", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-687bbd5c29aeaa2087ee", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8e37462e4a700a9d032d", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-8b838317977126c72896", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-c162cdb14c052116404d", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0b01ed5f487c653ef5e6", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3faf3b0b78cb6e5a7916", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-3cc483840fcb60da6de7", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-886e669450b0aa293cc8", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-5d9e035f106d302fa65a", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-850f54c586f39ff9ed15", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-b9482406e41527269426", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-472f4ce1e106982a41f2", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-e4b709b61462b8d189d1", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-9d3f428ef8c764b1ff11", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-6fb2012cd72d02b2a069", + "file": "pointer-events.spec.js", + "title": "published: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-17106154f47c826afcb7", + "file": "pointer-events.spec.js", + "title": "published: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-49817d29e2e8721cf6b9", + "file": "pointer-events.spec.js", + "title": "published: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-0aa0a59420e90b9113f5", + "file": "pointer-events.spec.js", + "title": "published: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-cf318af31bbcbc8c0d29", + "file": "pointer-events.spec.js", + "title": "published: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-7172a28011c10712e8f9", + "file": "pointer-events.spec.js", + "title": "candidate: real mouse input focuses the player, hovers and toggles actual playback", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-db2b94c7c74a6265c7e6", + "file": "pointer-events.spec.js", + "title": "candidate: click pairs preserve callback identity and playback ordering", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-ed084452ce2ddeee614c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in click stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-deb5a4dc1d9142fb059c", + "file": "pointer-events.spec.js", + "title": "candidate: destruction in dblclick stops its subsequent default action", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "32f7e7f35d9cbafc158d-bd60bf10694d5c9d5bc8", + "file": "pointer-events.spec.js", + "title": "candidate: focus, hover and move preserve flags, classes and original events", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-fb4286b068bc0600cff6", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-0a2362b7454728723ffe", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e1e8d2a13c11230aa98c", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-47d80491960fd6ea310b", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5ca838b0d7d085b3171c", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-ceb18a89995a5f524bb5", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f3da7e372dfc4ca08dab", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d426008fb62238e11f84", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e5234b4868a1e6e63259", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5667dcada09f02da7767", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a5936ea729b375a90d68", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-851c77d2899e902efa36", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-e931cfa2f01226c7342a", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-453ae6bd59490dfdbe39", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5c3b6be93f5a02202cd5", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-b23fad659ff994ab889d", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-cde96d244964d5994409", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f107c907c4348a32aca1", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-509e830745c3354e14d5", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-db2ce4b07c8501ec9f3b", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d382cb7aaf3e4dde02bd", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a965986d79fb4bca3819", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-d78bdabf74a8b242644a", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-0491300e9f273d3b74ec", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-48709e4bb5bb0b63a00f", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-c6cead770cbf3fc9518b", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-080efc54b0dc8e811ea5", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-74973a25c3c43bce8cce", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-a7a44dde52914c0071c9", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-12553b7460cc2837bdf5", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f55cae9cd9533c38a7a6", + "file": "progress-quality.spec.js", + "title": "published: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f59d61c02b2c7a09133a", + "file": "progress-quality.spec.js", + "title": "published: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-b1303a1aac807b19eb1e", + "file": "progress-quality.spec.js", + "title": "published: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-92b87c696643ea1b04d4", + "file": "progress-quality.spec.js", + "title": "published: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-7b2b019dd3c609469cdd", + "file": "progress-quality.spec.js", + "title": "published: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-ad7b2bc9685eb10c11ca", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through remove cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-72f9c4bf010a680a10e7", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through destroy cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-c64c6ba986cbf48dfa3a", + "file": "progress-quality.spec.js", + "title": "candidate: progress click reentry through source cannot continue an obsolete seek", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f58e0b20838b9a4ca914", + "file": "progress-quality.spec.js", + "title": "candidate: real progress click keeps setBar before seek and clamps the edges", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-fbcabd7c5459bef81b01", + "file": "progress-quality.spec.js", + "title": "candidate: a progress drag ends when its source is replaced and can restart on the new source", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-5921d852f120985f8dae", + "file": "progress-quality.spec.js", + "title": "candidate: a caller-owned media Blob URL remains readable after switching and destroying the player", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "21cef141557e7e8b6cc4-f30bd17b38dd9cb41e29", + "file": "progress-quality.spec.js", + "title": "candidate: quality selectors retain default labels, source position and empty-array behavior", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-28f56886e057fff9a3f8", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0be7c63e66376c943a21", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-05804eaad67a72e87c55", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b06f1498b7addfe2ec70", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-689d97b4f6669135b2e3", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-a2fd0175220b1e48556b", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-db16da3b81fc24a094c5", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-a9cb86d09b5c5ba6e279", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-59103ebfd820f1f0b009", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-54c7e588d7908084d50b", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-bc478d4f6cdfd249d99f", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1f2b13ee7a4cdd84a1d0", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-76f259dd6574072ee661", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0feef2cd41b3a85c35e0", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-d8119eeec24c94a622c6", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-22a3a24869893190be61", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-7ae0cd8fff2cdb8b3288", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1982bb505636ac42295e", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-12622dc301433cc56db7", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-dee150aae3c0b6a546cf", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-5f4c5d30efd32f347e43", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-93329700c4d82fce10c1", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-6d645addce5b71832bff", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-24c9df9b1239a0816afc", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-5df66bf73307b0227fab", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-87c0ad6802e891c610fd", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-004bb5a4c7ce279a2068", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-244372a5806f894f72dd", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-65259994b4e78a13c1be", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-491aa709b5562551e288", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-bff86af42468bb73da3d", + "file": "prompt-components.spec.js", + "title": "published: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-0f23572f241895417714", + "file": "prompt-components.spec.js", + "title": "published: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-7e0edac74ab36445f5bd", + "file": "prompt-components.spec.js", + "title": "published: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b5b78f66f3a7517f8a56", + "file": "prompt-components.spec.js", + "title": "published: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-08a7960db28b8ad2d7dd", + "file": "prompt-components.spec.js", + "title": "published: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1d3540e3cdf5ee8762fa", + "file": "prompt-components.spec.js", + "title": "published: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-3ab1714598d9893fe55d", + "file": "prompt-components.spec.js", + "title": "candidate: mask preserves observations before and after its destroy handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-aa150262c59632010cd4", + "file": "prompt-components.spec.js", + "title": "candidate: info preserves fields, native media text and close visibility", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-6e283408eac06976995a", + "file": "prompt-components.spec.js", + "title": "candidate: info retains native nullable string conversion for custom media fields", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-9ac12bfa0c8d453d385f", + "file": "prompt-components.spec.js", + "title": "candidate: repeated info init owns only one new timer and close handler", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-1bdc05386ecfa31c62ad", + "file": "prompt-components.spec.js", + "title": "candidate: info mobile construction waits for an explicit init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-4158474585ac03f92470", + "file": "prompt-components.spec.js", + "title": "candidate: mask click plays native video and destruction displays the terminal icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-70a1f30aa14cad71fa3f", + "file": "prompt-components.spec.js", + "title": "candidate: info destruction during a media getter prevents text writes and late init", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-b0db93e6a8a0402e442d", + "file": "prompt-components.spec.js", + "title": "candidate: reentrant info text conversion cannot write after player destruction", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "f9126502b55a64b21400-579ceb3ec7e0e7c2a058", + "file": "prompt-components.spec.js", + "title": "candidate: mask finalization follows an earlier throwing observer without replacing its error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-9bc90e10e6b91381b1dc", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-14c472cf2848797472e8", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "765888057b9f843ecf53-d3fa95cf4dedc7407cd9", + "file": "resource-scope.spec.js", + "title": "internal resource scope: native DOM, RAF, timer, fetch abort and URL release", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-45f5a568a618398c2003", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-df9c2bbb8d025d633416", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0a6dee5b9d177600d5a8", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-8f64836f1c03f8d717e4", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-b4214300e6ac634d4655", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-792a2dbdf0f914f96ecd", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-22a5ed94932418b4b372", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-a632ad23423ba0506c16", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-77348d8cffa16737f1dd", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-623fad4c93a929006ed5", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9e300009a29a3180767b", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-4bd04bd342c6bdf7a25b", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-e0a456d9599734bf4dcf", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-103e07624403b62f7105", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-d07a101b915332333405", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f9ac6b159f7b68e08d1f", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-8f9455d971851037e69b", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-2ee0a5945c50d9e45f02", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f19f61a7a1c98a24d88c", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-65dd2ec52a2eb98f201a", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-6b93df0891d1e9824971", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-50103daef0af74cb00cc", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-26c20a0c8613a9c27c04", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-95ac367f79cfe12d6100", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0fa775711c5f64752304", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-ee450bc7384fa2bf264f", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-c9c9cf5e121268cd3c46", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-ca43428c5f3aaaeb4a6b", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9f3df52110132996acf1", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-d6a14bd3846cace85be0", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-f815992e0057af92552e", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-c1936aa08e32e5571887", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-e4a6e8d9ad57f6261d57", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-64493da78eb55d39fce4", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-0658f99f3c9a04fd2918", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-43884fe589ffc5240a6c", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-de63a41620e9a6fbb8a6", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-9c57f1479f12611e3650", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "b6aa675bc40ab83f8367-db263e0db17b09f39961", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-fa5dfd957b26f3982f9b", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eecbfcd48fd0b44da4", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7c987ef852f16f3323dc", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-b1e49c1b67e35ce90df3", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-a42dee36a9b3d9c4fa0c", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-bb6dd2a13ef876f27f20", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-f4bc95d33fa3669f089e", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-821001884db4778713ae", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-180bf4aaa10c590bd599", + "file": "setting-interaction.spec.js", + "title": "published: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-e6a6a636533e1ae93dfd", + "file": "setting-interaction.spec.js", + "title": "published: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c80ec0bb00165ef911a5", + "file": "setting-interaction.spec.js", + "title": "candidate: native setting keyboard and pointer actions retain range and switch callbacks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-1ca51d9b23c4840440c6", + "file": "setting-interaction.spec.js", + "title": "candidate: long setting labels leave native controls inside the row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-7529bbc5da7ba02e9881", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-249074f810c94193958f", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-5d6d4df808eaf0e9b59d", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-2fea8a03da06a8d155fc", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-84eebdf7a1b26709a4af", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "541bf3e50ab27bb647b8-c6f3f4dbe1114df7bca4", + "file": "setting-interaction.spec.js", + "title": "candidate: nested settings remain selectable with autoOrientation=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3b6abffecd638d7e143f", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-435c729ed77736ac49bf", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-b1d56ff1e9d1586f27b1", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f48f91aa1d16a05778d3", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2f0d8d05fb5628452b73", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3237a1637bb73b6d11bd", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-87851356a1e1b9a04832", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7a52d540da49d844c3dd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-2d1be2095bee8967662e", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9e91549ca39177fdc341", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-9c6b842be6a0229603b2", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-da73608d2f06c5869eb0", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04000d17fec631057431", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-eafb41732c2d02fa92d6", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-f1387f78049e2f96216d", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-04bbff86779db8d424a5", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-3cc599e6ea966ac42f1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-6c81f2fe32d5bf59df14", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after navigate", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-01382f9e44ebfe71cd1b", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-7d7a52a1212aaa3903f9", + "file": "setting-ownership.spec.js", + "title": "candidate: cached panel failure preserves navigation after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-e0bc3bdb9684a0cd782f", + "file": "setting-ownership.spec.js", + "title": "published: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-135d698a416df763c37a", + "file": "setting-ownership.spec.js", + "title": "candidate: sharing an active setting has an explicit ownership baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-5d1ce52c24eb280eaa53", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d36ff1deff6d34ea3fc8-cde9321fcd4606c1b6fd", + "file": "setting-ownership.spec.js", + "title": "candidate: a setting subtree can move to another instance after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3b4d510589021541d752", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-cf920f57a2f13b3ad575", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-57486584167b26522115", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00fb29fdb678665bd82a", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f41eb20d274264176967", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5ffb3fde2da7d4420c6c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-bf7338a3096200f9f48b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5d99a0f5b38ea58db833", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-15130b33d5a769fe6a32", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f4a165db0eeee2fbb2fb", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1e6f34f81abd19db2f8d", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5e430ce64b390617ee3", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-dadb0014a2da497a555c", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e14fb1f8f441e37f3b6a", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f5fb5476b00f686e7097", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6ef2f1516fd5d9e51fc1", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1142eddf3eb99d81c770", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-6f65c65f97d09691ecf3", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-b2bb869e9bfc30126140", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-f7de42ba4922f372e409", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8b0033bf3124c2381b88", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ee91e94bc145ebbc752c", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-0a784e55b980e4a768ea", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-53895d4a405ab4764718", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-5a3db1f978360503899f", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-ad82945116d93adc0ee9", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-34b194f9407279f8831a", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9dc273025bda0344f5c4", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1ada9c348b31da0129ce", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-fa685e4dcb072c9ea0ee", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-884c6de7c5b0cd3f6143", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8c085c86b98980387cca", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-1d032d41a8812068669c", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after assign failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-88075bd9b821bc49ad85", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after format failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-e60dc36054298fb611da", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after item failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-a97693c8c3afea09a84e", + "file": "setting-update.spec.js", + "title": "candidate: setting update restores the original range row after render failure", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-878e0cb15d6a04d11f7b", + "file": "setting-update.spec.js", + "title": "candidate: failed switch updates restore the original closure and displayed icon", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7d1e13e2a9ee5204d11b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-7c59dad85dabf535d30b", + "file": "setting-update.spec.js", + "title": "candidate: reentrant remove supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-8310d1a5474799c482fd", + "file": "setting-update.spec.js", + "title": "candidate: reentrant destroy supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-22b4165ec09c3e56b7e0", + "file": "setting-update.spec.js", + "title": "candidate: reentrant child-update supersedes an unfinished setting update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-91e7fe297e8a037196c1", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-3d9bb69b9a2c4e7a5f37", + "file": "setting-update.spec.js", + "title": "candidate: reentry inside a render getter retains the winning row with throwing=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-047950c0a6d89c18dc10", + "file": "setting-update.spec.js", + "title": "candidate: removing an ancestor cancels its pending descendant update", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-9682b6f0bf28f0a6701e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant switch getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-4c2944013559cfa3aa5e", + "file": "setting-update.spec.js", + "title": "candidate: a reentrant range getter cannot replace the winning control handles", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-2f87e96dc17cd24bf360", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant add of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "d506eaa4732c86ec7b9f-00da5bc0a7813116c372", + "file": "setting-update.spec.js", + "title": "candidate: a failed outer add preserves a reentrant update of the same object", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-d666f9cbd2bc867bad9f", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd5a610bd634cf860947", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-17ad59cd7db68e82d4e2", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-745d515c00e5ef36e018", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-cf379c3ac3906fdbd530", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-b7c2d17089053cba66fb", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-903dd2547aeab4333b8b", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-dd7bc21d13c67bacec65", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0cda73e045d032d47ee8", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2b2f887e4b2b9c1be8f0", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-c5b5c2f93a4e9a66cf63", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-357f232d33a60db07e3c", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7785bf4b3b17c1ff68a0", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3b960308df208119cf5f", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-a39e2d52b8853c5c18d0", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-65fd62ceac4a2b0de679", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f0a0ba282ce64661d749", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-544d30d9ac046c59b7d8", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-019ac6cec34bd5492707", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8f9ac72827bec9ca6d46", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f9edbb240e681f54990d", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-925ded2c1bd757ab65e0", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-494124c7cb25ce9c8484", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08ff1fea641c1071ce3e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-5fc0cb0bafacd337621d", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bda80a9e217d5482e64f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-42a6aad1e0fdb0089e55", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d6fe57647819834649e", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-76c4d4bf464d081a3736", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0f1cce7dc1de17a45a59", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-db50125db4f2a490fdbe", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-bc0f9dca801bd308ea8f", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67f07edf6c0a08c6b68d", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-14422e8869a16392d3c8", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-58025407c8f1521df7d4", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-74c1f1904ce6d8baadb1", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-2ec13de1e4838fba9146", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6a86cf5a20b7f1eeb2fa", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-eae7ba2c99c1bda33c80", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-7525b67820217feb9c11", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-681bae4b93740ef5f0c5", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-90603a7bbeaac3ebac92", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1c9713c42a024b95bd44", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-13bd01f6910054eb3295", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88dfa403dc0f8ba0f199", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-93362782d6cd1c9b38e5", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-151d89deff8c82884589", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-af17e6f132f3601b9340", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-fd13688753dec32d87cf", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-08bb1d125afe61dbdd5f", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6718d686298503531939", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0443b81b66ee434750e0", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-67266454faaf86e9f82e", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-30daf2d7d1aa4885ac63", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4939a26ab7be1b67bcf0", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f95651ee1387c941a464", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-54aa82fad20e6cdd81d7", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-88ef3f5c7107b92df586", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-f5a885749ae7733db165", + "file": "setting.spec.js", + "title": "published: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-18a5161d5a026f9fba04", + "file": "setting.spec.js", + "title": "published: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-98ca74f8f55d4b15d8a1", + "file": "setting.spec.js", + "title": "published: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-50cee2adb9a3c61f0dc6", + "file": "setting.spec.js", + "title": "published: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6bff7e83b5206fa9d91d", + "file": "setting.spec.js", + "title": "published: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8173f024a9d58630ef0a", + "file": "setting.spec.js", + "title": "published: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-da9ef20e377375a16f83", + "file": "setting.spec.js", + "title": "published: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b831b27287c07fcc40", + "file": "setting.spec.js", + "title": "published: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-691d00f15d0081cb59f7", + "file": "setting.spec.js", + "title": "published: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-845ac433ce41eb556d00", + "file": "setting.spec.js", + "title": "published: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-0a674a144ccfb1d95b83", + "file": "setting.spec.js", + "title": "candidate: builtin setting subscriptions are replaced and removed with their row", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e565aafcc819b2450df7", + "file": "setting.spec.js", + "title": "candidate: deferred setting mounts belong to the rendered item generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-29089ac1a04857021285", + "file": "setting.spec.js", + "title": "candidate: removed setting subtrees release child listeners and cached panels", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-8ee8efd4c48b9758c274", + "file": "setting.spec.js", + "title": "candidate: setting button results cannot overwrite an updated or newer item", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-6acbb8df373136b70a54", + "file": "setting.spec.js", + "title": "candidate: sibling setting selections share the parent result generation", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-07b30dc9529bcc05872a", + "file": "setting.spec.js", + "title": "candidate: setting callback rejection retains its original failure identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-1d4a2e7780e6d0550948", + "file": "setting.spec.js", + "title": "candidate: a wide nested setting panel fits the narrow player and remains selectable", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3db8330bddd94096be58", + "file": "setting.spec.js", + "title": "candidate: setting registry retains item returns and hidden tree bindings", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-38ee4ebbf8170b376a1a", + "file": "setting.spec.js", + "title": "candidate: moved setting items bind to their current parent and panel", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-51b82f8cec6133b560b9", + "file": "setting.spec.js", + "title": "candidate: automatic setting names and explicit nested names have an explicit baseline", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d2164eb08268dd10fa6", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-9bf6091babe12c0829ab", + "file": "setting.spec.js", + "title": "candidate: open settings follow container and control height changes with fallback=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-714d3a7f292b207efea6", + "file": "setting.spec.js", + "title": "candidate: failed setting additions leave existing rows usable and allow retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-3aea2df8043c6a6e28a9", + "file": "setting.spec.js", + "title": "candidate: setting removal finishes DOM cleanup when the event-removal hook throws", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-79d4c0f92c8e7ce5074b", + "file": "setting.spec.js", + "title": "candidate: failed header rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-e83b0e3f4aa0610fd15f", + "file": "setting.spec.js", + "title": "candidate: failed item rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-4d1ddd2034d35cc4620e", + "file": "setting.spec.js", + "title": "candidate: failed layout rendering releases its panel and restores reusable inputs", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-524159ddf174094337a1", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant remove", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "6e198c9007101abd57b5-ba7af307dca325c42461", + "file": "setting.spec.js", + "title": "candidate: panel creation stops after reentrant destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-833e9ff88cc7391a59b8", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6782edd72d6da4a4ad8d", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f252bd2fc447577759b0", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-3cfca19d21391eac95e4", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f888935069d847b893e1", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-8a27b9c33276ed364b5a", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-6e57082f8837ec98eb4a", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d249488159d1321fd2bb", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-df992af2e935cf8992c4", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-80521267c3361388a69c", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-32b0ab4acd28e0f0c843", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2a9cd3695fb54d9983eb", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-e7b06471c09b919d19a9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-d4cb7cdf6b423439b579", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-f9ef3279fa413557bf74", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-4493fdd9f9a0b065a5d9", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-ff9db48194323087ff35", + "file": "source.spec.js", + "title": "published: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-b3f7622fc945984018c1", + "file": "source.spec.js", + "title": "published: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-9007396b1c807988496b", + "file": "source.spec.js", + "title": "candidate: rapid real-media switches identify the last restart and settle superseded work", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-7720ba65254587e4220f", + "file": "source.spec.js", + "title": "candidate: destroy settles the candidate switch without waiting for detached media", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-0dfab8dfb052a78725c9", + "file": "source.spec.js", + "title": "candidate: quality switch restores position/rate and preserves real customType identities", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-eb73224c6fba7201b543", + "file": "source.spec.js", + "title": "candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-2206320b5471e792b324", + "file": "source.spec.js", + "title": "candidate: real switch settles when the controlled native resume rejects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "1388a037bfe564bf4e3b-42d36054a79412ea814c", + "file": "source.spec.js", + "title": "candidate: late native play completion cannot publish stale player effects", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8a5fef92ae9112a22e17", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7c15928bbf9cf5446364", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3e105514fdcdf2109560", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b17f3a99113bcd921376", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-5a386ba920946118f5b9", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f152343084d96e444c25", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-19e34f584147a850810d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e6b47b2e4f1d89fdc1fd", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c54ff96a656f8f7e0614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-209d6e601169222401ec", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-0224c5f81d88e9a76abd", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bbf01adc9fea833a654f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-df809aca00e2b669dace", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-016cc1640e3b3d043bee", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-07dc4321a38968280cbb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-7334ec778cda78e83768", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4a0c98327b25b0f53349", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-3d4383aae663249070b4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ac1f881dcd7c9ea6b614", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2fc6f4437794b5fcae1a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-affdcf01df5b548e74c3", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e69a2633d1da5da0a033", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-eed34e3a1de997f80105", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-6f3db740e84bd4583de0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75a2ce3c50f0326338d6", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-40d428be335e78a03d78", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1e51854f9804aaa89760", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-f0bedbeadb96666727d5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ef9c82e81e4bc84eb35a", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a206e4dec77195448b2e", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b6a8e78c8bade555f99f", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1da818cd320f200493dc", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-37e8784fe2be118a89cb", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-baf78a292febd2d0253b", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2f67378d9be913549ee4", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ce42453036328047efb1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8354c7d516c210cb683f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c2c4c0e141302c3cef1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03df75134609c4dfbf10", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-23e94238a1be63a9aedb", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-306ec942a307ac4b332a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-27ea66e30846c6c35d1f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1ff068f72f09e1062c71", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-49268197eca684b03b23", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-45d66a58f8ace121aa3e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d55737ce84e01c268c81", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-de5ebfc899aee6d78694", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-80a4fc6eab4db076a7ce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d11efb83fe4bb3c07013", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8b874818fa453c7e6f49", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-644e384fedb167647bc1", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-97913b921f13e91b4542", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-315d8c53bcd83acda5c2", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d511fccbe7e54abf3fce", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bf9ed48af22e7dec6f9d", + "file": "subtitle-lifecycle.spec.js", + "title": "published: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-d8cac70b11a66ba978c8", + "file": "subtitle-lifecycle.spec.js", + "title": "published: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0d22129fdcac1480ab5", + "file": "subtitle-lifecycle.spec.js", + "title": "published: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-75861334d0fffb96d413", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-4d9c22a343ef35f5b877", + "file": "subtitle-lifecycle.spec.js", + "title": "published: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ae3ab743fb1aecf74832", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e402f7c34fc93b9cb6be", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-946b1205dfcbfb6f7daf", + "file": "subtitle-lifecycle.spec.js", + "title": "published: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-bd0e7d1620bf7e83e671", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: srt conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-54c89f9444bb550d9372", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: ass conversion reaches native cues with original callback binding", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-e0913a2d6fc2540d8a18", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: video fullscreen signal rebuilds track kind while retaining its URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-03dbb2c377fe45aa14c0", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle remains visible through real native fullscreen", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-066d3480dcdc71e8a4e9", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle cues, offset, styles and show contracts", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18cf581403b35016dd5b", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle latest request wins and cancelled calls settle", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-c7b04385144f290eee56", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle pending completion cannot replace track after destroy", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-18e90e6d63836e36b04f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle owns generated URLs and leaves caller URLs alive", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-350e2e7d4721dc11ee0a", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle cancellation settles before an ignored request or body finishes", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-8ebec3e26df820a018bc", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle conversion reentry preserves the newer operation and notice", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-da28a74d360e5e5f4da8", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: active subtitle errors reject, preserve track and allow a later retry", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b87e2eed66add761c939", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: subtitle HTTP failures do not become usable tracks", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-1eb214dd7fb6d08cd588", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: disabled native tracks expose empty cue arrays without throwing", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-a9c047aa7f9899ee2e91", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: native subtitle track failure is reported and obsolete callbacks are removed", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-ed84cf26fe663abba84e", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: constructor and URL setter failures notify without unhandled promises", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-b975a9d80a73ee2c5318", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=false", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-2325734fcbe9f19ef38f", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: reentrant track replacement keeps the winner when outer throws=true", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-53fa73e3d56972e17fb4", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: failed track insertion restores the old live track and releases the attempted URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "bd8b578824fda6d824e5-68d9c42770fb755ff944", + "file": "subtitle-lifecycle.spec.js", + "title": "candidate: cleanup failure after track commit does not revoke the committed URL", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-bf645b1a65cbfaea5769", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-9d765289d32be33b1358", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-aa26d2ab16bfa364ede5", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e05941de94496050665", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-07b5247e88feb728a1ea", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c585b499b392d1f3125b", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-807c73d105e8d88f3691", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "chromium", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-3a8724253f4ed9d64051", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0c1741b96b329426a59c", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-842c1a319c8ec887e2da", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0e3cc6ce8bb29447e4aa", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3157016a1f4a564e4e36", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0bf30ca101daa48f2926", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-f15c420a1fe6dde01ad5", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-d062fb6e304335da8017", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ab3a301f236c4211d0b0", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-db1474abf9d021d54190", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3fad5bde9035571dfeb1", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-527a6a05cfabdad5e934", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "firefox", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": false + } + }, + { + "id": "ea1be0d464ef792edb71-06d2174f2fcf7425f220", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-84b620f68a13175455c6", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65451ddd2f6fb97e5b62", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-91327ada1dd05e2a6298", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-ea62643a3c6b46fbb710", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-122f023f6398972e230c", + "file": "template-resources.spec.js", + "title": "published: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-651f98b0f143502c508d", + "file": "template-resources.spec.js", + "title": "published: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-65bebbe49c153c2d5f16", + "file": "template-resources.spec.js", + "title": "published: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-51c0c54a3382808aa510", + "file": "template-resources.spec.js", + "title": "published: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-3670c81ddbb8cd20a30b", + "file": "template-resources.spec.js", + "title": "published: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-9d3c02ac24a72b007bac", + "file": "template-resources.spec.js", + "title": "published: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-62ac1fcd49c58719b731", + "file": "template-resources.spec.js", + "title": "candidate: native fullscreen uses a real gesture when the engine supports it", + "engine": "webkit", + "status": "passed", + "retry": 0, + "nativeFullscreen": { + "native": true, + "video": true + } + }, + { + "id": "ea1be0d464ef792edb71-a0a212ed633e0fcae542", + "file": "template-resources.spec.js", + "title": "candidate: SSR mounting preserves nodes, listeners, selectors and style ownership", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-fdf8e58e63293f008154", + "file": "template-resources.spec.js", + "title": "candidate: proxy replacement preserves callback and node identity", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-6749a7d57a0a08031b98", + "file": "template-resources.spec.js", + "title": "candidate: icon access preserves descriptors and moves custom DOM into fresh wrappers", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-c71eda7665d7fe280226", + "file": "template-resources.spec.js", + "title": "candidate: i18n prototype fallback difference and custom keys are explicit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "ea1be0d464ef792edb71-0f9982e28da4776b41df", + "file": "template-resources.spec.js", + "title": "candidate: fullscreen web retains DOM and CSS hooks through entry and exit", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-0b84034df4da7a0602cb", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-27b7b29e95483cbd0627", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-c501a3337d7f3459c0bd", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7590e561a95171418094", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-ef943cb95bbec2be8e9f", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-35d168c9c28975e08fe1", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-15f9f09a8e027b4f1453", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7ac5238b9dd76e5bd284", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-cbdca6544e577990fbe6", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-ae0fe968cf56f04deadf", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3ea053475afbb979f768", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-e717f553b51ae759828d", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-36518c4875e5c6c5eb4d", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-e4dbbda8c6e5556ff597", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3aa635296202313cceb6", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7889e72271358857e901", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-80303351d5af14d7bcba", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-6303b616b2bb5f58f229", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-b18b5d8413c96e250a43", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-cdb048780d3502ba5f34", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3cd51c32262f07831a10", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-bdd8944a779d3e0838d2", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-3ea1350b66dcf3b9e182", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "c863e7942d336f9fc9b4-7e155f3c5195944a8163", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-47bf44da43f7ea630c57", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-94a91f70513a4f3a0536", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8bed1f155fdd13a8d676", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-76ae798ce585defae260", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-940ea42ed81a2e76857e", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "chromium", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-fe6258362fcc32df0641", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-3976dbe5125baf9596ea", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-e85621f95b6a8e48ca8c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8aa46f4bdea9ab2db828", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-8da0c6598ba3b3f02663", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "firefox", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-d7bcbbb91d28521d7e10", + "file": "utils.spec.js", + "title": "published: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-737ee111c8455e9547dd", + "file": "utils.spec.js", + "title": "published: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-0a0f67812bab08126d1c", + "file": "utils.spec.js", + "title": "candidate: subtitle object URL contains real VTT data", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-dbbe30e49f81e686c544", + "file": "utils.spec.js", + "title": "candidate: download starts and removes its temporary anchor", + "engine": "webkit", + "status": "passed", + "retry": 0 + }, + { + "id": "57073515c58af9afa33c-81ecbd7fd933b26d5381", + "file": "utils.spec.js", + "title": "candidate download releases the anchor even when click fails", + "engine": "webkit", + "status": "passed", + "retry": 0 + } + ], + "reportSha256": "560492cb9035b219b83b819030fcdca4b155f57d88d51f891f2fedcfa3f48689" + }, + "packageReportSha256": "4baa96d534e4fb5d4b3af51fec085e27f3748919817111f3e1eea57e3e444328", + "publicTypes": { + "changed": false, + "strategy": "Preserve historical public declarations and validated consumer inputs; accurate readonly/writeonly views remain CORE-21." + }, + "phases": [ + { + "file": "refactor/baselines/screenshot-partial.json", + "sha256": "ed7e2059b0a5ff18fa12e1f2c1dc5425f62f645d102b3fd2fb236309ad529dc2", + "scope": "Historical intermediate source; not final candidate evidence." + }, + { + "file": "refactor/baselines/capture-thumbnails-partial.json", + "sha256": "38af7267c6c0e1892ff7fa8a01af28ae8ff4a703c10b4b4bd2b695d8ec2ef304", + "scope": "Historical intermediate source; not final candidate evidence." + } + ], + "investigations": [ + { + "report": "refactor/.cache/core19-progress-browser.json", + "sha256": "5e3f80e6acc2e8d9cc36d5a73c290282ca305dd550309be556178cf43ceabbff", + "stats": { + "startTime": "2026-09-11T05:17:00.002Z", + "duration": 30270.964, + "expected": 38, + "skipped": 0, + "unexpected": 4, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-quality-deferred.json", + "sha256": "b9521dcb67e7eff1b5b0034716718fbc9361395e4761ddff784b442c3fc8578d", + "stats": { + "startTime": "2026-09-11T05:31:11.604Z", + "duration": 20289.485, + "expected": 13, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-quality-correction.json", + "sha256": "09bf482ee727aafc5a41b0a54d2c73cd6bd1e3d641bc67427d9c29e4d8473c53", + "stats": { + "startTime": "2026-09-11T05:34:46.586Z", + "duration": 33307.389, + "expected": 14, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-quality-correction-fixed.json", + "sha256": "738066ee73afb5ae210af566fe4b4de98c4efa69845105ccb295923703a9f1a2", + "stats": { + "startTime": "2026-09-11T05:38:39.178Z", + "duration": 17334.191, + "expected": 15, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-source-targeted-final.json", + "sha256": "8494a7a04215fa724e1d1f44495d4adb359219e9e1506c090a39f84e9ab57d62", + "stats": { + "startTime": "2026-09-11T05:40:38.468Z", + "duration": 52627.563, + "expected": 126, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-installed-umd.json", + "sha256": "534bcad813efd9b4bdfea581cd6a1a32e524d6bfbc816af3ca047e12d931105d", + "stats": { + "startTime": "2026-09-11T05:44:20.191Z", + "duration": 362292.913, + "expected": 1455, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-installed-legacy.json", + "sha256": "753a9964a5da5ec24224bf977de4fecea12839ad78adc43a940abd571b8d56ce", + "stats": { + "startTime": "2026-09-11T05:50:57.829Z", + "duration": 358025.605, + "expected": 1455, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-direct-position-before.json", + "sha256": "2d04c70bc3f47a6bb032880aa6cd835a00946eb16bdb3cbdf980fb4a0caa8f59", + "stats": { + "startTime": "2026-09-11T05:57:44.956Z", + "duration": 4776.656000000001, + "expected": 0, + "skipped": 0, + "unexpected": 3, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-direct-position-after.json", + "sha256": "50d6c320845dd3b075e1ddc9368b35204b81882cf844651782dde50ab41bd2fb", + "stats": { + "startTime": "2026-09-11T05:58:02.265Z", + "duration": 6240.423, + "expected": 2, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-direct-position-diagnostic.json", + "sha256": "f78c1ade55e5892b28176e0a88d334beca5b8c17ee61e359584e4fa8d23a7081", + "stats": { + "startTime": "2026-09-11T05:59:13.511Z", + "duration": 13713.252999999999, + "expected": 1, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-direct-position-contract-before.json", + "sha256": "f6021a54797b7d78a3b735fc0b884f1b80ae3d151295376c199103469b28fea9", + "stats": { + "startTime": "2026-09-11T06:01:19.893Z", + "duration": 4052.2270000000003, + "expected": 1, + "skipped": 0, + "unexpected": 2, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-direct-position-contract.json", + "sha256": "a7e6a5cdc27836b6b4a9f75c14571cbbc01b126ff3c301a19cd38654229d6363", + "stats": { + "startTime": "2026-09-11T06:01:12.681Z", + "duration": 6109.032, + "expected": 3, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-revision-installed-umd.json", + "sha256": "eb2eb0952d34f15490c0fd4caae06f5d54aca315ebeaa6ea3f81b3fbb6e07fb9", + "stats": { + "startTime": "2026-09-11T06:01:41.375Z", + "duration": 423112.266, + "expected": 1457, + "skipped": 0, + "unexpected": 1, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + }, + { + "report": "refactor/.cache/core19-hotkey-setup-fixed.json", + "sha256": "012dcfa31357a6d3863812fe67cfcfc5230602c91cc899710b1329919a14afef", + "stats": { + "startTime": "2026-09-11T06:10:51.544Z", + "duration": 5852.648999999999, + "expected": 3, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "scope": "Historical diagnostic or intermediate source/fixture run; not final acceptance evidence." + } + ], + "build": { + "logSha256": "a0523f44f4c422295a3078c161484f90aa5a58660b02a9a98f717cd86ca6b8a3", + "i18nLogSha256": "cb30be719aaf0c271cebbde0a22feb62dfd5af99cca8f38c4d1fa47f0e3fc420" + }, + "resolvedFindings": [ + "BASE-LIFE-36", + "BASE-LIFE-37", + "BASE-LIFE-38", + "BASE-LIFE-39", + "BASE-LIFE-40", + "BASE-LIFE-41", + "BASE-LIFE-42", + "BASE-LIFE-43", + "BASE-LIFE-44", + "BASE-DOM-19" + ], + "limits": [ + "This task covers the core and chapter integration, not the remaining ecosystem migration or release reviews.", + "Windows WebKit 26.6 native MP4/WebM Blob probes fail with error 4; byte ownership and HTTP playback are tested, native Blob decoding is not claimed. BASE-ENV-01 remains REL-03/REVIEW-02.", + "Physical devices, Safari and external integration environments remain separate release gates.", + "Known published screenshot and auto-resume rejections are matched exactly; no unexpected page errors are accepted.", + "A native position miss receives at most one correction. The code does not promise arbitrary codec or adapter seek accuracy.", + "The direct-currentTime browser case verifies no obsolete native setter write. WebKit reentrant seek clocks vary; ordinary quality restoration retains independent numeric position/rate assertions.", + "Public caller-created media/image/capture URLs remain caller-owned; consumers must release them when finished.", + "No dependency or lockfile changes, major version application, push, remote CI, publication or full-goal completion in this task." + ] +} diff --git a/refactor/baselines/capture-thumbnails-partial.json b/refactor/baselines/capture-thumbnails-partial.json new file mode 100644 index 000000000..5a0395420 --- /dev/null +++ b/refactor/baselines/capture-thumbnails-partial.json @@ -0,0 +1,597 @@ +{ + "task": "CORE-19", + "status": "partial", + "date": "2026-09-11", + "node": "v24.21.0", + "parentCommit": "98a18000321500f92f228be7b7edff4bda948a56", + "scope": "Capture and thumbnails source migration. Progress/quality and borrowed media URL ownership review, final builds and installed-package exit remain outstanding.", + "fingerprints": { + "package.json": "a288e650a0a65e5c036b8504e8f01f4039e609798066741171045a1f1da4262f", + "yarn.lock": "80c78af925697e0ae55fae48a6a0761c60d231737a389324c82b6efef437f7c4", + "packages/artplayer/ARCHITECTURE.md": "f500068cbf7a6a3259887d4ae21e96da61753558841ab6510904148270b08d58", + "packages/artplayer/src/player/screenshotMix.ts": "fb16737d3bb2735ef0d0aa1ebe536cc3418c27d92e1b66ad4b34e81c165773b2", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/control/screenshot.ts": "67be1306991861cb8bb0adec2b58a8468211459f9337895e611972dbb71a6ef5", + "packages/artplayer/src/player/thumbnailsMix.ts": "6c097d7d00779a6d0d3d65cf9ffd126624a48c9bdb98396c84c39f4de4bdf712", + "packages/artplayer/src/thumbnails/layout.ts": "6630439242a880f53fcb374b7b15c7f486405aab8a0fad651b137f02971eeb59", + "packages/artplayer/src/image/load.ts": "b4f1517243249d5fb017b89f993660e8b148906bbf28d08fe5c9f6d3a41e1e88", + "packages/artplayer/src/utils/dom.js": "fd6148ff85ee97607de54652f0f1e4cb5158f628a2d0951f1946a21f2b4e0008", + "test/screenshot.test.js": "740e879c9159c75e62240d37e3a327facb228f54b0b531e9da375c1f184abb24", + "test/thumbnails.test.js": "367882200a3898cce718379f95bb80706d9d5ee06e8d8e3624acada118ccc41c", + "test/types/screenshot.ts": "f329d9b897e9e9e4190ebc6ededfe55ccd0bebf796683615af103c19cf6b3947", + "test/types/thumbnails.ts": "2b01c655ad30be3e9ef6732d13f85dbdf32cf71c734d63537bdb0f82ac69350c", + "test/browser/screenshot.spec.js": "a2b49fbd8616533fc351892c1f6687d588d2bc9350fda4be5475decb97d77a0e", + "test/browser/thumbnails.spec.js": "bc00e6fe6eb6987bd36193f26c69e2377249b53f41dfc1474dd44d6e833a2c09", + "test/browser/media/thumbnail-grid.svg": "bb3f1ec9895d37def77ca4b192d3cd73577a2668558cc99de1588f511d65d3e6", + "test/browser/server.mjs": "2b36e65ed9248f334b6dfb2d54a22cf5a26b3b531d7eb1f93392e38bb14d10cc" + }, + "before": { + "file": "refactor/.cache/core19-thumbnails-before.log", + "sha256": "34f9d1cade73482bf90d05775db461a0dbf18b47dfba755127f52f6a873bf531", + "tests": 7, + "passed": 2, + "failed": 5, + "note": "Initial baseline used the old crop expectations; after generator review, final tests explicitly validate corrected zero-based grid cells." + }, + "ci": { + "tests": 401, + "unit": 372, + "engineering": 4, + "baseline": 25, + "screenshotTests": 11, + "thumbnailTests": 18, + "productionTs": 205, + "publicTypesUnchanged": true, + "file": "refactor/.cache/core19-thumbnails-ci.log", + "sha256": "c47ada46288646b0a817504b353be4bd3620490af051e986329561f6fa523353" + }, + "browser": { + "format": "Source-built UMD; not an installed tarball", + "tests": 63, + "screenshot": 39, + "thumbnail": 24, + "retries": 0, + "skipped": 0, + "unexpectedPageErrors": 0, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "knownRejections": [ + { + "browser": "chromium", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "chromium", + "core": "candidate", + "rejections": [] + }, + { + "browser": "firefox", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "firefox", + "core": "candidate", + "rejections": [] + }, + { + "browser": "webkit", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "webkit", + "core": "candidate", + "rejections": [] + } + ], + "artifacts": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.js" + }, + "sha256": "a5a5f9283af11841dc5f6d234012a16738f68d4549c704ef9bb0da93fe2a8493", + "bytes": 323694 + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/published/artplayer.js": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + } + }, + "cases": [ + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-45f5a568a618398c2003", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-df9c2bbb8d025d633416", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-0a6dee5b9d177600d5a8", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-8f64836f1c03f8d717e4", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-b4214300e6ac634d4655", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-792a2dbdf0f914f96ecd", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-22a5ed94932418b4b372", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-a632ad23423ba0506c16", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-77348d8cffa16737f1dd", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-623fad4c93a929006ed5", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-9e300009a29a3180767b", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-4bd04bd342c6bdf7a25b", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-e0a456d9599734bf4dcf", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-103e07624403b62f7105", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-d07a101b915332333405", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-f9ac6b159f7b68e08d1f", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-8f9455d971851037e69b", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-2ee0a5945c50d9e45f02", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-f19f61a7a1c98a24d88c", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-65dd2ec52a2eb98f201a", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-6b93df0891d1e9824971", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-50103daef0af74cb00cc", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-26c20a0c8613a9c27c04", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-95ac367f79cfe12d6100", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-0fa775711c5f64752304", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-ee450bc7384fa2bf264f", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-c9c9cf5e121268cd3c46", + "file": "screenshot.spec.js", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-ca43428c5f3aaaeb4a6b", + "file": "screenshot.spec.js", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-9f3df52110132996acf1", + "file": "screenshot.spec.js", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-d6a14bd3846cace85be0", + "file": "screenshot.spec.js", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-f815992e0057af92552e", + "file": "screenshot.spec.js", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-c1936aa08e32e5571887", + "file": "screenshot.spec.js", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-e4a6e8d9ad57f6261d57", + "file": "screenshot.spec.js", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-64493da78eb55d39fce4", + "file": "screenshot.spec.js", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-0658f99f3c9a04fd2918", + "file": "screenshot.spec.js", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-43884fe589ffc5240a6c", + "file": "screenshot.spec.js", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-de63a41620e9a6fbb8a6", + "file": "screenshot.spec.js", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-9c57f1479f12611e3650", + "file": "screenshot.spec.js", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-db263e0db17b09f39961", + "file": "screenshot.spec.js", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-0b84034df4da7a0602cb", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-27b7b29e95483cbd0627", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-c501a3337d7f3459c0bd", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-7590e561a95171418094", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-ef943cb95bbec2be8e9f", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-35d168c9c28975e08fe1", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-15f9f09a8e027b4f1453", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "status": "passed" + }, + { + "browser": "chromium", + "id": "c863e7942d336f9fc9b4-7ac5238b9dd76e5bd284", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-cbdca6544e577990fbe6", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-ae0fe968cf56f04deadf", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-3ea053475afbb979f768", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-e717f553b51ae759828d", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-36518c4875e5c6c5eb4d", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-e4dbbda8c6e5556ff597", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-3aa635296202313cceb6", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "status": "passed" + }, + { + "browser": "firefox", + "id": "c863e7942d336f9fc9b4-7889e72271358857e901", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-80303351d5af14d7bcba", + "file": "thumbnails.spec.js", + "title": "published: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-6303b616b2bb5f58f229", + "file": "thumbnails.spec.js", + "title": "published: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-b18b5d8413c96e250a43", + "file": "thumbnails.spec.js", + "title": "published: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-cdb048780d3502ba5f34", + "file": "thumbnails.spec.js", + "title": "candidate: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-3cd51c32262f07831a10", + "file": "thumbnails.spec.js", + "title": "candidate: scaled internal thumbnails and public image results have distinct Blob URL owners", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-bdd8944a779d3e0838d2", + "file": "thumbnails.spec.js", + "title": "candidate: a delayed image follows the latest hover rather than the first request position", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-3ea1350b66dcf3b9e182", + "file": "thumbnails.spec.js", + "title": "candidate: removing thumbnails revokes the scaled image and a replacement control can reload", + "status": "passed" + }, + { + "browser": "webkit", + "id": "c863e7942d336f9fc9b4-7e155f3c5195944a8163", + "file": "thumbnails.spec.js", + "title": "candidate: image failure permits a retry through the same thumbnail configuration", + "status": "passed" + } + ], + "file": "refactor/.cache/core19-capture-thumbnail-browser-final.json", + "sha256": "78fa8caf62f1acadeec505c96cea3d8b082f999f6cad99e2182938046525b1b5" + }, + "earlierFailure": { + "file": "refactor/.cache/core19-thumbnails-browser.json", + "sha256": "4f7be130c6ed4bdd63f447769b18f777eb6e09f2b094d5a283d14093a35582e9", + "passed": 62, + "failed": 1, + "description": "Firefox retry case using a malformed successful response failed. Fixture now explicitly uses a no-store transient HTTP 503, with two network attempts verified. No timeout increase or broad error suppression." + }, + "remaining": [ + "Progress callback/drag source lifetime review", + "Quality boundaries", + "Borrowed media URL ownership review", + "Build, installed tarball and full UMD/legacy browser exit", + "Final risk closure, task status and independent local commit" + ] +} diff --git a/refactor/baselines/screenshot-partial.json b/refactor/baselines/screenshot-partial.json new file mode 100644 index 000000000..9924970dd --- /dev/null +++ b/refactor/baselines/screenshot-partial.json @@ -0,0 +1,371 @@ +{ + "task": "CORE-19", + "status": "partial", + "date": "2026-09-11", + "parentCommit": "98a18000321500f92f228be7b7edff4bda948a56", + "node": "v24.21.0", + "scope": "Screenshot source migration only. Thumbnail migration, progress/quality review, generated distribution and installed-package validation remain outstanding.", + "fingerprints": { + "packages/artplayer/src/player/screenshotMix.ts": "fb16737d3bb2735ef0d0aa1ebe536cc3418c27d92e1b66ad4b34e81c165773b2", + "packages/artplayer/src/capture/frame.ts": "eb25d81ec2d40a239103c63cfd80333705251291f2c2da77c740b4d413ea9cd9", + "packages/artplayer/src/control/screenshot.ts": "67be1306991861cb8bb0adec2b58a8468211459f9337895e611972dbb71a6ef5", + "test/screenshot.test.js": "740e879c9159c75e62240d37e3a327facb228f54b0b531e9da375c1f184abb24", + "test/types/screenshot.ts": "f329d9b897e9e9e4190ebc6ededfe55ccd0bebf796683615af103c19cf6b3947", + "test/browser/screenshot.spec.js": "a2b49fbd8616533fc351892c1f6687d588d2bc9350fda4be5475decb97d77a0e", + "package.json": "97a0860bb31a4ddae2db96854da1d5531e2d0c14c3b87e487336eb7edb64f2d5", + "yarn.lock": "80c78af925697e0ae55fae48a6a0761c60d231737a389324c82b6efef437f7c4", + "packages/artplayer/ARCHITECTURE.md": "00bcea6fa0424121f98d107448b7a1fd07bab32accbdd2f79cef8f60bafa48ae" + }, + "before": { + "log": "refactor/.cache/core19-screenshot-before.log", + "sha256": "0e05e3a1abf0a4039eeaf243e89cfd0b094be41a862f269c823ae18af9bdde94", + "tests": 7, + "passed": 3, + "failed": 4, + "source": "HEAD screenshotMix.js before migration" + }, + "ci": { + "tests": 383, + "unit": 354, + "engineering": 4, + "baseline": 25, + "productionTs": 202, + "screenshotTests": 11, + "publicTypesUnchanged": true, + "log": "refactor/.cache/core19-screenshot-ci.log", + "sha256": "84b2b0725cf85bedaebada67dba574af47a7d959a6dcc960183d789577bc9fa6" + }, + "browser": { + "format": "source-built UMD, not installed tarball", + "tests": 39, + "retries": 0, + "skipped": 0, + "unexpectedPageErrors": 0, + "versions": { + "chromium": "153.0.8010.12", + "firefox": "155.0", + "webkit": "26.6" + }, + "knownRejections": [ + { + "browser": "chromium", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "chromium", + "core": "candidate", + "rejections": [] + }, + { + "browser": "firefox", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "firefox", + "core": "candidate", + "rejections": [] + }, + { + "browser": "webkit", + "core": "published", + "rejections": [ + "controlled screenshot draw failure" + ] + }, + { + "browser": "webkit", + "core": "candidate", + "rejections": [] + } + ], + "artifacts": { + "/candidate/artplayer.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.js" + }, + "sha256": "ef9fadfd897b2062d3f5661a0bb5640bf46ead4e3cae4ef6147114fe51250745", + "bytes": 319634 + }, + "/candidate/artplayer-plugin-chapter.js": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer-plugin-chapter\\src\\index.ts" + }, + "sha256": "3e8d0b7e7a90b5dbadf4cb108fd770d294f8a8a92ea089c41d0766c98bbc8230", + "bytes": 8433 + }, + "/published/artplayer.js": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "/published/artplayer-plugin-chapter.js": { + "source": { + "kind": "npm-release", + "version": "1.1.0", + "integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==", + "member": "package/dist/artplayer-plugin-chapter.js" + }, + "sha256": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0", + "bytes": 4973 + } + }, + "cases": [ + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-45f5a568a618398c2003", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-df9c2bbb8d025d633416", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-0a6dee5b9d177600d5a8", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-8f64836f1c03f8d717e4", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-b4214300e6ac634d4655", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-792a2dbdf0f914f96ecd", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-22a5ed94932418b4b372", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-a632ad23423ba0506c16", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-77348d8cffa16737f1dd", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-623fad4c93a929006ed5", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-9e300009a29a3180767b", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-4bd04bd342c6bdf7a25b", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "chromium", + "id": "b6aa675bc40ab83f8367-e0a456d9599734bf4dcf", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-103e07624403b62f7105", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-d07a101b915332333405", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-f9ac6b159f7b68e08d1f", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-8f9455d971851037e69b", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-2ee0a5945c50d9e45f02", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-f19f61a7a1c98a24d88c", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-65dd2ec52a2eb98f201a", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-6b93df0891d1e9824971", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-50103daef0af74cb00cc", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-26c20a0c8613a9c27c04", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-95ac367f79cfe12d6100", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-0fa775711c5f64752304", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "firefox", + "id": "b6aa675bc40ab83f8367-ee450bc7384fa2bf264f", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-c9c9cf5e121268cd3c46", + "title": "published: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-ca43428c5f3aaaeb4a6b", + "title": "published: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-9f3df52110132996acf1", + "title": "published: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-d6a14bd3846cace85be0", + "title": "published: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-f815992e0057af92552e", + "title": "published: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-c1936aa08e32e5571887", + "title": "candidate: captures decoded PNG pixels and consumer-owned Blob URLs", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-e4a6e8d9ad57f6261d57", + "title": "candidate: screenshot preserves download filename, event data and Promise result", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-64493da78eb55d39fce4", + "title": "candidate: actual cross-origin video rejects capture with SecurityError and notice", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-0658f99f3c9a04fd2918", + "title": "candidate: source replacement does not download a stale captured frame", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-43884fe589ffc5240a6c", + "title": "candidate: screenshot toolbar rejection has exact historical error accounting", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-de63a41620e9a6fbb8a6", + "title": "candidate: null toBlob callback rejects and reports without a page error", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-9c57f1479f12611e3650", + "title": "candidate: destroy during screenshot await suppresses the queued download and event", + "status": "passed" + }, + { + "browser": "webkit", + "id": "b6aa675bc40ab83f8367-db263e0db17b09f39961", + "title": "candidate: cross-origin screenshot toolbar handles its internal rejected Promise", + "status": "passed" + } + ], + "log": "refactor/.cache/core19-screenshot-browser-v2.json", + "sha256": "117aa85284e99d5fd5c2fc030e5ada2f68df4df321702ee7048a6f95badc283d" + }, + "remaining": [ + "Thumbnail generation, loading errors and internal Blob ownership", + "Quality/progress boundary regression", + "Full CORE-19 type/build/installed tarball browser validation", + "Close registered risks only with final evidence", + "Complete task documentation and separate local commit" + ] +} diff --git a/refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md b/refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md new file mode 100644 index 000000000..81324fdae --- /dev/null +++ b/refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md @@ -0,0 +1,89 @@ +# CORE-19 进度、质量、截图与缩略图 + +## 范围与状态 + +基线 `98a18000`,分支 `codex/compatible-modernization`。源码和完整任务验收完成;下文分阶段 doing/待验证描述保留历史过程。关联 API-02/03/04/05/08/11/12。 + +任务开始时,进度与质量已在 CORE-13/17 迁移 TS,本任务复核其计算及边界;截图、缩略图当时仍为 JS。本任务拆出图像捕获和布局计算,明确异步请求与资源归属,保持公共声明、方法描述符、PNG 返回值、截图事件、文件名和缩略图 DOM/CSS。 + +## 旧实现事实与待验证问题 + +- screenshotMix 在 Promise executor 内捕获绘制异常,但 toBlob 的异步回调没有异常捕获。空 Blob 或 createObjectURL 异常可能留下 pending Promise;先用受控回调复现。 +- getBlobUrl 返回的 URL 交给消费者使用;不能在播放器销毁时自动撤销一个仍被消费者使用的 URL。调用方负责 URL.revokeObjectURL。 +- screenshot 等待 getDataURL 后没有检查销毁或换源;需防止晚到截图触发下载/事件,保持已经产生的字符串结果。 +- thumbnailsMix 在配置替换后仍接受旧 loadImg 结果;加载失败没有清理 loading 标志。缩放 loadImg 内创建的 Blob URL 无成功释放路径,需明确内部所有权。 +- 缩略图历史行列计算需建立固定输入基线并核对生成工具;后续已复现裁剪错误,修复差异见下文,不能作为未声明的布局改动。 + +## 计划验证 + +受控 Node 用例覆盖同步绘制、异步失败/空 Blob、并发、销毁和替换。真实浏览器比较发布版/候选版 PNG 内容、截图文件名/事件、跨域失败、缩略图布局与加载顺序;复验质量和进度。严格类型检查、正常构建、实际 tarball 消费和安装产物浏览器检查完成前不标 done。 + +不新增依赖或更改版本。测试脚本按需接入已有 Node runner。包内 ARCHITECTURE.md 随实施维护。任务完成后独立提交 `refactor(core): CORE-19 type capture and preserve progress lifetimes`;回退该任务提交并按原工具链重建产物。 + +## 截图阶段实现与实测 + +- 新增 capture/frame.ts,截图门面迁移到 player/screenshotMix.ts。公共声明不变;绘制仍在调用栈同步完成,避免 await 之后取到不同帧。默认文件名仍读取等待之后的 currentTime,后缀始终追加 .png。 +- 异步 null Blob/createObjectURL 失败明确拒绝;同步 toBlob/drawImage 异常仍在返回 Promise 前更新 notice。缺少 2D context 保留 TypeError 类别并提供明确消息。notice setter 自身抛错也变成拒绝。 +- 返回 Blob URL 不随播放器销毁撤销,由调用者管理。已捕获结果照常结算,销毁/切源后不下载、不发 screenshot 事件、不覆盖 notice。错误事件监听器的异常仍遵循原 Promise 传播机制。 +- 内部截图工具栏用 silencePromise 消费拒绝;公开 screenshot/getDataURL/getBlobUrl 不吞错。发布版工具栏的受控失败每个浏览器产生一次未处理拒绝;用严格 Error 对象身份登记该已知历史错误,不屏蔽其他 pageerror。 +- 这是截图阶段的历史记录,随后缩略图已继续迁移;不要把截图阶段证据当成整个 CORE-19 完成。 + +阶段证据见 baselines/screenshot-partial.json。初始旧代码 7 项中 3 通过、4 失败;候选截图专项扩展到 11 项通过。CI 354 单元 + 4 工程 + 25 基线 = 383 项;202 个生产 TS 严格检查,五组消费者模式通过。源码构建 UMD 的三浏览器截图 39 项通过,无重试、跳过或意外 pageerror;真实跨域使用相同本地服务的不同 hostname,无 CORS 放行。 + +本阶段不是安装 tarball 验收,没有重建正式 dist/docs 分发产物;对应完整验收仍在本任务中待执行。BASE-LIFE-36/37/38 保持 open,等待任务最终证据。没有新增依赖或修改 yarn.lock,仅将 screenshot.test.js 接入既有 test:unit 脚本。 + +## 缩略图阶段实施 + +thumbnailsMix.ts 管理配置代次、缓存、最新悬停位置和控件生命周期;thumbnails/layout.ts 负责纯几何。image/load.ts 复用公开 loadImg 与内部加载,不复制两套缩放逻辑。公开 utils 只继续导出 loadImg,内部 loadThumbnailImage 不加入公开对象。public loadImg 的名称、形参数量、Promise 和成功 Blob 所有权保留;其内部 onload/onerror 完成后清理。 + +旧实现首轮 7 项中 2 通过、5 失败。已补到 18 个有效 Node 用例,覆盖配置覆盖、失败重试、控件移除、重复清理、晚到编码、源切换、公开/内部 URL 所有权、空 Blob、构造和 DOM 写入重入。初始基线保留当时的旧裁剪规则断言;进一步核对生成工具后,裁剪回归改为验证正确格子,并用浏览器明确比较旧/新差异。 + +BASE-DOM-19 的证据来自生成工具 creatScreenshotDate 与真实编号 SVG:生成工具按 `(index % column, floor(index / column))` 排列。旧播放器在 index=column 时选到上一行末格,index=0 时写出双负号 CSS,浏览器保留之前的位置。候选修正这两类显示缺陷;不改参数、DOM、尺寸、缩放、预览边缘定位和 0/1 进度端点处理。 + +三浏览器缩略图 24 项通过;首次截图/缩略图合并执行 63 项中 Firefox 的重试夹具失败,其余 62 项通过。首次夹具用成功 200 返回错误图像,不能可靠表达临时网络失败;改成明确 no-store 的 503 后,同 URL 第二次请求正常图像在三浏览器通过,不增加等待、不为请求追加 cache-busting 参数。随后还补了缩放 Image 构造中销毁的保护,当前源码需再走整轮检查,最终结果以新的阶段证据为准。 + +BASE-LIFE-39/40/41 和 BASE-DOM-19 保持 open,等待任务最终安装产物验收。已将 thumbnails.test.js 接入 test:unit;没有依赖或锁文件变化。截图阶段 screenshot-partial.json 保留历史指纹,不能用来代表当前新增图片模块后的全量候选。 + +在该历史阶段,进度和源 URL 所有权尚待复核;后续实施和实测见下文。 + +## 截图与缩略图阶段的最终重跑 + +本阶段实际执行的当前源码检查:`yarn ci:check` 共 401 项(372 单元 + 4 工程 + 25 基线),生产 TS 205 个;公开声明与 HEAD 相比未改动。`yarn test:browser test/browser/thumbnails.spec.js test/browser/screenshot.spec.js` 在 Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6 一次完整通过 63 项,无重试/跳过/意外 pageerror。精确登记了旧截图工具栏每引擎一次受控拒绝;临时 503 是有意网络失败,不宣称控制台没有任何错误输出。 + +`baselines/capture-thumbnails-partial.json` 固定本阶段源码/测试/夹具/工具链指纹、报告哈希、测试 ID、浏览器版本、候选/发布代码指纹和早期 Firefox 夹具失败。实际候选渲染截图已检查:编号 99 预览在进度右端,符合最后一格与右边缘约束。阶段记录不替代最终安装产物验收,也不关闭 CORE-19。 + +## 进度、媒体 URL 和清晰度复核 + +progress/interactions.ts 现在按控件、源、交互动作检查有效性。几何读取和 setBar 回调后重新检查,防止 remove/destroy/切源/新点击重入后继续 seek;旧拖动在切源后停止,新按下可重新开始。position.ts 保留坐标钳制、live 事件和正常 setBar-before-seek 顺序。新增 10 项 progress Node 检查并接入 test:unit。 + +urlMix.ts 删除对传入旧媒体 URL 的无条件 revokeObjectURL:调用方或 adapter 创建的 URL 由创建方释放。真实 Node Blob fetch 与浏览器换源、销毁后的字节读取对比旧版错误和候选结果。截图、公开 loadImg 与内部 thumbnail/subtitle 的不同资源归属均有独立验证。 + +质量 selector 增补首个 default、空数组、引用和只写描述符边界。真实点击同时检查源、标签、暂停位置、速率与 customType 参数身份。WebKit 原生事件记录发现首次恢复 seek 接受位置后却落到近零。曾试验等待 seeked 后恢复 rate,以及延后至 canplay 再 seek,均不能单独解决;不能声称 rate 是已证实根因。显式第二次 seek 有效,因此拆出 source/restore-position.ts:等待原生 seek 完成、恢复速率一次、对超过 0.05 秒的偏差最多修正一次,尊重实际钳制目标和用户 seek,并在源失效时停止。第二次也失败时不无限循环,不伪造成功位置。 + +第一次修正实验还暴露 seeked 监听只消费一次导致 Promise 挂起;监听持续至操作结束后,WebKit 15 项通过。新增受控用例验证第二次 seeked 结算、最多一次修正、用户覆盖、钳制/时钟舍入、getter 重入、同步 seeked 重入只恢复一次。三引擎截图/缩略图/进度/质量/源专项最终源码运行 126 项通过;仍以最终安装产物检查作为任务完成门槛。 + +原生 Blob 探针同时发现本机 Windows WebKit 26.6 不支持所测 MP4/WebM Blob 样本(错误 4、宽度 0),独立于 ArtPlayer。该引擎仅在此场景证明 HTTP 播放、实际 Blob 赋值和字节所有权,附件标明 decodedBlob=false。BASE-ENV-01 / REL-03 / REVIEW-02 保留真实 Apple 设备验证;不将能力缺口写成通过。Chromium/Firefox 实际解码 Blob。具体矩阵见 environment-matrix.md。 + +## 最终打包前的兼容补查 + +run-ECwxyz 安装 UMD 1455 项已通过,legacy 验证期间进一步发现自动修正只识别 seek 事件,会漏掉合法的直接 art.currentTime 写入。补上 media/position-revision.ts,在当前时间 setter 接受合法输入时记录代次;等待期间的直接赋值(包括 metadata 前)和嵌套赋值优先于自动恢复,NaN 仍无操作。专门回归使用真实 currentTimeMix 门面验证两个时序,而不是只验证内部 helper。该补查更改了候选源码,run-ECwxyz 及其 UMD/legacy 结果仅保留为历史证据,不能作为最终发布候选,需重新 CI、打包和安装浏览器验证。 + +新增原生浏览器重入用例:初次补查在旧候选三个引擎均复现用户写入 4 后又被自动写回 2。代次修复后 Chromium/Firefox 到达 4;WebKit 一次仍结束在约 2,另一次原生 setter 诊断结束在 4。这个重入用例因此把应用契约明确为原生 currentTime setter 序列只有恢复位置和用户新位置两次,禁止第三次写回旧值;完整记录实际时钟/seeked/速率 setter,不把可变原生落点当作应用覆盖的证据,也不宣称任意 native seek 精确度。普通清晰度位置、速率和暂停状态仍由已有独立用例进行真实数值断言,未取消该验证。 + +采用最终 setter 契约重跑旧候选时,Chromium/Firefox 两项失败、WebKit 一项通过,说明旧缺陷触发依赖原生时序,不能声称 WebKit 每次都会复现。相同用例在新 tarball 的三个引擎均通过。早期数值失败、原生诊断和新旧 setter 契约报告全部保留,并由最终证据记录哈希与各次结果。 + +run-bmh0dN 首轮完整 UMD 为 1457 通过、1 失败:旧 hotkey 用例尚未按方向键,准备阶段的原生 seek=1 在 Windows WebKit 落到 1.29903,没有页面错误。用例改为直接从真实暂停位置按左右方向键,新增每次请求等于当前位置 ± SEEK_STEP、事件数量为二及真实时间分别增加/减小、seek 完成的断言;保留播放/暂停、音量和 Escape。没有改播放器、放宽原生 seek 容差或延长等待。此 fixture 变更需要最终完整浏览器重跑,原失败报告保留。 + +## 最终任务验收与交接 + +固定 Node 24.21.0 / Yarn 1.22.22。CI 421 项(392 单元、4 工程、25 基线)通过,207 个生产 TS 文件(核心 202 + chapter 5)严格检查通过。新增截图/缩略图类型夹具及现有五组消费者模式通过;公开 types 目录未改动。 + +正式构建后,run-bmh0dN 的实际 tarball 消费通过 27 项运行时和 5 组类型检查。安装后的 UMD、legacy 在 Chromium 153.0.8010.12、Firefox 155.0、WebKit 26.6 各完整通过 1458 项,其中各 129 项截图/缩略图/进度/质量/源专项;无重试、跳过或意外 pageerror。已知旧截图工具栏和旧续播拒绝按精确对象身份计入证据,不屏蔽未知错误。原生桌面 fullscreen、可用引擎 PiP 及其余核心回归继续通过。 + +[最终证据](../baselines/capture-progress-validation.json) 核对当前全部核心源码、包内文件、UMD/legacy/ESM、docs 副本、22 个语言产物、声明和第三方许可;记录测试指纹、报告哈希、原生 Blob 能力与质量事件。中间失败报告保留,不能冒充最终产物结果。 + +关闭 BASE-LIFE-36 至 44 和 BASE-DOM-19 共十项。BASE-ENV-01、兼容公共类型精确视图及真实设备/多轮发布复盘继续保留;第二次原生 seek 仍不准确时不作无限修正。新增三个单元文件并接入 test:unit,源/组件文件增补关联回归;没有新增依赖、锁文件或版本变化。 + +当前 214 项:55 完成、159 待办,下一项 CORE-20 收敛入口、初始化与剩余自有 JS。按任务独立本地 commit 交付,不推送、不发布。回退只撤销本任务源码、测试、文档/风险和构建生成产物,保留 CORE-18 及之前交付。 + +CORE-20 读取入口:src/index.js、player/index.js、player/optionInit.js、config/index.js、storage.js、utils/dom.js、utils/compatibility.js,以及 player 中 airplayMix/attrMix/cssVarMix/typeMix/themeMix/posterMix.js。当前共 13 个剩余自有 JS;libs/screenfull.js 属第三方来源文件,须按既有 vendor 记录处理,不能随手重写为 TS。先核对初始化顺序、静态接口和描述符,再收敛门面类型。 diff --git a/refactor/environment-matrix.md b/refactor/environment-matrix.md index 40aaaa363..8e9887096 100644 --- a/refactor/environment-matrix.md +++ b/refactor/environment-matrix.md @@ -55,6 +55,12 @@ Node10 是 TS 模块解析模式名,不代表支持 Node.js 10。现代 es2020 | artplayer-tool-thumbnail / 4.4.0 | 视频抽帧、下载图片/VTT、seek/错误/取消;本地 MP4 | BASE-DIST-01 的入口/声明问题待核实;Canvas/下载/移动待 | PKG-TOOL-THUMB-01/02/04/05/06 | | artplayer-vitepress / 1.1.0 | ENV-SITE;Monaco/vConsole、示例 CDN/声明、构建静态资源 | 本地站点构建已验;编辑器实际执行/移动 HTML/旧链接待,npm 意图待核实 | SITE-01/02/03/04/05/06、EX-01/02/03 | +## CORE-19 本机 Blob 媒体能力证据 + +2026-09-11,Windows 上 Playwright WebKit 26.6 的独立原生 video 探针,对本地 MP4 和 WebM 转成 Blob URL 后均返回 MEDIA_ERR_SRC_NOT_SUPPORTED(code 4),videoWidth=0;探针不经过 ArtPlayer。相同检查在 Chromium 153.0.8010.12、Firefox 155.0 可解码。精确样本哈希与引擎版本由 browser-evidence manifest 和 native-blob-capabilities 附件记录。 + +WebKit 仍验证真实 HTTP 播放、Blob URL 实际赋值、切源/销毁后的字节可读性,borrowed-url-evidence 明确 decodedBlob=false;这不能充当 Blob 视频解码通过。BASE-ENV-01 保留 open,REL-03/REVIEW-02 需在真实 Safari/Apple 设备复验样本、播放、seek、切源和资源归属,区分系统 codec 能力与候选回归。本机结论不外推全部 WebKit 或 Safari。 + ## 报告和发布判定 已有报告位置见上文及 baselines/;新验证将命令、源码 SHA/候选 tarball integrity、包/核心/SDK/浏览器/OS/设备版本、样本哈希与 codec、能力检测、通过/失败/缺环境、trace 位置和限制写入对应 changes/任务记录,CI 大型 trace/录像留 artifact。缺环境报告写清获得何种设备/服务后执行哪个场景,不能虚构负责人姓名或设备版本。 diff --git a/refactor/plan.md b/refactor/plan.md index 14e521094..8ca505ff1 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -4,7 +4,7 @@ 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。 -状态:todo 160 / doing 0 / blocked 0 / done 54 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 +状态:todo 159 / doing 0 / blocked 0 / done 55 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 @@ -122,7 +122,7 @@ | CORE-16 | artplayer
迁移全屏、PiP、mini 与尺寸模式 | CORE-11, CORE-12 | 显示模式服务和原公开属性门面 | 模式互斥/恢复位置、手势权限、移动方向和退出失败通过 | H | done | | CORE-17 | artplayer
迁移键盘、手势、焦点和全局事件 | CORE-13, CORE-16 | events/hotkey 的明确 document 与资源归属 | 跨 document 重绑、触摸/键盘、快捷键及销毁无重复响应;修复 BASE-PERF-01 pending resize debounce 销毁后执行,并验证正常 resize 不变 | H | done | | CORE-18 | artplayer
迁移内置插件和提示模块 | CORE-14, CORE-16, CORE-17 | autoPlayback/autoOrientation/fastForward/lock/miniProgressBar 及 info/notice/loading/mask | 默认启用条件、storage 格式、定时器/动画清理通过;结合 BASE-PERF-01 防止销毁后重新安排 notice timer;接续 BASE-TYPE-07 的 notice.show boolean getter 与历史读类型冲突 | M | done | -| CORE-19 | artplayer
整理进度、质量、缩略图和截图 | CORE-10, CORE-13, CORE-16 | 相关 player/control 功能与纯计算分离 | 截图跨域失败、缩略图布局、quality/进度边界保持 | M | todo | +| CORE-19 | artplayer
整理进度、质量、缩略图和截图 | CORE-10, CORE-13, CORE-16 | 相关 player/control 功能与纯计算分离 | 截图跨域失败、缩略图布局、quality/进度边界保持 | M | done | | CORE-20 | artplayer
收敛核心入口与依赖方向 | CORE-14, CORE-15, CORE-18, CORE-19 | Artplayer 门面、初始化依赖与最终目录 | 所有核心自有源码迁移,公开描述符/静态接口/事件差分通过 | H | todo | | CORE-21 | artplayer
生成核心声明并校验包内容 | CORE-20, ENG-07 | 由 TS 生成的既有入口声明与三种发布产物 | 内部类型不泄漏,旧 JS/TS 消费者与 i18n 通过;逐项完成 CORE-07 留下的 BASE-TYPE-04/05/07 声明方案,旧合法消费者与实际返回分别留证;不能以虚假的交叉返回类型或改变运行时来掩盖冲突,未决项阻止核心声明出口;处理 CORE-10 / BASE-TYPE-08 的 setter-only 属性虚构 getter 声明,并复核 PlaybackControls 精确视图与旧 toggle 声明共存策略 | H | todo | | CORE-23 | artplayer
检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | todo | @@ -453,6 +453,7 @@ - CORE-16: [记录](changes/2026-09-11-CORE-16-display.md) [记录](baselines/display-validation.json) - CORE-17: [记录](changes/2026-09-11-CORE-17-input.md) [记录](baselines/input-validation.json) - CORE-18: [记录](changes/2026-09-11-CORE-18-builtins-prompts.md) [记录](baselines/builtins-prompts-validation.json) +- CORE-19: [记录](changes/2026-09-11-CORE-19-capture-thumbnails.md) [记录](baselines/capture-progress-validation.json) - PKG-CHAPTER-01: [记录](changes/2026-09-10-PKG-CHAPTER-01-contract.md) [记录](baselines/chapter-contract.md) - PKG-CHAPTER-02: [记录](changes/2026-09-10-PKG-CHAPTER-02-tests.md) [记录](baselines/chapter-validation.json) - PKG-CHAPTER-03: [记录](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md) [记录](baselines/chapter-migration-validation.json) diff --git a/refactor/progress.md b/refactor/progress.md index ae07d9166..240b85048 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,13 @@ # 进度与证据 +## 当前实施:CORE-19 进度、质量、截图与缩略图完成 + +截图和缩略图门面迁移 TS,拆清图像捕获、加载与布局。进度交互防止回调重入/跨源拖动继续 seek;质量切换对原生首次 seek 偏差最多修正一次,保持用户覆盖、取消与 Promise 结算。媒体/公开图片 URL 由调用方拥有,内部资源在配置、控件或实例结束时释放。保留公开 API、类型、正常事件顺序和 DOM/CSS;整列与首格缩略图裁剪是明确记录的显示修复。 + +CI 421 项、207 个生产 TS 严格检查、真实 tarball 27 项运行时及五组类型通过;安装 UMD/legacy 各 1458 项三浏览器全量通过,各含 129 项本任务和关联源专项。源码、包文件、三个分发格式、语言、docs 副本和许可指纹一致。见 [实施记录](changes/2026-09-11-CORE-19-capture-thumbnails.md) 和 [最终证据](baselines/capture-progress-validation.json)。 + +关闭十项已复现差异。BASE-ENV-01 保留 Windows WebKit 本机 Blob 解码限制,真实 Apple 设备仍交 REL-03/REVIEW-02;公共类型精确视图交 CORE-21。当前 214 项:55 完成、159 待办,下一项 CORE-20。本任务独立本地提交,无推送或发布。 + ## 当前实施:CORE-18 内置插件与提示模块完成 notice、autoPlayback、fastForward、lock、miniProgressBar、info、loading、mask 已迁移 TS,拆清记录、提示、长按与轮询归属;autoOrientation 组合复验通过。修复重复响应、陈旧回调和清理,同时保持公开结果、存储格式、DOM 与 destroy 观察顺序。 diff --git a/refactor/risk-table.md b/refactor/risk-table.md index dd0581495..09893b5a5 100644 --- a/refactor/risk-table.md +++ b/refactor/risk-table.md @@ -100,3 +100,14 @@ | BASE-LIFE-33 | resolved / 已复现 | Auto-playback restarts retain obsolete resume clicks, subscriptions and timers | CORE-18 | | BASE-LIFE-34 | resolved / 已复现 | Lock icon and miniature progress subscriptions outlive their UI or player | CORE-18 | | BASE-LIFE-35 | resolved / 已复现 | Info repeated initialization retains polling and close callbacks; destroyed reads continue writing | CORE-18 | +| BASE-LIFE-36 | resolved / 已复现 | Screenshot Blob callback failures escape and leave public promises pending | CORE-19 | +| BASE-LIFE-37 | resolved / 已复现 | Screenshot completion can download or emit after destruction or source replacement | CORE-19 | +| BASE-LIFE-38 | resolved / 已复现 | Screenshot toolbar leaves internal capture failures as unhandled rejections | CORE-19 | +| BASE-LIFE-39 | resolved / 已复现 | Thumbnail image completions can overwrite newer configuration or hover state and outlive controls | CORE-19 | +| BASE-LIFE-40 | resolved / 已复现 | Image load failures leave thumbnail loading frozen and canvas callback failures escape public loadImg promises | CORE-19 | +| BASE-LIFE-41 | resolved / 已复现 | Scaled thumbnail Blob URLs survive replacement, control removal and destruction | CORE-19 | +| BASE-DOM-19 | resolved / 已复现 | Thumbnail row boundaries and first-cell return do not match the generated zero-based sprite grid | CORE-19 | +| BASE-LIFE-42 | resolved / 已复现 | Progress callbacks and active drags can seek an obsolete source or removed control | CORE-19 | +| BASE-LIFE-43 | resolved / 已复现 | Replacing a media source revokes a caller-owned Blob URL still in use | CORE-19 | +| BASE-LIFE-44 | resolved / 已复现 | Native quality restoration can settle at a different position after its first seek | CORE-19 | +| BASE-ENV-01 | open / 已复现 | Windows WebKit native Blob video samples lack decoding support; Apple-device validation remains outstanding | REL-03, REVIEW-02 | diff --git a/refactor/risks.json b/refactor/risks.json index c4f3bf9bc..7b8187b14 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -1998,6 +1998,246 @@ "test/browser/prompt-components.spec.js" ], "resolutionRationale": "Owned prompt/input resources prevent stale callbacks and survive reentry/removal/destruction; normal public API and event ordering are retained. Final installed UMD and legacy each pass 1350 browser cases, including 207 CORE-18 cases, plus actual tarball runtime/type consumers. Physical mobile and release-review gates remain outstanding for the overall refactor." + }, + { + "id": "BASE-LIFE-36", + "title": "Screenshot Blob callback failures escape and leave public promises pending", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/screenshot.test.js" + ], + "compatibleResolution": "Preserve legal capture results and error propagation, while fixing asynchronous failure and stale lifecycle effects.", + "closureCriteria": "Candidate unit, real-browser and installed-package regressions plus compatibility review pass.", + "workspaceState": "Before migration, null Blob and thrown createObjectURL escape the asynchronous callback. Candidate Node regression passes; final installed-package evidence remains outstanding. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-37", + "title": "Screenshot completion can download or emit after destruction or source replacement", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/screenshot.test.js", + "test/browser/screenshot.spec.js" + ], + "compatibleResolution": "Preserve legal capture results and error propagation, while fixing asynchronous failure and stale lifecycle effects.", + "closureCriteria": "Candidate unit, real-browser and installed-package regressions plus compatibility review pass.", + "workspaceState": "Before migration, screenshot await resumes download and event effects after disposal or source replacement. Candidate guards preserve the captured string result while suppressing stale effects. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-38", + "title": "Screenshot toolbar leaves internal capture failures as unhandled rejections", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/browser/screenshot.spec.js", + "refactor/baselines/screenshot-partial.json" + ], + "compatibleResolution": "Consume the internal toolbar Promise after the existing notice, while preserving rejection of every public capture method.", + "closureCriteria": "Exact historical Error identity is reproduced and candidate toolbar, cross-origin and installed-package regressions pass.", + "workspaceState": "Published toolbar produces one exactly identified rejection per engine; source candidate produces none. Real cross-origin toolbar validation passes. Installed-package exit remains outstanding. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-39", + "title": "Thumbnail image completions can overwrite newer configuration or hover state and outlive controls", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/thumbnails.test.js", + "test/browser/thumbnails.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve public configuration identity, dimensions, layout positioning and public URL ownership; repair documented crop and lifecycle defects.", + "closureCriteria": "Candidate type, unit, actual image browser and installed-package validation pass with explicit historical differences.", + "workspaceState": "Five of seven initial Node cases fail before migration. Candidate generation/source/control ownership guards and latest-hover rendering now pass focused Node and real-image browser checks. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-40", + "title": "Image load failures leave thumbnail loading frozen and canvas callback failures escape public loadImg promises", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/thumbnails.test.js", + "test/browser/thumbnails.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve public configuration identity, dimensions, layout positioning and public URL ownership; repair documented crop and lifecycle defects.", + "closureCriteria": "Candidate type, unit, actual image browser and installed-package validation pass with explicit historical differences.", + "workspaceState": "Owned image requests now settle on cancellation or failure and release handlers; the public utility retains HTMLImageElement results and callback errors reject. Transient no-store HTTP failure can retry in all three engines. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-41", + "title": "Scaled thumbnail Blob URLs survive replacement, control removal and destruction", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/thumbnails.test.js", + "test/browser/thumbnails.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve public configuration identity, dimensions, layout positioning and public URL ownership; repair documented crop and lifecycle defects.", + "closureCriteria": "Candidate type, unit, actual image browser and installed-package validation pass with explicit historical differences.", + "workspaceState": "Candidate internal URLs belong to the thumbnail configuration/control. Public loadImg and screenshot Blob URL ownership stays with callers. Final installed-package evidence remains outstanding. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-DOM-19", + "title": "Thumbnail row boundaries and first-cell return do not match the generated zero-based sprite grid", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/thumbnails.test.js", + "test/browser/thumbnails.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve public configuration identity, dimensions, layout positioning and public URL ownership; repair documented crop and lifecycle defects.", + "closureCriteria": "Candidate type, unit, actual image browser and installed-package validation pass with explicit historical differences.", + "workspaceState": "artplayer-tool-thumbnail uses index modulo column and floor(index / column). Published renderer selects the previous row last cell at exact multiples and writes invalid double-negative CSS for the first cell. Corrected candidate crop is compared against a numbered real SVG grid. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-42", + "title": "Progress callbacks and active drags can seek an obsolete source or removed control", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/source.test.js", + "test/progress.test.js", + "test/browser/progress-quality.spec.js", + "test/browser/source.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve legal progress and quality APIs, callback order, source results and caller ownership; stop obsolete work and bound native position correction.", + "closureCriteria": "Unit, strict types and installed-package browser matrices pass with explicit baseline differences and native evidence.", + "workspaceState": "Published real progress interactions continue seeking after setBar reentry; candidate guards entry, source and action identity and ends a drag on source replacement. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-43", + "title": "Replacing a media source revokes a caller-owned Blob URL still in use", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/source.test.js", + "test/progress.test.js", + "test/browser/progress-quality.spec.js", + "test/browser/source.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve legal progress and quality APIs, callback order, source results and caller ownership; stop obsolete work and bound native position correction.", + "closureCriteria": "Unit, strict types and installed-package browser matrices pass with explicit baseline differences and native evidence.", + "workspaceState": "Published URL setter revokes the supplied old URL. Node fetch and three-browser byte ownership checks reproduce the consumer failure; candidate preserves caller ownership after switching and destruction. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-LIFE-44", + "title": "Native quality restoration can settle at a different position after its first seek", + "confirmation": "reproduced", + "status": "resolved", + "owners": [ + "CORE-19" + ], + "evidence": [ + "test/source.test.js", + "test/progress.test.js", + "test/browser/progress-quality.spec.js", + "test/browser/source.spec.js", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "compatibleResolution": "Preserve legal progress and quality APIs, callback order, source results and caller ownership; stop obsolete work and bound native position correction.", + "closureCriteria": "Unit, strict types and installed-package browser matrices pass with explicit baseline differences and native evidence.", + "workspaceState": "Windows WebKit native event traces show the first seek reporting the accepted target then completing near zero. Waiting or deferring alone is insufficient. Candidate waits for native completion and performs at most one correction; a persistent seeked listener prevents a pending Promise after that correction. Final CORE-19 CI and installed-package acceptance passed; see resolution evidence.", + "resolutionEvidence": [ + "refactor/baselines/capture-progress-validation.json", + "refactor/changes/2026-09-11-CORE-19-capture-thumbnails.md" + ], + "resolutionRationale": "Core source, strict types, unit cases, real images/media, actual installed tarball and full UMD/legacy matrices pass. Explicit historical defect differences are documented; no API/type removal or environment waiver." + }, + { + "id": "BASE-ENV-01", + "title": "Windows WebKit native Blob video samples lack decoding support; Apple-device validation remains outstanding", + "confirmation": "reproduced", + "status": "open", + "owners": [ + "REL-03", + "REVIEW-02" + ], + "evidence": [ + "test/browser/progress-quality.spec.js", + "refactor/environment-matrix.md" + ], + "compatibleResolution": "Keep byte ownership and real HTTP playback evidence distinct from native Blob decoding; do not infer Safari or Apple-device support from Windows WebKit.", + "closureCriteria": "Record actual Safari and Apple device versions and native sample capabilities, then compare published/candidate load, playback, seek, source replacement and Blob ownership.", + "workspaceState": "Independent video probes on Windows WebKit 26.6 return error 4 and width zero for both local MP4 and WebM Blob samples. Chromium and Firefox decode the tested Blob sample. WebKit ownership tests explicitly report decodedBlob=false.", + "resolutionEvidence": [] } ] } diff --git a/refactor/tasks.json b/refactor/tasks.json index 7d028bbc6..3d852045d 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -1111,11 +1111,14 @@ "CORE-13", "CORE-16" ], - "status": "todo", + "status": "done", "risk": "M", "deliverable": "相关 player/control 功能与纯计算分离", "acceptance": "截图跨域失败、缩略图布局、quality/进度边界保持", - "evidence": [] + "evidence": [ + "changes/2026-09-11-CORE-19-capture-thumbnails.md", + "baselines/capture-progress-validation.json" + ] }, { "id": "CORE-20", diff --git a/test/browser/hotkey.spec.js b/test/browser/hotkey.spec.js index 0141a3a2e..327247656 100644 --- a/test/browser/hotkey.spec.js +++ b/test/browser/hotkey.spec.js @@ -57,22 +57,26 @@ test('candidate: native keyboard play/pause, seek, volume and web-fullscreen Esc await page.evaluate(() => { window.art.isFocus = true window.nativeHotkeys = [] + window.nativeHotkeySeeks = [] window.art.on('hotkey', event => window.nativeHotkeys.push(event.code)) + window.art.on('seek', (time, requested) => window.nativeHotkeySeeks.push(requested)) }) await page.keyboard.press('Space') await expect.poll(() => page.evaluate(() => window.art.playing && window.art.currentTime > 0.1)).toBe(true) await page.keyboard.press('Space') await expect.poll(() => page.evaluate(() => window.art.template.$video.paused && !window.art.template.$video.seeking)).toBe(true) - await page.evaluate(() => { - window.art.currentTime = 1 - }) - await expect.poll(() => page.evaluate(() => !window.art.template.$video.seeking && Math.abs(window.art.currentTime - 1) < 0.1)).toBe(true) + const start = await page.evaluate(() => ({ time: window.art.currentTime, step: window.Artplayer.SEEK_STEP })) await page.keyboard.press('ArrowRight') expect(await page.evaluate(() => window.nativeHotkeys.at(-1))).toBe('ArrowRight') - await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(5) + expect(await page.evaluate(() => window.nativeHotkeySeeks.at(-1))).toBeCloseTo(start.time + start.step, 1) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(start.time) await expect.poll(() => page.evaluate(() => window.art.template.$video.seeking)).toBe(false) + const forward = await page.evaluate(() => window.art.currentTime) await page.keyboard.press('ArrowLeft') - await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeLessThan(2) + expect(await page.evaluate(() => window.nativeHotkeySeeks.at(-1))).toBeCloseTo(forward - start.step, 1) + expect(await page.evaluate(() => window.nativeHotkeySeeks.length)).toBe(2) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeLessThan(forward) + await expect.poll(() => page.evaluate(() => window.art.template.$video.seeking)).toBe(false) const volume = await page.evaluate(() => { window.art.volume = 0.5 return window.art.volume diff --git a/test/browser/media/thumbnail-grid.svg b/test/browser/media/thumbnail-grid.svg new file mode 100644 index 000000000..440c05ffe --- /dev/null +++ b/test/browser/media/thumbnail-grid.svg @@ -0,0 +1,202 @@ + + + 0 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 + + 32 + + 33 + + 34 + + 35 + + 36 + + 37 + + 38 + + 39 + + 40 + + 41 + + 42 + + 43 + + 44 + + 45 + + 46 + + 47 + + 48 + + 49 + + 50 + + 51 + + 52 + + 53 + + 54 + + 55 + + 56 + + 57 + + 58 + + 59 + + 60 + + 61 + + 62 + + 63 + + 64 + + 65 + + 66 + + 67 + + 68 + + 69 + + 70 + + 71 + + 72 + + 73 + + 74 + + 75 + + 76 + + 77 + + 78 + + 79 + + 80 + + 81 + + 82 + + 83 + + 84 + + 85 + + 86 + + 87 + + 88 + + 89 + + 90 + + 91 + + 92 + + 93 + + 94 + + 95 + + 96 + + 97 + + 98 + + 99 + diff --git a/test/browser/progress-quality.spec.js b/test/browser/progress-quality.spec.js new file mode 100644 index 000000000..495366948 --- /dev/null +++ b/test/browser/progress-quality.spec.js @@ -0,0 +1,234 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(() => window.createPlayer('/test/pattern.mp4')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('#play').click() + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1) + await page.locator('#pause').click() + await expect.poll(() => page.evaluate(() => window.art.video.paused && !window.art.video.seeking)).toBe(true) +} + +for (const core of ['published', 'candidate']) { + for (const mode of ['remove', 'destroy', 'source']) { + test(`${core}: progress click reentry through ${mode} cannot continue an obsolete seek`, async ({ page }) => { + await setup(page, core) + const result = await page.evaluate((mode) => { + const art = window.art + let seeks = 0 + let bars = 0 + art.on('seek', () => seeks++) + art.on('setBar', (type) => { + if (type !== 'played' || bars++) + return + if (mode === 'remove') + art.controls.remove('progress') + else if (mode === 'destroy') + art.destroy() + else + art.url = '/test/pattern.mp4?progress=reentrant' + }) + const progress = art.template.$progress + progress.dispatchEvent(new MouseEvent('click', { clientX: progress.getBoundingClientRect().left + progress.clientWidth / 2 })) + const result = { seeks, bars } + art.destroy() + return result + }, mode) + expect(result).toEqual({ seeks: core === 'published' ? 1 : 0, bars: 1 }) + }) + } + + test(`${core}: real progress click keeps setBar before seek and clamps the edges`, async ({ page }) => { + await setup(page, core) + const rect = await page.evaluate(() => { + const art = window.art + window.progressOrder = [] + art.on('setBar', (type, percent) => { + if (type === 'played') + window.progressOrder.push(['setBar', percent]) + }) + art.on('seek', () => window.progressOrder.push(['seek'])) + const rect = art.template.$progress.getBoundingClientRect() + return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 } + }) + await page.mouse.click(rect.x, rect.y) + await expect.poll(() => page.evaluate(() => window.art.video.seeking)).toBe(false) + expect(await page.evaluate(() => window.art.currentTime / window.art.duration)).toBeCloseTo(0.5, 1) + const result = await page.evaluate(() => { + const art = window.art + const firstSeek = window.progressOrder.findIndex(item => item[0] === 'seek') + const previous = window.progressOrder[firstSeek - 1] + const progress = art.template.$progress + progress.dispatchEvent(new MouseEvent('click', { clientX: progress.getBoundingClientRect().left - 100 })) + const start = art.currentTime + progress.dispatchEvent(new MouseEvent('click', { clientX: progress.getBoundingClientRect().right + 100 })) + const end = art.currentTime + const duration = art.duration + art.destroy() + return { previous, start, end, duration } + }) + expect(result.previous[0]).toBe('setBar') + expect(result.previous[1]).toBeCloseTo(0.5, 1) + expect(result.start).toBe(0) + expect(result.end).toBeCloseTo(result.duration, 1) + }) + + test(`${core}: a progress drag ends when its source is replaced and can restart on the new source`, async ({ page }) => { + await setup(page, core) + const stale = await page.evaluate(() => { + const art = window.art + window.dragSeeks = 0 + art.on('seek', () => window.dragSeeks++) + const progress = art.template.$progress + progress.dispatchEvent(new MouseEvent('mousedown', { button: 0 })) + art.url = '/test/pattern.mp4?progress=new-source' + art.emit('document:mousemove', new MouseEvent('mousemove', { clientX: progress.getBoundingClientRect().left + progress.clientWidth / 2 })) + return window.dragSeeks + }) + expect(stale).toBe(core === 'published' ? 1 : 0) + await expect.poll(() => page.evaluate(() => window.art.video.readyState >= 2)).toBe(true) + expect(await page.evaluate(() => { + const art = window.art + const progress = art.template.$progress + progress.dispatchEvent(new MouseEvent('mousedown', { button: 0 })) + art.emit('document:mousemove', new MouseEvent('mousemove', { clientX: progress.getBoundingClientRect().left + progress.clientWidth / 2 })) + art.emit('document:mouseup', new MouseEvent('mouseup')) + const seeks = window.dragSeeks + art.destroy() + return seeks + })).toBe(stale + 1) + }) + + test(`${core}: a caller-owned media Blob URL remains readable after switching and destroying the player`, async ({ page, browserName }, testInfo) => { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(async () => { + window.blobCapabilities = [] + let blob + let fallback + for (const extension of ['mp4', 'webm']) { + const candidate = await (await fetch(`/test/pattern.${extension}`)).blob() + fallback ||= candidate + const url = URL.createObjectURL(candidate) + const video = document.createElement('video') + const capability = await new Promise((resolve) => { + video.onloadedmetadata = () => resolve({ extension, width: video.videoWidth, error: 0 }) + video.onerror = () => resolve({ extension, width: video.videoWidth, error: video.error.code }) + video.src = url + video.load() + }) + window.blobCapabilities.push(capability) + video.onloadedmetadata = null + video.onerror = null + video.removeAttribute('src') + video.load() + URL.revokeObjectURL(url) + if (!capability.error) { + blob = candidate + break + } + } + window.blobPlayable = !!blob + blob ||= fallback + window.sharedBlobSize = blob.size + window.sharedBlobUrl = URL.createObjectURL(blob) + window.borrowedRevocations = [] + const original = URL.revokeObjectURL + URL.revokeObjectURL = function (url) { + window.borrowedRevocations.push(url) + return original.call(this, url) + } + window.createPlayer(window.blobPlayable ? window.sharedBlobUrl : '/test/pattern.mp4') + }) + const capabilities = await page.evaluate(() => window.blobCapabilities) + await testInfo.attach('native-blob-capabilities', { contentType: 'application/json', body: JSON.stringify(capabilities) }) + if (!capabilities.some(item => item.error === 0)) { + expect(browserName).toBe('webkit') + expect(capabilities).toEqual([{ extension: 'mp4', width: 0, error: 4 }, { extension: 'webm', width: 0, error: 4 }]) + } + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + const result = await page.evaluate(async () => { + const art = window.art + // The Windows WebKit runtime cannot decode either Blob fixture natively. + // Still exercise actual URL assignment/replacement and byte ownership there. + if (!window.blobPlayable) + art.url = window.sharedBlobUrl + const assigned = art.video.src === window.sharedBlobUrl + await art.switchUrl('/test/pattern.mp4?borrowed=replaced') + const read = async () => { + try { + return (await (await fetch(window.sharedBlobUrl)).blob()).size + } + catch (error) { + return error.name + } + } + const afterSwitch = await read() + art.destroy() + const afterDestroy = await read() + const revoked = window.borrowedRevocations.filter(url => url === window.sharedBlobUrl).length + URL.revokeObjectURL(window.sharedBlobUrl) + return { afterSwitch, afterDestroy, revoked, size: window.sharedBlobSize, assigned, decodedBlob: window.blobPlayable } + }) + expect(result.size).toBeGreaterThan(100) + expect(result.assigned).toBe(true) + await testInfo.attach('borrowed-url-evidence', { contentType: 'application/json', body: JSON.stringify(result) }) + expect(result.revoked).toBe(core === 'published' ? 1 : 0) + expect(result.afterSwitch).toBe(core === 'published' ? 'TypeError' : result.size) + expect(result.afterDestroy).toBe(core === 'published' ? 'TypeError' : result.size) + }) + + test(`${core}: quality selectors retain default labels, source position and empty-array behavior`, async ({ page, browserName }, testInfo) => { + await setup(page, core) + await page.evaluate(() => { + const art = window.art + window.qualityNativeEvents = [] + for (const key of ['currentTime', 'playbackRate', 'src']) { + const descriptor = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, key) + Object.defineProperty(art.video, key, { + configurable: true, + get() { return descriptor.get.call(this) }, + set(value) { + window.qualityNativeEvents.push({ key, value, time: this.currentTime, seeking: this.seeking, source: this.currentSrc }) + descriptor.set.call(this, value) + }, + }) + } + for (const event of ['loadedmetadata', 'seeking', 'seeked', 'canplay', 'ratechange', 'pause', 'playing']) + art.video.addEventListener(event, () => window.qualityNativeEvents.push({ event, time: art.currentTime, seeking: art.video.seeking, source: art.video.currentSrc })) + art.playbackRate = 1.5 + art.currentTime = 2 + window.qualityRestarts = [] + art.on('restart', url => window.qualityRestarts.push(url)) + window.qualityOptions = [ + { html: 'Quality A', url: '/test/pattern.mp4?quality=A' }, + { html: 'Quality B', url: '/test/pattern.mp4?quality=B', default: true }, + ] + art.quality = window.qualityOptions + }) + await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - 2) < 0.05 && !window.art.video.seeking)).toBe(true) + await expect(page.locator('.art-control-quality .art-selector-value')).toHaveText('Quality B') + await page.locator('.art-control-quality').hover() + await page.locator('.art-control-quality .art-selector-item').filter({ hasText: 'Quality A' }).click() + await expect.poll(() => page.evaluate(() => window.art.url.includes('quality=A'))).toBe(true) + await expect.poll(() => page.evaluate(() => window.qualityRestarts)).toEqual(['/test/pattern.mp4?quality=A']) + await expect.poll(() => page.evaluate(() => window.art.video.readyState >= 3 && !window.art.video.seeking)).toBe(true) + await expect(page.locator('.art-control-quality .art-selector-value')).toHaveText('Quality A') + await testInfo.attach('quality-native-events', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => window.qualityNativeEvents)) }) + const restoredTime = await page.evaluate(() => window.art.currentTime) + if (core === 'published' && browserName === 'webkit') + expect(restoredTime).toBeLessThan(0.05) + else + expect(restoredTime).toBeCloseTo(2, 1) + expect(await page.evaluate(() => window.art.playbackRate)).toBe(1.5) + expect(await page.evaluate(() => window.qualityOptions.map(item => !!item.default))).toEqual([true, false]) + const empty = await page.evaluate(() => { + const art = window.art + art.quality = [] + const result = { text: art.controls.quality.textContent, read: art.quality, hasGetter: !!Object.getOwnPropertyDescriptor(art, 'quality').get } + art.destroy() + return result + }) + expect(empty).toEqual({ text: '', read: undefined, hasGetter: false }) + }) +} diff --git a/test/browser/screenshot.spec.js b/test/browser/screenshot.spec.js new file mode 100644 index 000000000..39caf8ba4 --- /dev/null +++ b/test/browser/screenshot.spec.js @@ -0,0 +1,214 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core, crossOrigin = false, control = false) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(({ crossOrigin, control }) => { + const url = new URL('/test/pattern.mp4', location.href) + if (crossOrigin) + url.hostname = 'localhost' + window.art = new window.Artplayer({ container: '.player', url: url.href, muted: true, screenshot: control }) + }, { crossOrigin, control }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.evaluate(() => window.art.play()) + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1) + await page.evaluate(() => window.art.pause()) +} + +for (const core of ['published', 'candidate']) { + test(`${core}: captures decoded PNG pixels and consumer-owned Blob URLs`, async ({ page }) => { + await setup(page, core) + const result = await page.evaluate(async () => { + const art = window.art + const data = await art.getDataURL() + const url = await art.getBlobUrl() + const image = new Image() + image.src = data + await image.decode() + const canvas = document.createElement('canvas') + canvas.width = image.width + canvas.height = image.height + const context = canvas.getContext('2d') + context.drawImage(image, 0, 0) + const pixels = context.getImageData(0, 0, image.width, image.height).data + const colors = new Set() + for (let index = 0; index < pixels.length; index += 4) + colors.add(`${pixels[index]},${pixels[index + 1]},${pixels[index + 2]}`) + const expected = [art.video.videoWidth, art.video.videoHeight] + const descriptors = ['getDataURL', 'getBlobUrl', 'screenshot'].map((name) => { + const d = Object.getOwnPropertyDescriptor(art, name) + return [d.writable, d.configurable, d.enumerable] + }) + art.destroy() + const blob = await (await fetch(url)).blob() + URL.revokeObjectURL(url) + return { png: data.startsWith('data:image/png;base64,'), dimensions: [image.width, image.height], expected, colors: colors.size, blobType: blob.type, blobSize: blob.size, descriptors } + }) + expect(result.png).toBe(true) + expect(result.dimensions).toEqual(result.expected) + expect(result.dimensions[0]).toBeGreaterThan(0) + expect(result.colors).toBeGreaterThan(10) + expect(result.blobType).toBe('image/png') + expect(result.blobSize).toBeGreaterThan(100) + expect(result.descriptors).toEqual(Array.from({ length: 3 }, () => [false, false, false])) + }) + + test(`${core}: screenshot preserves download filename, event data and Promise result`, async ({ page }) => { + await setup(page, core) + const downloadPromise = page.waitForEvent('download') + const result = await page.evaluate(async () => { + const art = window.art + const events = [] + art.on('screenshot', value => events.push(value)) + const screenshot = art.screenshot + const value = await screenshot('chosen.png') + art.destroy() + return { count: events.length, same: events[0] === value, png: value.startsWith('data:image/png;base64,') } + }) + const download = await downloadPromise + expect(download.suggestedFilename()).toBe('chosen.png.png') + expect(result).toEqual({ count: 1, same: true, png: true }) + await download.delete() + }) + + test(`${core}: actual cross-origin video rejects capture with SecurityError and notice`, async ({ page }) => { + await setup(page, core, true) + const result = await page.evaluate(async () => { + const art = window.art + const errors = [] + for (const name of ['getDataURL', 'getBlobUrl', 'screenshot']) { + try { + await art[name]() + errors.push('resolved') + } + catch (error) { + errors.push(error.name) + } + } + const result = { errors, notice: art.notice.show, text: art.template.$noticeInner.textContent.length } + art.destroy() + return result + }) + expect(result.errors).toEqual(['SecurityError', 'SecurityError', 'SecurityError']) + expect(result.notice).toBe(true) + expect(result.text).toBeGreaterThan(0) + }) + + test(`${core}: source replacement does not download a stale captured frame`, async ({ page }) => { + await setup(page, core) + const result = await page.evaluate(async () => { + const art = window.art + let events = 0 + let downloads = 0 + const original = HTMLAnchorElement.prototype.click + HTMLAnchorElement.prototype.click = () => { + downloads++ + } + art.on('screenshot', () => { + events++ + }) + try { + const promise = art.screenshot() + art.url = '/test/pattern.mp4?replacement=1' + const result = { png: (await promise).startsWith('data:image/png;base64,'), events, downloads } + art.destroy() + return result + } + finally { + HTMLAnchorElement.prototype.click = original + } + }) + const oldEffects = core === 'published' ? 1 : 0 + expect(result).toEqual({ png: true, events: oldEffects, downloads: oldEffects }) + }) + + test(`${core}: screenshot toolbar rejection has exact historical error accounting`, async ({ page }, testInfo) => { + await setup(page, core, false, true) + await page.evaluate((core) => { + window.captureFailures = [] + const failure = new Error('controlled screenshot draw failure') + const original = HTMLCanvasElement.prototype.toDataURL + window.restoreCapture = () => { + HTMLCanvasElement.prototype.toDataURL = original + } + HTMLCanvasElement.prototype.toDataURL = () => { + throw failure + } + if (core === 'published') { + window.addEventListener('unhandledrejection', (event) => { + if (event.reason === failure) { + window.captureFailures.push(event.reason.message) + event.preventDefault() + } + }) + } + window.art.notice.show = false + }, core) + await page.locator('.art-control-screenshot').click() + await expect.poll(() => page.evaluate(() => window.art.template.$noticeInner.textContent)).toBe('controlled screenshot draw failure') + if (core === 'published') + await expect.poll(() => page.evaluate(() => window.captureFailures.length)).toBe(1) + const known = await page.evaluate(() => { + window.restoreCapture() + window.art.destroy() + return window.captureFailures + }) + expect(known).toEqual(core === 'published' ? ['controlled screenshot draw failure'] : []) + await testInfo.attach('known-screenshot-rejections', { contentType: 'application/json', body: JSON.stringify(known) }) + }) +} + +test('candidate: null toBlob callback rejects and reports without a page error', async ({ page }) => { + await setup(page, 'candidate') + expect(await page.evaluate(async () => { + const prototype = HTMLCanvasElement.prototype + const original = prototype.toBlob + prototype.toBlob = function (callback) { + queueMicrotask(() => callback(null)) + } + try { + await window.art.getBlobUrl() + return 'resolved' + } + catch (error) { + return error.message + } + finally { + prototype.toBlob = original + window.art.destroy() + } + })).toBe('Unable to encode screenshot blob') +}) + +test('candidate: destroy during screenshot await suppresses the queued download and event', async ({ page }) => { + await setup(page, 'candidate') + expect(await page.evaluate(async () => { + const art = window.art + let events = 0 + let downloads = 0 + const original = HTMLAnchorElement.prototype.click + HTMLAnchorElement.prototype.click = () => { + downloads++ + } + art.on('screenshot', () => { + events++ + }) + try { + const promise = art.screenshot() + art.destroy() + return { png: (await promise).startsWith('data:image/png;base64,'), events, downloads } + } + finally { + HTMLAnchorElement.prototype.click = original + } + })).toEqual({ png: true, events: 0, downloads: 0 }) +}) + +test('candidate: cross-origin screenshot toolbar handles its internal rejected Promise', async ({ page }) => { + await setup(page, 'candidate', true, true) + await page.evaluate(() => { + window.art.notice.show = false + }) + await page.locator('.art-control-screenshot').click() + await expect.poll(() => page.evaluate(() => window.art.notice.show)).toBe(true) + await page.evaluate(() => window.art.destroy()) +}) diff --git a/test/browser/server.mjs b/test/browser/server.mjs index 45884a9b2..fa0000ed3 100644 --- a/test/browser/server.mjs +++ b/test/browser/server.mjs @@ -61,6 +61,7 @@ for (const extension of ['mp4', 'webm']) { const mime = { '.html': 'text/html', '.js': 'text/javascript', '.mjs': 'text/javascript', '.json': 'application/json', '.css': 'text/css', '.mp4': 'video/mp4', '.webm': 'video/webm', '.vtt': 'text/vtt', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg' } add('/test/declaration-cues.vtt', fs.readFileSync(path.join(workspace, 'test/browser/media/declaration-cues.vtt')), { kind: 'test-subtitles', file: 'test/browser/media/declaration-cues.vtt' }) +add('/test/thumbnail-grid.svg', fs.readFileSync(path.join(workspace, 'test/browser/media/thumbnail-grid.svg')), { kind: 'test-thumbnail-grid', file: 'test/browser/media/thumbnail-grid.svg' }) function send(req, res, bytes, filename) { res.setHeader('Content-Type', mime[path.extname(filename)] || 'application/octet-stream') res.setHeader('Cache-Control', 'no-store') diff --git a/test/browser/source.spec.js b/test/browser/source.spec.js index 79ba44299..da7f8f13c 100644 --- a/test/browser/source.spec.js +++ b/test/browser/source.spec.js @@ -116,6 +116,57 @@ test('candidate: quality switch restores position/rate and preserves real custom expect(result.error).toBe(0) }) +test('candidate: direct currentTime during a native quality seek is not overwritten by automatic restoration', async ({ page }, testInfo) => { + await page.goto('/test/player.html?core=candidate&chapter=published') + await page.evaluate(() => window.createPlayer('/test/pattern.mp4?position=initial')) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) + await page.locator('#play').click() + await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1) + await page.locator('#pause').click() + await expect.poll(() => page.evaluate(() => window.art.video.paused && !window.art.video.seeking)).toBe(true) + await page.evaluate(() => { + window.art.currentTime = 2 + }) + await expect.poll(() => page.evaluate(() => !window.art.video.seeking && Math.abs(window.art.currentTime - 2) < 0.05)).toBe(true) + const result = await page.evaluate(async () => { + const { art } = window + let overrides = 0 + const seeks = [] + const writes = [] + for (const name of ['currentTime', 'playbackRate']) { + const descriptor = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, name) + Object.defineProperty(art.video, name, { + configurable: true, + get() { return descriptor.get.call(this) }, + set(value) { + writes.push({ name, value, before: this.currentTime, seeking: this.seeking }) + descriptor.set.call(this, value) + writes.push({ name: `${name}:after`, value: this.currentTime, seeking: this.seeking }) + }, + }) + } + art.once('video:seeked', () => { + overrides++ + art.currentTime = 4 + }) + art.on('video:seeked', () => seeks.push({ time: art.currentTime, seeking: art.video.seeking })) + await art.switchQuality('/test/pattern.mp4?position=consumer') + const result = { overrides, seeks, writes, time: art.currentTime, paused: art.video.paused, seeking: art.video.seeking } + art.destroy() + return result + }) + await testInfo.attach('quality-direct-position', { contentType: 'application/json', body: JSON.stringify(result) }) + expect(result.overrides).toBe(1) + // Assert the player write contract separately from native seek precision. + // WebKit may finish this reentrant native seek at a different media clock. + const positions = result.writes.filter(item => item.name === 'currentTime') + expect(positions).toHaveLength(2) + expect(positions[0].value).toBeCloseTo(2, 1) + expect(positions[1].value).toBe(4) + expect(result.paused).toBe(true) + expect(result.seeking).toBe(false) +}) + test('candidate: real switch settles when the controlled native resume rejects', async ({ page }) => { await page.goto('/test/player.html?core=candidate&chapter=published') await page.evaluate(() => window.createPlayer('/test/pattern.mp4?resume=initial')) diff --git a/test/browser/thumbnails.spec.js b/test/browser/thumbnails.spec.js new file mode 100644 index 000000000..d189cd080 --- /dev/null +++ b/test/browser/thumbnails.spec.js @@ -0,0 +1,165 @@ +import { expect, test } from './fixtures.js' + +async function setup(page, core, scale = 1) { + await page.goto(`/test/player.html?core=${core}&chapter=published`) + await page.evaluate(({ scale }) => { + window.art = new window.Artplayer({ + container: '.player', + url: '/test/pattern.mp4', + muted: true, + thumbnails: { url: '/test/thumbnail-grid.svg', number: 100, column: 10, width: 100, height: 60, scale }, + }) + window.hoverThumbnail = (percentage) => { + const art = window.art + const progress = art.template.$progress + const clientX = progress.getBoundingClientRect().left + progress.clientWidth * percentage + art.emit('setBar', 'hover', percentage, new MouseEvent('mousemove', { clientX })) + } + }, { scale }) + await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true) +} + +async function visible(page) { + await expect.poll(() => page.evaluate(() => window.art.controls.thumbnails.style.backgroundImage)).not.toBe('') +} + +for (const core of ['published', 'candidate']) { + test(`${core}: thumbnail cells follow the generated grid at row boundaries and on returning to the first cell`, async ({ page }, testInfo) => { + await setup(page, core) + await page.evaluate(() => window.hoverThumbnail(0.1)) + await visible(page) + const result = await page.evaluate(() => { + const art = window.art + const element = art.controls.thumbnails + const row = element.style.backgroundPosition + const dimensions = [element.style.width, element.style.height] + window.hoverThumbnail(0.11) + const ordinary = element.style.backgroundPosition + window.hoverThumbnail(0.001) + const first = element.style.backgroundPosition + const left = element.style.left + window.hoverThumbnail(0.999) + const last = element.style.backgroundPosition + const right = Number.parseFloat(element.style.left) + const expectedRight = art.template.$progress.clientWidth - 100 + const descriptor = Object.getOwnPropertyDescriptor(art, 'thumbnails') + return { row, ordinary, first, last, left, right, expectedRight, dimensions, immutable: !descriptor.enumerable && !descriptor.configurable } + }) + expect(result.row).toBe(core === 'published' ? '-900px 0px' : '0px -60px') + expect(result.ordinary).toBe('-100px -60px') + expect(result.first).toBe(core === 'published' ? '-100px -60px' : '0px 0px') + expect(result.last).toBe('-900px -540px') + expect(result.left).toBe('0px') + expect(result.right).toBe(result.expectedRight) + expect(result.dimensions).toEqual(['100px', '60px']) + expect(result.immutable).toBe(true) + await testInfo.attach('thumbnail-grid', { contentType: 'image/png', body: await page.locator('.player').screenshot() }) + await page.evaluate(() => window.art.destroy()) + }) + + test(`${core}: scaled internal thumbnails and public image results have distinct Blob URL owners`, async ({ page }) => { + await setup(page, core, 0.5) + await page.evaluate(() => { + window.thumbnailRevocations = [] + const original = URL.revokeObjectURL + URL.revokeObjectURL = function (url) { + window.thumbnailRevocations.push(url) + return original.call(this, url) + } + }) + await page.evaluate(() => window.hoverThumbnail(0.2)) + await visible(page) + const result = await page.evaluate(async () => { + const art = window.art + const style = art.controls.thumbnails.style + const internal = style.backgroundImage.slice(5, -2) + const image = await window.Artplayer.utils.loadImg('/test/thumbnail-grid.svg', 0.5) + const publicUrl = image.src + const dimensions = [image.naturalWidth, image.naturalHeight] + const previewSize = [style.width, style.height] + art.destroy() + const revokedInternal = window.thumbnailRevocations.filter(url => url === internal).length + const revokedPublic = window.thumbnailRevocations.filter(url => url === publicUrl).length + const blob = await (await fetch(publicUrl)).blob() + URL.revokeObjectURL(publicUrl) + if (!revokedInternal) + URL.revokeObjectURL(internal) + return { dimensions, previewSize, internalBlob: internal.startsWith('blob:'), revokedInternal, revokedPublic, publicType: blob.type } + }) + expect(result).toEqual({ dimensions: [500, 300], previewSize: ['50px', '30px'], internalBlob: true, revokedInternal: core === 'published' ? 0 : 1, revokedPublic: 0, publicType: 'image/png' }) + }) + + test(`${core}: a delayed image follows the latest hover rather than the first request position`, async ({ page, request }) => { + const svg = await (await request.get('/test/thumbnail-grid.svg')).body() + let release + const gate = new Promise(resolve => release = resolve) + let requested + const received = new Promise(resolve => requested = resolve) + await page.route('**/test/thumbnail-grid.svg?delayed=1', async (route) => { + requested() + await gate + await route.fulfill({ contentType: 'image/svg+xml', body: svg }) + }) + await setup(page, core) + await page.evaluate(() => { + window.art.thumbnails = { ...window.art.thumbnails, url: '/test/thumbnail-grid.svg?delayed=1' } + window.hoverThumbnail(0.2) + }) + await received + await page.evaluate(() => window.hoverThumbnail(0.7)) + release() + await visible(page) + const result = await page.evaluate(() => ({ left: Number.parseFloat(window.art.controls.thumbnails.style.left), width: window.art.template.$progress.clientWidth })) + expect(result.left).toBeCloseTo(result.width * (core === 'published' ? 0.2 : 0.7) - 50, 4) + await page.evaluate(() => window.art.destroy()) + }) +} + +test('candidate: removing thumbnails revokes the scaled image and a replacement control can reload', async ({ page }) => { + await setup(page, 'candidate', 0.5) + await page.evaluate(() => window.hoverThumbnail(0.2)) + await visible(page) + await page.evaluate(() => { + const art = window.art + const url = art.controls.thumbnails.style.backgroundImage.slice(5, -2) + window.removedThumbnailRevocations = 0 + const original = URL.revokeObjectURL + URL.revokeObjectURL = function (value) { + if (value === url) + window.removedThumbnailRevocations++ + return original.call(this, value) + } + art.controls.remove('thumbnails') + art.controls.add({ name: 'thumbnails', position: 'top', index: 20 }) + window.hoverThumbnail(0.4) + }) + await visible(page) + expect(await page.evaluate(() => window.removedThumbnailRevocations)).toBe(1) + await page.evaluate(() => window.art.destroy()) + expect(await page.evaluate(() => window.removedThumbnailRevocations)).toBe(1) +}) + +test('candidate: image failure permits a retry through the same thumbnail configuration', async ({ page, request }) => { + const svg = await (await request.get('/test/thumbnail-grid.svg')).body() + let attempts = 0 + await page.route('**/test/thumbnail-grid.svg?retry=1', async (route) => { + attempts++ + await route.fulfill({ + status: attempts === 1 ? 503 : 200, + headers: { 'Cache-Control': 'no-store' }, + contentType: 'image/svg+xml', + body: attempts === 1 ? '' : svg, + }) + }) + await setup(page, 'candidate') + const warning = page.waitForEvent('console', message => message.type() === 'warning' && message.text().includes('ArtPlayer thumbnail load failed')) + await page.evaluate(() => { + window.art.thumbnails = { ...window.art.thumbnails, url: '/test/thumbnail-grid.svg?retry=1' } + window.hoverThumbnail(0.2) + }) + await warning + await page.evaluate(() => window.hoverThumbnail(0.3)) + await visible(page) + expect(attempts).toBe(2) + await page.evaluate(() => window.art.destroy()) +}) diff --git a/test/component-resources.test.js b/test/component-resources.test.js index e046ac56c..f7940c2dc 100644 --- a/test/component-resources.test.js +++ b/test/component-resources.test.js @@ -127,6 +127,27 @@ test('quality rejection identity and captured selection closure survive disposal assert.equal(art.notice.show, '') }) +test('quality setter retains the selected default, empty arrays, option identity and setter-only descriptor', () => { + const { art } = fixture() + const updates = [] + art.controls = { update: option => updates.push(option) } + qualityMix(art) + const options = [{ html: 'first', url: 'a' }, { html: 'chosen', url: 'b', default: true }, { html: 'later', url: 'c', default: true }] + art.quality = options + assert.equal(updates[0].html, 'chosen') + assert.equal(updates[0].selector, options) + assert.deepEqual(updates[0].style, { marginRight: '10px' }) + const empty = [] + art.quality = empty + assert.equal(updates[1].html, '') + assert.equal(updates[1].selector, empty) + const descriptor = Object.getOwnPropertyDescriptor(art, 'quality') + assert.equal(descriptor.get, undefined) + assert.equal(descriptor.enumerable, false) + assert.equal(descriptor.configurable, false) + assert.equal(art.quality, undefined) +}) + function fixture() { const art = new Emitter() const registered = new Set() diff --git a/test/progress.test.js b/test/progress.test.js new file mode 100644 index 000000000..08cb007d6 --- /dev/null +++ b/test/progress.test.js @@ -0,0 +1,134 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { Emitter, installProgressInteractions, getPosFromEvent, beginLifecycle, getScope, beginSource, ownEntry, releaseEntry } = await loadModules({ + Emitter: 'packages/artplayer/src/utils/emitter', + installProgressInteractions: { file: 'packages/artplayer/src/control/progress/interactions', name: 'installProgressInteractions' }, + getPosFromEvent: { file: 'packages/artplayer/src/control/progress/position', name: 'getPosFromEvent' }, + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, + beginSource: { file: 'packages/artplayer/src/source/operation', name: 'beginSource' }, + ownEntry: { file: 'packages/artplayer/src/component/resources', name: 'ownEntry' }, + releaseEntry: { file: 'packages/artplayer/src/component/resources', name: 'releaseEntry' }, +}) + +function mouse(name, clientX = 60, button = 0) { + return Object.assign(new Event(name), { clientX, button }) +} + +function fixture() { + const progress = Object.assign(new EventTarget(), { clientWidth: 100, getBoundingClientRect: () => ({ left: 10 }) }) + const indicator = new EventTarget() + const control = Object.assign(new EventTarget(), { querySelector: () => indicator }) + const effects = [] + const art = Object.assign(new Emitter(), { + template: { $progress: progress }, + duration: 200, + isRotate: false, + events: { + proxy(target, name, callback) { + target.addEventListener(name, callback) + return () => target.removeEventListener(name, callback) + }, + remove: cleanup => cleanup(), + }, + }) + Object.defineProperty(art, 'seek', { get: () => 0, set: value => effects.push(['seek', value]) }) + art.on('setBar', (kind, percentage) => effects.push(['setBar', kind, percentage])) + beginLifecycle(art) + ownEntry(art, control) + installProgressInteractions(art, control) + return { art, progress, control, indicator, effects } +} + +test('progress position clamps outside edges and retains its time and percentage calculations', () => { + const f = fixture() + assert.deepEqual(getPosFromEvent(f.art, mouse('click', 60)), { second: 100, time: '01:40', width: 50, percentage: 0.5 }) + assert.equal(getPosFromEvent(f.art, mouse('click', -100)).percentage, 0) + assert.equal(getPosFromEvent(f.art, mouse('click', 1000)).percentage, 1) + f.progress.clientWidth = 0 + assert(Number.isNaN(getPosFromEvent(f.art, mouse('click', 10)).percentage)) +}) + +test('live progress clicks and drags preserve setBar before seek and mouseup stops dragging', () => { + const f = fixture() + f.progress.dispatchEvent(mouse('click')) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['seek', 100]]) + f.effects.length = 0 + f.progress.dispatchEvent(mouse('mousedown')) + f.art.emit('document:mousemove', mouse('mousemove', 85)) + f.art.emit('document:mouseup', mouse('mouseup')) + f.art.emit('document:mousemove', mouse('mousemove', 100)) + assert.deepEqual(f.effects, [['setBar', 'played', 0.75], ['seek', 150]]) +}) + +for (const mode of ['control removal', 'destruction', 'source replacement']) { + test(`progress click does not seek after ${mode} inside setBar`, () => { + const f = fixture() + f.art.on('setBar', () => { + if (mode === 'control removal') + releaseEntry(f.control) + else if (mode === 'destruction') + getScope(f.art).dispose() + else + beginSource(f.art) + }) + f.progress.dispatchEvent(mouse('click')) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5]]) + }) +} + +test('progress drag loses its source when media is replaced and a new mousedown can start again', () => { + const f = fixture() + f.progress.dispatchEvent(mouse('mousedown')) + beginSource(f.art) + f.art.emit('document:mousemove', mouse('mousemove', 85)) + assert.deepEqual(f.effects, []) + f.progress.dispatchEvent(mouse('mousedown')) + f.art.emit('document:mousemove', mouse('mousemove', 60)) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['seek', 100]]) +}) + +test('progress drag does not seek when its control is removed inside setBar', () => { + const f = fixture() + f.art.on('setBar', () => releaseEntry(f.control)) + f.progress.dispatchEvent(mouse('mousedown')) + f.art.emit('document:mousemove', mouse('mousemove', 60)) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5]]) +}) + +test('progress geometry reentry cannot emit or seek after disposal', () => { + const f = fixture() + f.progress.getBoundingClientRect = () => { + getScope(f.art).dispose() + return { left: 10 } + } + f.progress.dispatchEvent(mouse('click')) + assert.deepEqual(f.effects, []) +}) + +test('a newer nested progress click supersedes the earlier seek', () => { + const f = fixture() + let nested = false + f.art.on('setBar', () => { + if (!nested) { + nested = true + f.progress.dispatchEvent(mouse('click', 85)) + } + }) + f.progress.dispatchEvent(mouse('click', 60)) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['setBar', 'played', 0.75], ['seek', 150]]) +}) + +test('right-button mousedown and mouseup inside setBar do not continue dragging', () => { + const f = fixture() + f.progress.dispatchEvent(mouse('mousedown', 60, 2)) + f.art.emit('document:mousemove', mouse('mousemove', 85)) + assert.deepEqual(f.effects, []) + f.art.on('setBar', () => f.art.emit('document:mouseup', mouse('mouseup'))) + f.progress.dispatchEvent(mouse('mousedown')) + f.art.emit('document:mousemove', mouse('mousemove', 60)) + assert.deepEqual(f.effects, [['setBar', 'played', 0.5]]) +}) diff --git a/test/screenshot.test.js b/test/screenshot.test.js new file mode 100644 index 000000000..df9fd7c99 --- /dev/null +++ b/test/screenshot.test.js @@ -0,0 +1,165 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { screenshotMix, beginLifecycle, getScope, beginSource } = await loadModules({ + screenshotMix: 'packages/artplayer/src/player/screenshotMix', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, + beginSource: { file: 'packages/artplayer/src/source/operation', name: 'beginSource' }, +}) + +function fixture(t) { + const calls = [] + const callbacks = [] + const context = { drawImage: (...args) => calls.push(['draw', ...args]) } + const canvas = { + width: 0, + height: 0, + getContext: () => context, + toDataURL: type => `data:${type};base64,frame`, + toBlob: callback => callbacks.push(callback), + } + const anchor = { style: {}, click: () => calls.push(['download', anchor.download]), remove: () => calls.push(['remove']) } + const previous = Object.getOwnPropertyDescriptor(globalThis, 'document') + Object.defineProperty(globalThis, 'document', { configurable: true, value: { + createElement: tag => tag === 'canvas' ? canvas : anchor, + body: { appendChild: () => {} }, + } }) + t.after(() => previous ? Object.defineProperty(globalThis, 'document', previous) : delete globalThis.document) + const video = { videoWidth: 320, videoHeight: 180, currentTime: 62 } + const art = { template: { $video: video }, notice: { show: '' }, emit: (...args) => calls.push(args) } + beginLifecycle(art) + screenshotMix(art) + return { art, canvas, video, context, calls, callbacks, scope: getScope(art) } +} + +test('screenshot methods retain immutable bound descriptors, PNG dimensions and filename', async (t) => { + const f = fixture(t) + for (const name of ['getDataURL', 'getBlobUrl', 'screenshot']) { + const descriptor = Object.getOwnPropertyDescriptor(f.art, name) + assert.equal(descriptor.enumerable, false) + assert.equal(descriptor.configurable, false) + assert.equal(descriptor.writable, false) + } + const screenshot = f.art.screenshot + assert.equal(await screenshot(), 'data:image/png;base64,frame') + assert.equal(f.canvas.width, 320) + assert.equal(f.canvas.height, 180) + assert.deepEqual(f.calls, [ + ['draw', f.video, 0, 0], + ['download', 'artplayer_01:02.png'], + ['remove'], + ['screenshot', 'data:image/png;base64,frame'], + ]) + await screenshot('custom.png') + assert.deepEqual(f.calls.at(-3), ['download', 'custom.png.png']) +}) + +test('capture rejects the original drawing and security errors through both methods', async (t) => { + const f = fixture(t) + const failure = new Error('tainted canvas') + f.context.drawImage = () => { + throw failure + } + await assert.rejects(f.art.getDataURL(), error => error === failure) + await assert.rejects(f.art.getBlobUrl(), error => error === failure) + assert.equal(f.art.notice.show, failure) + assert.equal(f.callbacks.length, 0) +}) + +test('synchronous toBlob failure updates notice before returning its rejected Promise', async (t) => { + const f = fixture(t) + const failure = new Error('encoding failed synchronously') + f.canvas.toBlob = () => { + throw failure + } + const promise = f.art.getBlobUrl() + assert.equal(f.art.notice.show, failure) + await assert.rejects(promise, error => error === failure) +}) + +test('missing canvas context rejects both public captures', async (t) => { + const f = fixture(t) + f.canvas.getContext = () => null + await assert.rejects(f.art.getDataURL(), { name: 'TypeError', message: /context/ }) + await assert.rejects(f.art.getBlobUrl(), { name: 'TypeError', message: /context/ }) +}) + +test('throwing notice setter becomes a rejection even in an asynchronous callback', async (t) => { + const f = fixture(t) + const failure = new Error('consumer notice setter failed') + Object.defineProperty(f.art.notice, 'show', { + get: () => '', + set() { + throw failure + }, + }) + const promise = f.art.getBlobUrl() + const rejected = assert.rejects(promise, error => error === failure) + assert.doesNotThrow(() => f.callbacks[0](null)) + await rejected +}) + +test('late capture rejection after destruction does not update notice', async (t) => { + const f = fixture(t) + const promise = f.art.getBlobUrl() + const rejected = assert.rejects(promise, /encode/) + f.scope.dispose() + f.callbacks[0](null) + await rejected + assert.equal(f.art.notice.show, '') +}) + +test('asynchronous Blob URL failures reject without escaping the canvas callback', async (t) => { + const f = fixture(t) + const failure = new Error('object URL allocation failed') + t.mock.method(URL, 'createObjectURL', () => { + throw failure + }) + const promise = f.art.getBlobUrl() + const rejected = assert.rejects(promise, error => error === failure) + assert.doesNotThrow(() => f.callbacks[0](new Blob(['frame']))) + await rejected + assert.equal(f.art.notice.show, failure) +}) + +test('null Blob rejects without allocating a URL or leaving the promise pending', async (t) => { + const f = fixture(t) + const allocate = t.mock.method(URL, 'createObjectURL') + const promise = f.art.getBlobUrl() + const rejected = assert.rejects(promise, /encode|blob/i) + assert.doesNotThrow(() => f.callbacks[0](null)) + await rejected + assert.equal(allocate.mock.callCount(), 0) +}) + +test('concurrent Blob captures settle independently and transfer URL ownership to consumers', async (t) => { + const f = fixture(t) + const revoke = t.mock.method(URL, 'revokeObjectURL', () => {}) + t.mock.method(URL, 'createObjectURL', blob => `blob:${blob.size}`) + const first = f.art.getBlobUrl() + const second = f.art.getBlobUrl() + f.callbacks[1](new Blob(['bb'])) + f.scope.dispose() + f.callbacks[0](new Blob(['a'])) + assert.deepEqual(await Promise.all([first, second]), ['blob:1', 'blob:2']) + assert.equal(revoke.mock.callCount(), 0) +}) + +test('destruction during screenshot await preserves its result without download or event', async (t) => { + const f = fixture(t) + const promise = f.art.screenshot() + f.scope.dispose() + assert.equal(await promise, 'data:image/png;base64,frame') + assert.deepEqual(f.calls, [['draw', f.video, 0, 0]]) +}) + +test('source replacement during screenshot await suppresses stale download and event', async (t) => { + const f = fixture(t) + const promise = f.art.screenshot() + beginSource(f.art) + assert.equal(await promise, 'data:image/png;base64,frame') + assert.deepEqual(f.calls, [['draw', f.video, 0, 0]]) +}) diff --git a/test/source.test.js b/test/source.test.js index c8b19b517..7bae9dcb9 100644 --- a/test/source.test.js +++ b/test/source.test.js @@ -4,13 +4,15 @@ import { mock, test } from 'node:test' import { setImmediate } from 'node:timers/promises' import { loadModules } from './helpers/load.js' -const { Emitter, urlMix, switchMix, playMix, beginLifecycle, getScope } = await loadModules({ +const { Emitter, urlMix, switchMix, playMix, beginLifecycle, getScope, positionRestoration, currentTimeMix } = await loadModules({ Emitter: 'packages/artplayer/src/utils/emitter', urlMix: 'packages/artplayer/src/player/urlMix', switchMix: 'packages/artplayer/src/player/switchMix', playMix: 'packages/artplayer/src/player/playMix', beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, + positionRestoration: { file: 'packages/artplayer/src/source/restore-position', name: 'positionRestoration' }, + currentTimeMix: 'packages/artplayer/src/player/currentTimeMix', }) function createArt(customType) { @@ -33,6 +35,212 @@ function createArt(customType) { return art } +test('source assignment does not revoke a caller-owned Blob URL still used elsewhere', async (t) => { + const art = createArt() + const blob = new Blob(['shared media'], { type: 'video/mp4' }) + const url = URL.createObjectURL(blob) + t.after(() => URL.revokeObjectURL(url)) + art.url = url + art.url = 'next.mp4' + assert.equal(await (await fetch(url)).text(), 'shared media') + getScope(art).dispose() + assert.equal(await (await fetch(url)).text(), 'shared media') +}) + +test('quality restoration waits for a pending native seek before restoring playback rate', async () => { + const art = createArt() + let settled = false + const switching = art.switchQuality('next.mp4').then(() => { + settled = true + }) + art.playbackRate = 1 + art.template.$video.seeking = true + art.emit('video:loadedmetadata') + art.emit('video:canplay') + await Promise.resolve() + assert.equal(settled, false) + assert.equal(art.playbackRate, 1) + assert.equal(art.currentTime, 37) + art.template.$video.seeking = false + art.emit('video:seeked') + await switching + assert.equal(settled, true) + assert.equal(art.playbackRate, 1.5) + assert.deepEqual(Object.keys(art.e), []) +}) + +test('a switch waiting for seeked settles on cancellation and ignores the late seek', async () => { + const art = createArt() + const switching = art.switchQuality('next.mp4') + art.playbackRate = 1 + art.template.$video.seeking = true + art.emit('video:canplay') + getScope(art).dispose() + await switching + art.template.$video.seeking = false + art.emit('video:seeked') + assert.equal(art.playbackRate, 1) + assert.deepEqual(Object.keys(art.e), []) +}) + +test('a missed native quality seek is corrected once and settles after the second seeked', async () => { + const art = createArt() + let time = 37 + const writes = [] + Object.defineProperty(art, 'currentTime', { + get: () => time, + set(value) { + writes.push(value) + time = value + art.template.$video.seeking = true + }, + }) + let settled = false + const switching = art.switchQuality('next.mp4').then(() => { + settled = true + }) + art.emit('video:loadedmetadata') + art.emit('video:canplay') + time = 0 + art.template.$video.seeking = false + art.emit('video:seeked') + await Promise.resolve() + assert.equal(settled, false) + assert.deepEqual(writes, [37, 37]) + assert.equal(art.playbackRate, 1.5) + // Even a second native miss must not start an unbounded correction loop. + time = 0 + art.template.$video.seeking = false + art.emit('video:seeked') + await switching + assert.deepEqual(writes, [37, 37]) + assert.deepEqual(Object.keys(art.e), []) +}) + +test('public seek during quality loading wins over metadata restoration and native correction', async () => { + for (const beforeMetadata of [false, true]) { + const art = createArt() + const switching = art.switchQuality('next.mp4') + art.template.$video.seeking = true + if (!beforeMetadata) + art.emit('video:loadedmetadata') + art.currentTime = 6 + art.emit('seek', 6) + if (beforeMetadata) + art.emit('video:loadedmetadata') + art.template.$video.seeking = false + art.emit('video:canplay') + await switching + assert.equal(art.currentTime, 6) + assert.deepEqual(Object.keys(art.e), []) + } +}) + +test('direct public currentTime writes during quality loading supersede automatic restoration', async () => { + for (const beforeMetadata of [false, true]) { + const art = createArt() + art.duration = 100 + art.template.$video.currentTime = 37 + currentTimeMix(art) + const switching = art.switchQuality('next.mp4') + art.template.$video.seeking = true + if (!beforeMetadata) + art.emit('video:loadedmetadata') + art.currentTime = 6 + if (beforeMetadata) + art.emit('video:loadedmetadata') + art.template.$video.seeking = false + art.emit('video:canplay') + await switching + assert.equal(art.currentTime, 6) + assert.deepEqual(Object.keys(art.e), []) + } +}) + +test('position restoration preserves clamping and native frame rounding', () => { + let time = 0 + const video = { seeking: false } + const writes = [] + const art = { + template: { $video: video }, + get currentTime() { return time }, + set currentTime(value) { + writes.push(value) + time = Math.min(10, value) + video.seeking = true + }, + } + const restoration = positionRestoration(art, 37, () => true) + restoration.restore() + time = 9.99 + video.seeking = false + assert.equal(restoration.ready(), true) + assert.deepEqual(writes, [37]) + time = 0 + assert.equal(restoration.ready(), false) + assert.deepEqual(writes, [37, 10]) +}) + +test('a reentrant position read cannot correct a cancelled or manually superseded seek', () => { + for (const boundary of ['cancel', 'manual']) { + let active = true + let reenter = false + let time = 0 + let restoration + const writes = [] + const art = { + template: { $video: { seeking: true } }, + get currentTime() { + if (reenter) { + if (boundary === 'cancel') + active = false + else + restoration.manual() + } + return time + }, + set currentTime(value) { + writes.push(value) + time = value + }, + } + restoration = positionRestoration(art, 37, () => active) + restoration.restore() + art.template.$video.seeking = false + time = 6 + reenter = true + assert.equal(restoration.ready(), boundary === 'manual') + assert.deepEqual(writes, [37]) + } +}) + +test('synchronous correction seeked reentry resumes a source only once', async () => { + const art = createArt() + art.playing = true + let time = 37 + let correcting = false + Object.defineProperty(art, 'currentTime', { + get: () => time, + set(value) { + time = value + art.template.$video.seeking = !correcting + if (correcting) + art.emit('video:seeked') + }, + }) + const switching = art.switchQuality('next.mp4') + art.emit('video:loadedmetadata') + art.emit('video:canplay') + time = 0 + correcting = true + art.template.$video.seeking = false + art.emit('video:seeked') + await switching + assert.equal(time, 37) + assert.equal(art.play.mock.callCount(), 1) + assert.deepEqual(Object.keys(art.e), []) +}) + test('superseded switches settle before readiness and only the latest restores state/restarts', async () => { const art = createArt() const restarts = [] diff --git a/test/thumbnails.test.js b/test/thumbnails.test.js new file mode 100644 index 000000000..c56899b01 --- /dev/null +++ b/test/thumbnails.test.js @@ -0,0 +1,340 @@ +import assert from 'node:assert/strict' +// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner. +import { test } from 'node:test' +import { loadModules } from './helpers/load.js' + +const { thumbnailsMix, Emitter, beginLifecycle, getScope, beginSource, ownEntry, releaseEntry, loadImg, loadThumbnailImage } = await loadModules({ + thumbnailsMix: 'packages/artplayer/src/player/thumbnailsMix', + Emitter: 'packages/artplayer/src/utils/emitter', + beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' }, + getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' }, + beginSource: { file: 'packages/artplayer/src/source/operation', name: 'beginSource' }, + ownEntry: { file: 'packages/artplayer/src/component/resources', name: 'ownEntry' }, + releaseEntry: { file: 'packages/artplayer/src/component/resources', name: 'releaseEntry' }, + loadImg: { file: 'packages/artplayer/src/image/load', name: 'loadImg' }, + loadThumbnailImage: { file: 'packages/artplayer/src/image/load', name: 'loadThumbnailImage' }, +}) + +const flush = () => new Promise(resolve => setImmediate(resolve)) + +function fixture(t, overrides = {}) { + const images = [] + const callbacks = [] + const errors = [] + const revoked = [] + const warnings = [] + class FakeImage { + width = 1000 + height = 600 + naturalWidth = 1000 + src = '' + onload = null + onerror = null + constructor() { + images.push(this) + } + + removeAttribute(name) { + if (name === 'src') + this.src = '' + } + } + const canvas = { width: 0, height: 0, getContext: () => ({ drawImage() {} }), toBlob: callback => callbacks.push(callback) } + for (const [name, value] of Object.entries({ Image: FakeImage, document: { createElement: () => canvas } })) { + const previous = Object.getOwnPropertyDescriptor(globalThis, name) + Object.defineProperty(globalThis, name, { configurable: true, value }) + t.after(() => previous ? Object.defineProperty(globalThis, name, previous) : delete globalThis[name]) + } + t.mock.method(URL, 'createObjectURL', () => 'blob:thumbnail') + t.mock.method(URL, 'revokeObjectURL', url => revoked.push(url)) + t.mock.method(console, 'warn', (...args) => warnings.push(args)) + const art = Object.assign(new Emitter(), { + option: { thumbnails: { url: 'first.png', number: 100, column: 10, width: 100, height: 60, scale: 1, ...overrides }, isLive: false }, + template: { $progress: { clientWidth: 1000 }, $video: { videoWidth: 320, videoHeight: 180 } }, + controls: { thumbnails: { style: {} } }, + }) + beginLifecycle(art) + ownEntry(art, art.controls.thumbnails) + thumbnailsMix(art) + function bar(kind, percentage, event) { + for (const listener of art.e?.setBar || []) { + const result = listener.fn(kind, percentage, event) + if (result?.catch) + result.catch(error => errors.push(error)) + } + } + return { art, canvas, images, callbacks, errors, revoked, warnings, scope: getScope(art), bar, hover: percentage => bar('hover', percentage) } +} + +test('thumbnail setter preserves option identity, live restrictions and immutable descriptor', (t) => { + const f = fixture(t) + const descriptor = Object.getOwnPropertyDescriptor(f.art, 'thumbnails') + assert.equal(descriptor.enumerable, false) + assert.equal(descriptor.configurable, false) + const option = { url: 'next.png', number: 4 } + f.art.thumbnails = option + assert.equal(f.art.thumbnails, option) + f.art.thumbnails = { url: '' } + assert.equal(f.art.thumbnails, option) + f.art.option.isLive = true + f.art.thumbnails = { url: 'live.png' } + assert.equal(f.art.thumbnails, option) +}) + +test('thumbnail layout matches generated sprite cells and preserves progress endpoint handling', async (t) => { + const f = fixture(t) + f.hover(0.1) + f.images[0].onload() + await flush() + const style = f.art.controls.thumbnails.style + assert.deepEqual(style, { backgroundImage: 'url(first.png)', height: '60px', width: '100px', backgroundPosition: '-0px -60px', left: '50px' }) + f.hover(0.11) + assert.equal(style.backgroundPosition, '-100px -60px') + const before = { ...style } + f.hover(0) + f.hover(1) + f.hover(Number.NaN) + assert.deepEqual(style, before) + f.hover(0.001) + assert.equal(style.backgroundPosition, '-0px -0px') + assert.equal(style.left, 0) + f.hover(0.999) + assert.equal(style.backgroundPosition, '-900px -540px') + assert.equal(style.left, '900px') +}) + +test('replaced thumbnail configuration cannot be overwritten by an older completed load', async (t) => { + const f = fixture(t) + f.hover(0.2) + const oldLoad = f.images[0].onload + f.art.thumbnails = { ...f.art.thumbnails, url: 'second.png' } + f.hover(0.4) + f.images[1].onload() + await flush() + oldLoad() + await flush() + assert.equal(f.art.controls.thumbnails.style.backgroundImage, 'url(second.png)') +}) + +test('failed thumbnail load can retry and does not escape the internal event handler', async (t) => { + const f = fixture(t) + f.hover(0.2) + f.images[0].onerror() + await flush() + f.hover(0.3) + assert.equal(f.images.length, 2) + f.images[1].onload() + await flush() + assert.equal(f.art.controls.thumbnails.style.backgroundImage, 'url(first.png)') + assert.deepEqual(f.errors, []) +}) + +test('destroy cancels pending thumbnail rendering and removes its setBar subscription', async (t) => { + const f = fixture(t) + f.hover(0.2) + const loaded = f.images[0].onload + f.scope.dispose() + loaded() + await flush() + assert.deepEqual(f.art.controls.thumbnails.style, {}) + assert.equal(f.art.e?.setBar?.length || 0, 0) +}) + +test('scaled thumbnail Blob URL is released once on configuration replacement', async (t) => { + const f = fixture(t, { scale: 0.5 }) + f.hover(0.2) + f.images[0].onload() + f.callbacks[0](new Blob(['image'])) + f.images[1].onload() + await flush() + assert.equal(f.art.controls.thumbnails.style.backgroundImage, 'url(blob:thumbnail)') + f.art.thumbnails = { ...f.art.thumbnails, url: 'next.png' } + assert.deepEqual(f.revoked, ['blob:thumbnail']) + f.scope.dispose() + assert.deepEqual(f.revoked, ['blob:thumbnail']) +}) + +test('pending load renders only the latest hover and suppresses stale source coordinates', async (t) => { + const f = fixture(t) + f.hover(0.2) + f.hover(0.7) + f.images[0].onload() + await flush() + assert.equal(f.art.controls.thumbnails.style.left, '650px') + f.art.thumbnails = { ...f.art.thumbnails, url: 'next.png' } + const before = { ...f.art.controls.thumbnails.style } + f.hover(0.4) + beginSource(f.art) + f.images[1].onload() + await flush() + assert.deepEqual(f.art.controls.thumbnails.style, before) + f.hover(0.5) + assert.equal(f.art.controls.thumbnails.style.backgroundImage, 'url(next.png)') +}) + +test('removing the thumbnail control releases its image and a replacement starts a new request', async (t) => { + const f = fixture(t, { scale: 0.5 }) + f.hover(0.2) + f.images[0].onload() + f.callbacks[0](new Blob(['image'])) + f.images[1].onload() + await flush() + releaseEntry(f.art.controls.thumbnails) + assert.deepEqual(f.revoked, ['blob:thumbnail']) + const next = { style: {} } + f.art.controls.thumbnails = next + ownEntry(f.art, next) + f.hover(0.4) + assert.equal(f.images.length, 3) + f.scope.dispose() +}) + +test('cancelled scaling cannot allocate a Blob URL from a late encoder callback', async (t) => { + const f = fixture(t, { scale: 0.5 }) + f.hover(0.2) + f.images[0].onload() + f.scope.dispose() + f.callbacks[0](new Blob(['image'])) + await flush() + assert.equal(f.images.length, 1) + assert.deepEqual(f.revoked, []) + assert.deepEqual(f.art.controls.thumbnails.style, {}) +}) + +test('configuration replacement during rendering stops remaining stale style writes', async (t) => { + const f = fixture(t) + let background = '' + Object.defineProperty(f.art.controls.thumbnails.style, 'backgroundImage', { + get: () => background, + set(value) { + background = value + f.art.thumbnails = { ...f.art.thumbnails, url: 'new.png' } + }, + }) + f.hover(0.2) + f.images[0].onload() + await flush() + assert.equal(background, 'url(first.png)') + assert.equal(f.art.controls.thumbnails.style.width, undefined) + assert.equal(f.art.thumbnails.url, 'new.png') +}) + +test('public loadImg preserves function name, arity, original image and no-scaling inputs', async (t) => { + const f = fixture(t) + assert.equal(loadImg.name, 'loadImg') + assert.equal(loadImg.length, 2) + for (const scale of [undefined, 0, 1, Number.NaN]) { + const pending = loadImg('direct.png', scale) + const image = f.images.at(-1) + image.onload() + assert.equal(await pending, image) + assert.equal(image.src, 'direct.png') + assert.equal(image.onload, null) + assert.equal(image.onerror, null) + } + assert.equal(f.callbacks.length, 0) +}) + +test('public scaled loadImg transfers a successfully decoded Blob URL without revoking it', async (t) => { + const f = fixture(t) + const pending = loadImg('public.png', 0.5) + f.images[0].onload() + assert.deepEqual([f.canvas.width, f.canvas.height], [500, 300]) + f.callbacks[0](new Blob(['image'])) + f.images[1].onload() + assert.equal(await pending, f.images[1]) + f.scope.dispose() + assert.deepEqual(f.revoked, []) + assert.equal(f.images[1].src, 'blob:thumbnail') +}) + +test('internal image cancellation settles undefined and detaches the image handlers', async (t) => { + const f = fixture(t) + const pending = loadThumbnailImage('cancel.png', 0.5, f.scope) + const image = f.images[0] + const staleLoad = image.onload + f.scope.dispose() + assert.equal(await pending, undefined) + assert.equal(image.onload, null) + assert.equal(image.onerror, null) + assert.equal(image.src, '') + staleLoad() + assert.equal(f.callbacks.length, 0) + assert.equal(await loadThumbnailImage('closed.png', 1, f.scope), undefined) + assert.equal(f.images.length, 1) +}) + +test('null encoding result rejects public image loading without a callback escape', async (t) => { + const f = fixture(t) + const pending = loadImg('empty.png', 0.5) + const rejected = assert.rejects(pending, /Unable to encode thumbnail image/) + f.images[0].onload() + assert.doesNotThrow(() => f.callbacks[0](null)) + await rejected + assert.equal(f.images.length, 1) +}) + +test('scaled image failure releases its Blob exactly once and preserves the original URL in errors', async (t) => { + const f = fixture(t) + const pending = loadThumbnailImage('failed.png', 0.5, f.scope) + const rejected = assert.rejects(pending, { message: 'Image load failed: failed.png' }) + f.images[0].onload() + f.callbacks[0](new Blob(['image'])) + f.images[1].onerror() + await rejected + assert.deepEqual(f.revoked, ['blob:thumbnail']) + f.scope.dispose() + assert.deepEqual(f.revoked, ['blob:thumbnail']) +}) + +test('image scaling preserves thrown draw errors and rejects a missing canvas context', async (t) => { + const f = fixture(t) + const failure = new Error('draw failed') + f.canvas.getContext = () => ({ + drawImage() { + throw failure + }, + }) + const first = loadImg('first.png', 0.5) + const rejected = assert.rejects(first, error => error === failure) + assert.doesNotThrow(() => f.images[0].onload()) + await rejected + f.canvas.getContext = () => null + const second = loadImg('second.png', 0.5) + const missing = assert.rejects(second, { name: 'TypeError', message: 'Canvas 2D context is unavailable' }) + assert.doesNotThrow(() => f.images[1].onload()) + await missing +}) + +test('destruction during object URL allocation revokes the URL without starting a scaled image', async (t) => { + const f = fixture(t) + t.mock.method(URL, 'createObjectURL', () => { + f.scope.dispose() + return 'blob:cancelled' + }) + const pending = loadThumbnailImage('cancel.png', 0.5, f.scope) + f.images[0].onload() + f.callbacks[0](new Blob(['image'])) + assert.equal(await pending, undefined) + assert.deepEqual(f.revoked, ['blob:cancelled']) + assert.equal(f.images.length, 1) +}) + +test('destruction inside the scaled image constructor does not start a late image request', async (t) => { + const f = fixture(t) + const ImageClass = globalThis.Image + Object.defineProperty(globalThis, 'Image', { configurable: true, value: class extends ImageClass { + constructor() { + super() + if (f.images.length === 2) + f.scope.dispose() + } + } }) + const pending = loadThumbnailImage('cancel.png', 0.5, f.scope) + f.images[0].onload() + f.callbacks[0](new Blob(['image'])) + assert.equal(await pending, undefined) + assert.deepEqual(f.revoked, ['blob:thumbnail']) + assert.equal(f.images[1].src, '') + assert.equal(f.images[1].onload, null) +}) diff --git a/test/types/screenshot.ts b/test/types/screenshot.ts new file mode 100644 index 000000000..8a3cba589 --- /dev/null +++ b/test/types/screenshot.ts @@ -0,0 +1,18 @@ +import type { CaptureMedia } from '../../packages/artplayer/src/capture/frame' +import type { ScreenshotHost } from '../../packages/artplayer/src/player/screenshotMix' +import type Artplayer from '../../packages/artplayer/types/artplayer' +import screenshotMix from '../../packages/artplayer/src/player/screenshotMix' + +declare const art: Artplayer +declare const host: ScreenshotHost +declare const video: HTMLVideoElement +const media: CaptureMedia = video +const data: Promise = art.getDataURL() +const blob: Promise = art.getBlobUrl() +const screenshot: Promise = art.screenshot('frame') +const installed: void = screenshotMix(host) +// @ts-expect-error Screenshot names remain strings. +art.screenshot(123) +// @ts-expect-error Captures return promises, not synchronous data URLs. +const sync: string = art.getDataURL() +export { blob, data, installed, media, screenshot, sync } diff --git a/test/types/thumbnails.ts b/test/types/thumbnails.ts new file mode 100644 index 000000000..87bfb07d4 --- /dev/null +++ b/test/types/thumbnails.ts @@ -0,0 +1,29 @@ +import type { ThumbnailsHost } from '../../packages/artplayer/src/player/thumbnailsMix' +import type { ThumbnailGeometry } from '../../packages/artplayer/src/thumbnails/layout' +import type Artplayer from '../../packages/artplayer/types/artplayer' +import type { Thumbnails } from '../../packages/artplayer/types/option' +import { loadImg, loadThumbnailImage } from '../../packages/artplayer/src/image/load' +import ResourceScope from '../../packages/artplayer/src/lifecycle/scope' +import thumbnailsMix from '../../packages/artplayer/src/player/thumbnailsMix' +import { thumbnailLayout } from '../../packages/artplayer/src/thumbnails/layout' + +declare const art: Artplayer +declare const host: ThumbnailsHost +declare const geometry: ThumbnailGeometry +const scope = new ResourceScope() +const installed: void = thumbnailsMix(host) +const option: Thumbnails = { url: 'sprite.png', column: 10, number: 100 } +art.thumbnails = option +const current: Thumbnails = art.thumbnails +const image: Promise = loadImg('sprite.png', 0.5) +const preview: Promise = loadThumbnailImage('sprite.png', 0.5, scope) +const layout = thumbnailLayout(option, geometry) +const width: string = layout.width +const left: number | string = layout.left +// @ts-expect-error Scale remains a number. +loadImg('sprite.png', 'half') +// @ts-expect-error Thumbnail configuration requires a URL. +art.thumbnails = { number: 100 } +// @ts-expect-error An owned request may be cancelled before producing an image. +const guaranteed: Promise = loadThumbnailImage('sprite.png', 1, scope) +export { current, guaranteed, image, installed, left, preview, width }