his,true);this.enterPossibleState();} gestureChanged(event) {} gestureEnded(event) {} enterPossibleState() {this.state=GestureRecognizer.States.Possible;} enterBeganState() {if(this.delegate&&typeof this.delegate.gestureRecognizerShouldBegin==="function"&&!this.delegate.gestureRecognizerShouldBegin(this)){this.enterFailedState();return;} this.state=GestureRecognizer.States.Began;} enterEndedState() {this.state=GestureRecognizer.States.Ended;this._removeTrackingListeners();this.reset();} enterCancelledState() {this.state=GestureRecognizer.States.Cancelled;this._removeTrackingListeners();this.reset();} enterFailedState() {this.state=GestureRecognizer.States.Failed;this._removeTrackingListeners();this.reset();} enterChangedState() {this.state=GestureRecognizer.States.Changed;} enterRecognizedState() {this.state=GestureRecognizer.States.Recognized;} handleEvent(event) {this._updateTargetTouches(event);this._updateKeyboardModifiers(event);switch(event.type){case GestureRecognizer.Events.PointerDown:this.touchesBegan(event);break;case GestureRecognizer.Events.PointerMove:this.touchesMoved(event);break;case GestureRecognizer.Events.PointerUp:this.touchesEnded(event);break;case GestureRecognizer.Events.PointerCancel:this.touchesCancelled(event);break;case GestureRecognizer.Events.GestureStart:this.gestureBegan(event);break;case GestureRecognizer.Events.GestureChange:this.gestureChanged(event);break;case GestureRecognizer.Events.GestureEnd:this.gestureEnded(event);break;}} _initRecognizer() {this.reset();this.state=GestureRecognizer.States.Possible;this._updateBaseListeners();} _updateBaseListeners() {if(!this._target) return;if(this._enabled){this._target.addEventListener(GestureRecognizer.Events.PointerDown,this);if(GestureRecognizer.SupportsGestures) this._target.addEventListener(GestureRecognizer.Events.GestureStart,this);}else{this._target.removeEventListener(GestureRecognizer.Events.PointerDown,this);if(GestureRecognizer.SupportsGestures) this._target.removeEventListener(GestureRecognizer.Events.GestureStart,this);}} get _captureTarget() {if(GestureRecognizer.SupportsTouches) return this._target;return window;} _removeTrackingListeners() {this._captureTarget.removeEventListener(GestureRecognizer.Events.PointerMove,this,true);this._captureTarget.removeEventListener(GestureRecognizer.Events.PointerUp,this,true);this._captureTarget.removeEventListener(GestureRecognizer.Events.PointerCancel,this,true);this._target.removeEventListener(GestureRecognizer.Events.GestureChange,this,true);this._target.removeEventListener(GestureRecognizer.Events.GestureEnd,this,true);this._targetPointers=new Map;} _updateTargetTouches(event) {if(!(event instanceof PointerEvent)) return;if(event.type===GestureRecognizer.Events.PointerDown){this._targetPointers.set(event.pointerId,event);return;} if(event.type===GestureRecognizer.Events.PointerMove){this._targetPointers.set(event.pointerId,event);return;} this._targetPointers.delete(event.pointerId);} _updateKeyboardModifiers(event) {this.modifierKeys.alt=event.altKey;this.modifierKeys.ctrl=event.ctrlKey;this.modifierKeys.meta=event.metaKey;this.modifierKeys.shift=event.shiftKey;}} GestureRecognizer.SupportsTouches="createTouch"in document;GestureRecognizer.SupportsGestures=!!window.GestureEvent;GestureRecognizer.States={Possible:"possible",Began:"began",Changed:"changed",Ended:"ended",Cancelled:"cancelled",Failed:"failed",Recognized:"ended"};GestureRecognizer.Events={PointerDown:"pointerdown",PointerMove:"pointermove",PointerUp:"pointerup",PointerCancel:"pointercancel",GestureStart:"gesturestart",GestureChange:"gesturechange",GestureEnd:"gestureend"};const MOVE_TOLERANCE=GestureRecognizer.SupportsTouches?40:0;const WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT=350;const WAITING_FOR_TAP_COMPLETION_TIMEOUT=750;class TapGestureRecognizer extends GestureRecognizer {constructor(target,delegate) {super(target,delegate);this.numberOfTapsRequired=1;this.numberOfTouchesRequired=1;this.allowsRightMouseButton=false;} touchesBegan(event) {if(event.currentTarget!==this.target) return;if(event.button===2&&!this.allowsRightMouseButton) return;super.touchesBegan(event);if(this.numberOfTouches!==this.numberOfTouchesRequired){this.enterFailedState();return;} this._startPoint=super.locationInElement();this._startClientPoint=super.locationInClient();this._rewindTimer(WAITING_FOR_TAP_COMPLETION_TIMEOUT);} touchesMoved(event) {const touchLocation=super.locationInElement();const distance=Math.sqrt(Math.pow(this._startPoint.x-touchLocation.x,2)+Math.pow(this._startPoint.y-touchLocation.y,2));if(distance>MOVE_TOLERANCE) this.enterFailedState();} touchesEnded(event) {this._taps++;if(this._taps===this.numberOfTapsRequired){ event.preventDefault();this.enterRecognizedState();this.reset();} this._rewindTimer(WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT);} reset() {this._taps=0;this._clearTimer();} locationInElement(element) {const p=this._startPoint||new DOMPoint;if(!element) return p;const wkPoint=window.webkitConvertPointFromPageToNode(element,new WebKitPoint(p.x,p.y));return new DOMPoint(wkPoint.x,wkPoint.y);} locationInClient() {return this._startClientPoint||new DOMPoint;} _clearTimer() {window.clearTimeout(this._timerId);delete this._timerId;} _rewindTimer(timeout) {this._clearTimer();this._timerId=window.setTimeout(this._timerFired.bind(this),timeout);} _timerFired() {this.enterFailedState();}} const MAXIMUM_TIME_FOR_RECORDING_GESTURES=100;const MAXIMUM_DECELERATION_TIME=500;class PinchGestureRecognizer extends GestureRecognizer {constructor(target,delegate) {super(target,delegate);this.scaleThreshold=0;this._scaledMinimumAmount=false;} get velocity() {const lastGesture=this._gestures[this._gestures.length-1];if(!lastGesture) return this._velocity;const elapsedTime=Date.now()-(lastGesture.timeStamp+MAXIMUM_TIME_FOR_RECORDING_GESTURES);if(elapsedTime<=0) return this._velocity;const f=Math.max((MAXIMUM_DECELERATION_TIME-elapsedTime)/MAXIMUM_DECELERATION_TIME,0);return this._velocity*f;} touchesBegan(event) {if(event.currentTarget!==this.target) return; if(!GestureRecognizer.SupportsGestures){ if(this.numberOfTouches>2){this.enterFailedState();return;} if(this.numberOfTouches!==2) return;this._startDistance=this._distance(); this._recordGesture(1);this._scaledMinimumAmount=false;this._updateStateWithEvent(event);}else if(this.numberOfTouches!==2){ return;} super.touchesBegan(event);} touchesMoved(event) { if(GestureRecognizer.SupportsGestures) return;if(this.numberOfTouches!==2) return;this._updateStateWithEvent(event);} touchesEnded(event) { if(GestureRecognizer.SupportsGestures) return; if(this.numberOfTouches>=2||!this._startDistance) return;if(this._scaledMinimumAmount) this.enterEndedState();else this.enterFailedState();} gestureBegan(event) {super.gestureBegan(event); this._recordGesture(event.scale);this._scaledMinimumAmount=false;this._updateStateWithEvent(event);event.preventDefault();} gestureChanged(event) {event.preventDefault();this._updateStateWithEvent(event);} gestureEnded(event) {if(this._scaledMinimumAmount) this.enterEndedState();else this.enterFailedState();} reset() {this.scale=1;this._velocity=0;this._gestures=[];delete this._startDistance;} _recordGesture(scale) {const currentTime=Date.now();const count=this._gestures.push({scale:scale,timeStamp:currentTime});if(count<=2) return;const scaleDirection=this._gestures[count-1].scale>=this._gestures[count-2].scale;let i=count-3;for(;i>=0;--i){let gesture=this._gestures[i];if(currentTime-gesture.timeStamp>MAXIMUM_TIME_FOR_RECORDING_GESTURES||this._gestures[i+1].scale>=gesture.scale!==scaleDirection) break;} if(i>0) this._gestures=this._gestures.slice(i+1);} _updateStateWithEvent(event) {const scaleSinceStart=GestureRecognizer.SupportsGestures?event.scale:this._distance()/this._startDistance;if(!this._scaledMinimumAmount){if(Math.abs(1-scaleSinceStart)>=this.scaleThreshold){this._scaledMinimumAmount=true;this.scale=1;this.enterBeganState();} return;} this._recordGesture(scaleSinceStart);const oldestGesture=this._gestures[0];const ds=scaleSinceStart-oldestGesture.scale;const dt=Date.now()-oldestGesture.timeStamp;this._velocity=(dt===0)?0:ds/dt*1000;this.scale*=scaleSinceStart/this._gestures[this._gestures.length-2].scale;this.enterChangedState();} _distance() {console.assert(this.numberOfTouches===2);const firstTouch=this._targetTouches[0];const firstTouchPoint=new DOMPoint(firstTouch.pageX,firstTouch.pageY);const secondTouch=this._targetTouches[1];const secondTouchPoint=new DOMPoint(secondTouch.pageX,secondTouch.pageY);return Math.sqrt(Math.pow(firstTouchPoint.x-secondTouchPoint.x,2)+Math.pow(firstTouchPoint.y-secondTouchPoint.y,2));}} const scheduler=new class {constructor() {this._frameID=-1;this._layoutCallbacks=new Set;} get hasScheduledLayoutCallbacks() {return this._frameID!==-1||this._layoutCallbacks.size>0;} scheduleLayout(callback) {if(typeof callback!=="function") return;this._layoutCallbacks.add(callback);this._requestFrameIfNeeded();} unscheduleLayout(callback) {if(typeof callback!=="function") return;this._layoutCallbacks.delete(callback);} flushScheduledLayoutCallbacks() {this._frameDidFire();} _requestFrameIfNeeded() {if(this._frameID===-1&&this._layoutCallbacks.size>0) this._frameID=window.requestAnimationFrame(this._frameDidFire.bind(this));} _frameDidFire() {if(typeof scheduler.frameWillFire==="function") scheduler.frameWillFire();this._layout();this._frameID=-1;this._requestFrameIfNeeded();if(typeof scheduler.frameDidFire==="function") scheduler.frameDidFire();} _layout() {const layoutCallbacks=this._layoutCallbacks;this._layoutCallbacks=new Set;for(let callback of layoutCallbacks) callback();}};class LayoutTraits {constructor(mode) {this.mode=mode} get isFullscreen() {return this.mode==LayoutTraits.Mode.Fullscreen;} mediaControlsClass() {throw"Derived class must implement this function.";} supportingObjectClasses() {return[AirplaySupport,AudioSupport,CloseSupport,ControlsVisibilitySupport,FullscreenSupport,MuteSupport,OverflowSupport,PiPSupport,PlacardSupport,PlaybackSupport,ScrubbingSupport,SeekBackwardSupport,SeekForwardSupport,SkipBackSupport,SkipForwardSupport,StartSupport,StatusSupport,TimeControlSupport,TracksSupport,VolumeSupport];} resourceDirectory() {throw"Derived class must implement this function.";} controlsNeverAvailable() {throw"Derived class must implement this function.";} supportsIconWithFullscreenVariant() {throw"Derived class must implement this function.";} supportsDurationTimeLabel() {throw"Derived class must implement this function.";} skipDuration() {throw"Derived class must implement this function.";} controlsDependOnPageScaleFactor() {throw"Derived class must implement this function.";} promoteSubMenusWhenShowingMediaControlsContextMenu() {throw"Derived class must implement this function.";} supportsTouches() {return GestureRecognizer.SupportsTouches;} supportsAirPlay() {throw"Derived class must implement this function.";} supportsPiP() {throw"Derived class must implement this function.";} inheritsBorderRadius() {throw"Derived class must implement this function.";}} LayoutTraits.Mode={Inline:0,Fullscreen:1};window.layoutTraitsClasses={};const dirtyNodes=new Set;const nodesRequiringChildrenUpdate=new Set;class LayoutNode {constructor(stringOrElement) {if(!stringOrElement) this.element=document.createElement("div");else if(stringOrElement instanceof Element) this.element=stringOrElement;else if(typeof stringOrElement==="string"||stringOrElement instanceof String) this.element=elementFromString(stringOrElement);this._parent=null;this._children=[];this._x=0;this._y=0;this._width=0;this._height=0;this._visible=true;this._needsLayout=false;this._dirtyProperties=new Set;this._pendingDOMManipulation=LayoutNode.DOMManipulation.None;} get x() {return this._x;} set x(x) {if(x===this._x) return;this._x=x;this.markDirtyProperty("x");} get y() {return this._y;} set y(y) {if(y===this._y) return;this._y=y;this.markDirtyProperty("y");} get width() {return this._width;} set width(width) {if(width===this._width) return;this._width=width;this.markDirtyProperty("width");this.layout();} get height() {return this._height;} set height(height) {if(height===this._height) return;this._height=height;this.markDirtyProperty("height");this.layout();} get visible() {return this._visible;} set visible(flag) {if(flag===this._visible) return;this._visible=flag;this.markDirtyProperty("visible");} get needsLayout() {return this._needsLayout||this._pendingDOMManipulation!==LayoutNode.DOMManipulation.None||this._dirtyProperties.size>0;} set needsLayout(flag) {if(this.needsLayout===flag) return;this._needsLayout=flag;this._updateDirtyState();} get parent() {return this._parent;} get children() {return this._children;} set children(children) {if(children.length===this._children.length){let arraysDiffer=false;for(let i=children.length-1;i>=0;--i){if(children[i]!==this._children[i]){arraysDiffer=true;break;}} if(!arraysDiffer) return;} this._updatingChildren=true;while(this._children.length) this.removeChild(this._children[0]);for(let child of children) this.addChild(child);delete this._updatingChildren;this.didChangeChildren();} parentOfType(type) {let node=this;while(node=node._parent){if(node instanceof type) return node;} return null;} addChild(child,index) {child.remove();if(index===undefined||index<0||index>this._children.length) index=this._children.length;this._children.splice(index,0,child);child._parent=this;if(!this._updatingChildren) this.didChangeChildren();child._markNodeManipulation(LayoutNode.DOMManipulation.Addition);return child;} insertBefore(newSibling,referenceSibling) {return this.addChild(newSibling,this._children.indexOf(referenceSibling));} insertAfter(newSibling,referenceSibling) {const index=this._children.indexOf(referenceSibling);return this.addChild(newSibling,index+1);} removeChild(child) {if(child._parent!==this) return;const index=this._children.indexOf(child);if(index===-1) return;this.willRemoveChild(child);this._children.splice(index,1);child._parent=null;if(!this._updatingChildren) this.didChangeChildren();child._markNodeManipulation(LayoutNode.DOMManipulation.Removal);return child;} remove() {if(this._parent instanceof LayoutNode) return this._parent.removeChild(this);} markDirtyProperty(propertyName) {const hadProperty=this._dirtyProperties.has(propertyName);this._dirtyProperties.add(propertyName);if(!hadProperty) this._updateDirtyState();} computedValueForStyleProperty(propertyName) {return window.getComputedStyle(this.element).getPropertyValue(propertyName);} computedValueForStylePropertyInPx(propertyName) {const value=this.computedValueForStyleProperty(propertyName);if(!value) return 0;if(!value.endsWith("px")) return 0;return parseFloat(value);} layout() {} commit() {if(this._pendingDOMManipulation===LayoutNode.DOMManipulation.Removal){const parent=this.element.parentNode;if(parent) parent.removeChild(this.element);} for(let propertyName of this._dirtyProperties) this.commitProperty(propertyName);this._dirtyProperties.clear();if(this._pendingDOMManipulation===LayoutNode.DOMManipulation.Addition) nodesRequiringChildrenUpdate.add(this.parent);} commitProperty(propertyName) {const style=this.element.style;switch(propertyName){case"x":style.left=`${this._x}px`;break;case"y":style.top=`${this._y}px`;break;case"width":style.width=`${this._width}px`;break;case"height":style.height=`${this._height}px`;break;case"visible":if(this._visible) style.removeProperty("display");else style.display="none";break;}} willRemoveChild(child) {} didChangeChildren() {} _markNodeManipulation(manipulation) {this._pendingDOMManipulation=manipulation;this._updateDirtyState();} _updateDirtyState() {if(this.needsLayout){dirtyNodes.add(this);scheduler.scheduleLayout(performScheduledLayout);}else{dirtyNodes.delete(this);if(dirtyNodes.size===0) scheduler.unscheduleLayout(performScheduledLayout);}} _updateChildren() {let nextChildElement=null;const element=this.element;for(let i=this.children.length-1;i>=0;--i){let child=this.children[i];let childElement=child.element;if(child._pendingDOMManipulation===LayoutNode.DOMManipulation.Addition){element.insertBefore(childElement,nextChildElement);child._pendingDOMManipulation=LayoutNode.DOMManipulation.None;} nextChildElement=childElement;}}} LayoutNode.DOMManipulation={None:0,Removal:1,Addition:2};function performScheduledLayout() {const previousDirtyNodes=Array.from(dirtyNodes);dirtyNodes.clear();previousDirtyNodes.forEach(node=>{node._needsLayout=false;node.layout();node.commit();});nodesRequiringChildrenUpdate.forEach(node=>node._updateChildren());nodesRequiringChildrenUpdate.clear();} function elementFromString(elementString) {const element=document.createElement("div");element.innerHTML=elementString;return element.firstElementChild;} class LayoutItem extends LayoutNode {constructor({element=null,layoutDelegate=null}={}) {super(element);this.layoutDelegate=layoutDelegate;} get layoutTraits() {if(!this.layoutDelegate?.layoutTraits) throw"No layout traits specified via layoutDelegate or overriden layouTraits() getter";return this.layoutDelegate.layoutTraits;}} const Icons={Airplay:{name:"Airplay",type:"svg",label:UIString("AirPlay")},AirplayPlacard:{name:"airplay-placard",type:"png",label:UIString("AirPlay")},Close:{name:"X",type:"svg",label:UIString("Close")},Ellipsis:{name:"Ellipsis",type:"svg",label:UIString("More\u2026")},EnterFullscreen:{name:"EnterFullscreen",type:"svg",label:UIString("Enter Full Screen")},EnterPiP:{name:"PipIn",type:"svg",label:UIString("Enter Picture in Picture")},ExitFullscreen:{name:"ExitFullscreen",type:"svg",label:UIString("Exit Full Screen")},Forward:{name:"Forward",type:"svg",label:UIString("Forward")},InvalidCircle:{name:"InvalidCircle",type:"pdf",label:UIString("Invalid")},InvalidPlacard:{name:"invalid-placard",type:"png",label:UIString("Invalid")},Overflow:{name:"Overflow",type:"svg",label:UIString("More\u2026")},Pause:{name:"Pause",type:"svg",label:UIString("Pause")},PiPPlacard:{name:"pip-placard",type:"png",label:UIString("Picture in Picture")},Play:{name:"Play",type:"svg",label:UIString("Play")},PlayCircle:{name:"PlayCircle",type:"pdf",label:UIString("Play")},Rewind:{name:"Rewind",type:"svg",label:UIString("Rewind")},SkipBack10:{name:"SkipBack10",type:"svg",label:UIString("Skip Back 10 Seconds")},SkipBack15:{name:"SkipBack15",type:"svg",label:UIString("Skip Back 15 Seconds")},SkipForward10:{name:"SkipForward10",type:"svg",label:UIString("Skip Forward 10 Seconds")},SkipForward15:{name:"SkipForward15",type:"svg",label:UIString("Skip Forward 15 Seconds")},SpinnerSprite:{name:"SpinnerSprite",type:"png",label:UIString("Loading\u2026")},Tracks:{name:"MediaSelector",type:"svg",label:UIString("Media Selection")},Volume0:{name:"Volume0",type:"svg",label:UIString("Mute")},Volume0RTL:{name:"Volume0-RTL",type:"svg",label:UIString("Mute")},Volume1:{name:"Volume1",type:"svg",label:UIString("Mute")},Volume1RTL:{name:"Volume1-RTL",type:"svg",label:UIString("Mute")},Volume2:{name:"Volume2",type:"svg",label:UIString("Mute")},Volume2RTL:{name:"Volume2-RTL",type:"svg",label:UIString("Mute")},Volume3:{name:"Volume3",type:"svg",label:UIString("Mute")},Volume3RTL:{name:"Volume3-RTL",type:"svg",label:UIString("Mute")},VolumeMuted:{name:"VolumeMuted",type:"svg",label:UIString("Unmute")},VolumeMutedRTL:{name:"VolumeMuted-RTL",type:"svg",label:UIString("Unmute")},};const MimeTypes={"pdf":"application/pdf","png":"image/png","svg":"image/svg+xml"};const IconsWithFullscreenVariants=[Icons.Airplay,Icons.Tracks,Icons.EnterPiP];const iconService=new class IconService{constructor() {this.images={};} get shadowRoot() {return this.shadowRootWeakRef?this.shadowRootWeakRef.deref():null;} set shadowRoot(shadowRoot) {this.shadowRootWeakRef=new WeakRef(shadowRoot);} imageForIconAndLayoutTraits(icon,layoutTraits) {const[fileName,resourceDirectory]=this._fileNameAndResourceDirectoryForIconAndLayoutTraits(icon,layoutTraits);const path=`${resourceDirectory}/${fileName}.${icon.type}`;let image=this.images[path];if(image) return image;image=this.images[path]=new Image;image.style.display="none";this.shadowRoot?.appendChild(image);if(this.mediaControlsHost) image.src=`data:${MimeTypes[icon.type]};base64,${this.mediaControlsHost.base64StringForIconNameAndType(fileName, icon.type)}`;else image.src=`${this.directoryPath}/${path}`;image.remove();return image;} _fileNameAndResourceDirectoryForIconAndLayoutTraits(icon,layoutTraits) {let resourceDirectory=layoutTraits.resourceDirectory();let iconName=icon.name;if(layoutTraits.supportsIconWithFullscreenVariant()&&IconsWithFullscreenVariants.includes(icon)) iconName+="-fullscreen";let fileName=iconName;if(icon.type==="png") fileName=`${iconName}@${window.devicePixelRatio}x`;return[fileName,resourceDirectory];}};class BackgroundTint extends LayoutNode {constructor() {super(`
`);}} const TenMinutes=10*60;const OneHour=6*TenMinutes;const TenHours=10*OneHour;const MinimumScrubberWidth=120;const ScrubberMargin=5;class TimeControl extends LayoutItem {constructor(layoutDelegate) {super({element:`
`,layoutDelegate});this._timeLabelsAttachment=TimeControl.TimeLabelsAttachment.Side;this._shouldShowDurationTimeLabel=this.layoutTraits.supportsDurationTimeLabel();this.elapsedTimeLabel=new TimeLabel(TimeLabel.Type.Elapsed);this.scrubber=new Slider(this.layoutDelegate,"scrubber");if(this._shouldShowDurationTimeLabel) this.durationTimeLabel=new TimeLabel(TimeLabel.Type.Duration);this.remainingTimeLabel=new TimeLabel(TimeLabel.Type.Remaining);this.activityIndicator=new LayoutNode(`
`);this.activityIndicator.width=14;this.activityIndicator.height=14;for(let segmentClassName of["n","ne","e","se","s","sw","w","nw"]) this.activityIndicator.element.appendChild(document.createElement("div")).className=segmentClassName;this._duration=0;this._currentTime=0;this._loading=false;this._supportsSeeking=true;if(this._shouldShowDurationTimeLabel){this.durationTimeLabel.element.addEventListener("click",this);this.remainingTimeLabel.element.addEventListener("click",this);}} set duration(duration) {if(this._duration===duration) return;this._duration=duration;this.needsLayout=true;} set currentTime(currentTime) {if(this._currentTime===currentTime) return;this._currentTime=currentTime;this.needsLayout=true;} get loading() {return this._loading;} set loading(flag) {if(this._loading===flag) return;this._loading=flag;this.scrubber.disabled=this._loading||!this._supportsSeeking;this.needsLayout=true;} get supportsSeeking() {return this._supportsSeeking;} set supportsSeeking(flag) {if(this._supportsSeeking===flag) return;this._supportsSeeking=flag;this.scrubber.disabled=this._loading||!this._supportsSeeking;this.needsLayout=true;} get minimumWidth() {this._performIdealLayout();if(this._timeLabelsDisplayOnScrubberSide){const scrubberMargin=this.computedValueForStylePropertyInPx("--scrubber-margin");return MinimumScrubberWidth+scrubberMargin+this._durationOrRemainingTimeLabel().width;} return MinimumScrubberWidth;} get idealMinimumWidth() {this._performIdealLayout();if(this._timeLabelsDisplayOnScrubberSide){const scrubberMargin=this.computedValueForStylePropertyInPx("--scrubber-margin");return this.elapsedTimeLabel.width+MinimumScrubberWidth+(2*scrubberMargin)+this._durationOrRemainingTimeLabel().width;} return MinimumScrubberWidth;} get timeLabelsAttachment() {return this._timeLabelsAttachment;} set timeLabelsAttachment(attachment) {if(this._timeLabelsAttachment==attachment) return;this._timeLabelsAttachment=attachment;this.needsLayout=true;} layout() {super.layout();this._performIdealLayout();if(this._loading||!this._timeLabelsDisplayOnScrubberSide) return;if(this.scrubber.width>=MinimumScrubberWidth){this.elapsedTimeLabel.visible=true;return;} let durationOrRemainingTimeLabel=this._durationOrRemainingTimeLabel(); this.scrubber.x=0;const scrubberMargin=this.computedValueForStylePropertyInPx("--scrubber-margin");this.scrubber.width=this.width-scrubberMargin-durationOrRemainingTimeLabel.width;durationOrRemainingTimeLabel.x=this.scrubber.x+this.scrubber.width+scrubberMargin;this.elapsedTimeLabel.visible=false;} handleEvent(event) {switch(event.type){case"click":switch(event.target){case this.durationTimeLabel.element:this._shouldShowDurationTimeLabel=false;this.needsLayout=true;break;case this.remainingTimeLabel.element:if(this._canShowDurationTimeLabel){this._shouldShowDurationTimeLabel=true;this.needsLayout=true;} break;}}} get _timeLabelsDisplayOnScrubberSide() {return this._timeLabelsAttachment==TimeControl.TimeLabelsAttachment.Side;} get _canShowDurationTimeLabel() {return this.elapsedTimeLabel.visible;} _durationOrRemainingTimeLabel() {return(this._canShowDurationTimeLabel&&this._shouldShowDurationTimeLabel)?this.durationTimeLabel:this.remainingTimeLabel;} _performIdealLayout() {if(this._loading) this._durationOrRemainingTimeLabel().setValueWithNumberOfDigits(NaN,4);else{const shouldShowZeroDurations=isNaN(this._duration)||this._duration>maxNonLiveDuration;let numberOfDigitsForTimeLabels;if(this._duration{if(this._loading) return this.activityIndicator.width+scrubberMargin;if(this._timeLabelsDisplayOnScrubberSide) return this.elapsedTimeLabel.width+scrubberMargin;return 0;})();this.scrubber.width=(()=>{if(this._timeLabelsDisplayOnScrubberSide) return this.width-this.scrubber.x-scrubberMargin-durationOrRemainingTimeLabel.width;return this.width;})();if(this._timeLabelsAttachment==TimeControl.TimeLabelsAttachment.Below) this.elapsedTimeLabel.y=this.scrubber.height;durationOrRemainingTimeLabel.x=(()=>{if(this._timeLabelsDisplayOnScrubberSide) return this.scrubber.x+this.scrubber.width+scrubberMargin;return this.width-durationOrRemainingTimeLabel.width;})();if(this._timeLabelsAttachment==TimeControl.TimeLabelsAttachment.Below) durationOrRemainingTimeLabel.y=this.scrubber.height;this.children=[this._loading?this.activityIndicator:this.elapsedTimeLabel,this.scrubber,durationOrRemainingTimeLabel];} updateScrubberLabel() {this.scrubber.inputAccessibleLabel=this.elapsedTimeLabel.value;}} TimeControl.TimeLabelsAttachment={Above:1<<0,Side:1<<1,Below:1<<2};const MinusSignWidthsForDigits={3:6,4:5,5:6,6:5};const WidthsForDigits={3:27,4:35,5:46,6:54} class TimeLabel extends LayoutNode {constructor(type) {super(`
`);this._type=type;this.setValueWithNumberOfDigits(0,4);switch(this._type){case TimeLabel.Type.Elapsed:this.element.setAttribute("id","time-label-elapsed");break;case TimeLabel.Type.Remaining:this.element.setAttribute("id","time-label-remaining");break;case TimeLabel.Type.Duration:this.element.setAttribute("id","time-label-duration");break;}} get value() {return this._value;} setValueWithNumberOfDigits(value,numberOfDigits) {this._value=value;this._numberOfDigits=numberOfDigits;this.width=WidthsForDigits[this._numberOfDigits]+(this._type===TimeLabel.Type.Remaining&&!isNaN(this._value)?MinusSignWidthsForDigits[this._numberOfDigits]:0);this.markDirtyProperty("value");} commitProperty(propertyName) {if(propertyName==="value"){this.element.textContent=this._formattedTime();const timeAsString=formattedStringForDuration(this.value);switch(this._type){case TimeLabel.Type.Elapsed:this.element.setAttribute("aria-label",UIString("Elapsed: %s",timeAsString));break;case TimeLabel.Type.Remaining:this.element.setAttribute("aria-label",UIString("Remaining: %s",timeAsString));break;case TimeLabel.Type.Duration:this.element.setAttribute("aria-label",UIString("Duration: %s",timeAsString));break;} if(this.parent instanceof TimeControl) this.parent.updateScrubberLabel();} else super.commitProperty(propertyName);} _formattedTime() {if(isNaN(this._value)) return"--:--";const time=formatTimeByUnit(this._value);let timeComponents;if(this._numberOfDigits==3) timeComponents=[time.minutes,doubleDigits(time.seconds)];else if(this._numberOfDigits==4) timeComponents=[doubleDigits(time.minutes),doubleDigits(time.seconds)];else if(this._numberOfDigits==5) timeComponents=[time.hours,doubleDigits(time.minutes),doubleDigits(time.seconds)];else if(this._numberOfDigits==6) timeComponents=[doubleDigits(time.hours),doubleDigits(time.minutes),doubleDigits(time.seconds)];return(this._type===TimeLabel.Type.Remaining?"-":"")+timeComponents.join(":");}} function doubleDigits(x) {if(x<10) return`0${x}`;return`${x}`;} TimeLabel.Type={Elapsed:0,Remaining:1,Duration:2,};class SliderBase extends LayoutNode {constructor(layoutDelegate,cssClassName="") {super(`
`);console.assert(this.constructor!==SliderBase&&this instanceof SliderBase,this);this._layoutDelegate=layoutDelegate;this.appearanceContainer=new LayoutNode(`
`);this._input=new LayoutNode(``);this._input.element.addEventListener("pointerdown",this);this._input.element.addEventListener("input",this);this._input.element.addEventListener("change",this);this.value=0;this.enabled=true;this.isActive=false;this._disabled=false;this._secondaryValue=0;this._allowsRelativeScrubbing=false;this._startValue=NaN;this._startPosition=NaN;this.children=[this.appearanceContainer,this._input];} set inputAccessibleLabel(timeValue) {this._input.element.setAttribute("aria-valuetext",formattedStringForDuration(timeValue));} get disabled() {return this._disabled;} set disabled(flag) {if(this._disabled===flag) return;this._disabled=flag;this.markDirtyProperty("disabled");} get value() {if(this._value!==undefined) return this._value;return parseFloat(this._input.element.value);} set value(value) {if(this._animatedValue) delete this._animatedValue;this._setValueInternal(value);} setValueAnimated(value) {if(this.isActive||this._value==value) return;this._valueAnimation={start:this.value,end:value,startTime:window.performance.now()};const duration=150;const animate=currentTime=>{if(!this._valueAnimation) return;const elapsedTime=currentTime-this._valueAnimation.startTime;const progress=Math.min(elapsedTime/duration,1);const animatedValue=this._valueAnimation.start+(this._valueAnimation.end-this._valueAnimation.start)*progress;this._setValueInternal(animatedValue);if(progress==1) delete this._valueAnimation;else requestAnimationFrame(animate);};requestAnimationFrame(animate);} _setValueInternal(value) {if(this.isActive||this._value==value) return;this._value=value;this.markDirtyProperty("value");this.needsLayout=true;} get secondaryValue() {return this._secondaryValue;} set secondaryValue(secondaryValue) {if(this._secondaryValue===secondaryValue) return;this._secondaryValue=secondaryValue;this.needsLayout=true;} get allowsRelativeScrubbing() {return this._allowsRelativeScrubbing;} set allowsRelativeScrubbing(allowsRelativeScrubbing) {this._allowsRelativeScrubbing=!!allowsRelativeScrubbing;this.element.classList.toggle("allows-relative-scrubbing",this._allowsRelativeScrubbing);} handleEvent(event) {switch(event.type){case"pointerdown":this._handlePointerdownEvent(event);return;case"pointermove":this._handlePointermoveEvent(event);return;case"pointerup":this._handlePointerupEvent(event);return;case"change":case"input":this._valueDidChange();return;}} commitProperty(propertyName) {switch(propertyName){case"value":this._input.element.value=this._value;delete this._value;break;case"disabled":this.element.classList.toggle("disabled",this._disabled);break;default:super.commitProperty(propertyName);break;}} _handlePointerdownEvent(event) {delete this._valueAnimation;this._pointerupTarget=this._interactionEndTarget();this._pointerupTarget.addEventListener("pointerup",this,{capture:true});if(this._allowsRelativeScrubbing) this._pointerupTarget.addEventListener("pointermove",this,{capture:true});delete this._value;if(this._allowsRelativeScrubbing){this._startValue=parseFloat(this._input.element.value);this._startPosition=this._playbackProgress(event.pageX);} if(this.uiDelegate&&typeof this.uiDelegate.controlValueWillStartChanging==="function") this.uiDelegate.controlValueWillStartChanging(this);this.isActive=true;this.appearanceContainer.element.classList.add("changing");this.needsLayout=true;} _interactionEndTarget() {const mediaControls=this.parentOfType(MediaControls);if(mediaControls?.layoutTraits.supportsTouches()) return mediaControls.element;return(!mediaControls||!mediaControls.layoutTraits.isFullscreen)?window:mediaControls.element;} _valueDidChange() {if(this.uiDelegate&&typeof this.uiDelegate.controlValueDidChange==="function") this.uiDelegate.controlValueDidChange(this);this.needsLayout=true;} _handlePointermoveEvent(event) {if(!this._allowsRelativeScrubbing||isNaN(this._startValue)||isNaN(this._startPosition)) return;let value=this._startValue+this._playbackProgress(event.pageX)-this._startPosition;this._input.element.value=Math.min(Math.max(0,value),1);this._valueDidChange();} _handlePointerupEvent(event) {this._pointerupTarget.removeEventListener("pointerup",this,{capture:true});this._pointerupTarget.removeEventListener("pointermove",this,{capture:true});delete this._pointerupTarget;this._startValue=NaN;this._startPosition=NaN;this.isActive=false;this.appearanceContainer.element.classList.remove("changing");if(this.uiDelegate&&typeof this.uiDelegate.controlValueDidStopChanging==="function") this.uiDelegate.controlValueDidStopChanging(this);this.needsLayout=true;} _playbackProgress(pageX) {let x=window.webkitConvertPointFromPageToNode(this.element,new WebKitPoint(pageX,0)).x;if(this._layoutDelegate?.scaleFactor) x*=this._layoutDelegate.scaleFactor;return x/this.element.clientWidth;}} class Slider extends SliderBase {constructor(layoutDelegate,cssClassName="",knobStyle=Slider.KnobStyle.Circle) {super(layoutDelegate,`default ${cssClassName}`);this._primaryFill=new LayoutNode(`
`);this._trackFill=new LayoutNode(`
`);this._secondaryFill=new LayoutNode(`
`);let fillContainer=new LayoutNode(`
`);fillContainer.children=[this._primaryFill,this._trackFill,this._secondaryFill];this._knob=new LayoutNode(`
`);this.appearanceContainer.children=[fillContainer,this._knob];this.height=16;this._knobStyle=knobStyle;} get knobStyle() {return this._knobStyle;} set knobStyle(knobStyle) {if(this._knobStyle===knobStyle) return;this._knob.element.classList.remove(this._knobStyle);this._knobStyle=knobStyle;this._knob.element.classList.add(this._knobStyle);this.needsLayout=true;} commit() {super.commit();const scrubberWidth=(style=>{switch(style){case Slider.KnobStyle.Bar:return 4;case Slider.KnobStyle.Circle:return 9;case Slider.KnobStyle.None:return 0;} console.error("Unknown Slider.KnobStyle");return 0;})(this._knobStyle);const scrubberBorder=(style=>{switch(style){case Slider.KnobStyle.Bar:return 1;case Slider.KnobStyle.Circle:return(-1*scrubberWidth/2);case Slider.KnobStyle.None:return 0;} console.error("Unknown Slider.KnobStyle");return 0;})(this._knobStyle);const scrubberCenterX=(scrubberWidth/2)+Math.round((this.width-scrubberWidth)*this.value);this._primaryFill.element.style.width=`${scrubberCenterX - (scrubberWidth / 2) - scrubberBorder}px`;this._trackFill.element.style.left=`${scrubberCenterX + (scrubberWidth / 2) + scrubberBorder}px`;this._secondaryFill.element.style.left=`${scrubberCenterX + (scrubberWidth / 2) + scrubberBorder}px`;this._secondaryFill.element.style.right=`${(1 - this.secondaryValue) * 100}%`;this._knob.element.style.left=`${scrubberCenterX}px`;}} Slider.KnobStyle={Circle:"circle",Bar:"bar",None:"none",};class Button extends LayoutItem {constructor({layoutDelegate=null,cssClassName="",iconName=""}={}) {super({element:"