@obipascal/player 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,7 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
5
5
  ## ✨ Features
6
6
 
7
7
  ### Core Playback
8
+
8
9
  - 🎬 **HLS Streaming**: Full HLS.js support with adaptive bitrate streaming
9
10
  - 🔒 **CloudFront Integration**: Native support for CloudFront signed cookies and S3-hosted videos
10
11
  - 🎯 **Skip Controls**: 10-second forward/backward skip with circular arrow buttons
@@ -13,11 +14,13 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
13
14
  - 🎛️ **Playback Rate**: Adjustable speed (0.5x - 2x)
14
15
 
15
16
  ### Subtitle & Accessibility
17
+
16
18
  - 📝 **Subtitle Support**: Full subtitle/caption support with programmatic API
17
19
  - 🌐 **Multi-language**: Support for multiple subtitle tracks with language selection
18
20
  - ♿ **Accessibility**: WCAG compliant with keyboard navigation
19
21
 
20
22
  ### UI & Controls
23
+
21
24
  - 🎨 **Modern UI Design**: Beautiful controls with blur effects, gradients, and smooth animations
22
25
  - 🖱️ **Smart Controls**: Auto-hide on inactivity, fade on hover
23
26
  - 📍 **Sticky Controls**: Optional persistent controls (toggle in settings)
@@ -27,6 +30,7 @@ A modern, feature-rich HLS video player SDK for educational platforms with Cloud
27
30
  - 🎨 **Custom Theming**: Full CSS variable theming with 8 customizable properties
28
31
 
29
32
  ### Developer Experience
33
+
30
34
  - ⚛️ **React Support**: Component, Hook, and Context Provider patterns
31
35
  - 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
32
36
  - 📊 **Analytics & QoE**: Built-in analytics tracking and Quality of Experience metrics
@@ -98,7 +102,7 @@ yarn add @obipascal/player hls.js
98
102
  player.on("timeupdate", (event) => {
99
103
  console.log("Current time:", event.data.currentTime)
100
104
  })
101
-
105
+
102
106
  // Programmatic subtitle control
103
107
  player.enableSubtitles(0) // Enable first subtitle track
104
108
  player.toggleSubtitles() // Toggle subtitles on/off
@@ -213,43 +217,165 @@ function ControlPanel() {
213
217
 
214
218
  ## 🔒 CloudFront & S3 Integration
215
219
 
216
- ### CloudFront with Signed Cookies (Recommended)
220
+ This player supports **three video hosting scenarios**. Choose the one that fits your needs:
221
+
222
+ ### Scenario 1: Public Videos (Easiest - No Authentication Required)
223
+
224
+ **When to use:** Your videos are publicly accessible and don't require user authentication.
217
225
 
218
- For secure video delivery, use CloudFront with signed cookies:
226
+ **Setup:** Just provide the video URL!
219
227
 
220
228
  ```typescript
221
229
  import { WontumPlayer } from "@obipascal/player"
222
230
 
223
- // Your backend sets signed cookies for CloudFront
224
- // Cookie names: CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id
225
-
226
231
  const player = new WontumPlayer({
227
- src: "https://media.yourdomain.com/video/playlist.m3u8",
232
+ src: "https://d1234567890.cloudfront.net/video/playlist.m3u8",
228
233
  container: "#player",
229
- s3Config: {
230
- cloudfront: {
231
- domain: "media.yourdomain.com",
232
- // Cookies are automatically sent by browser
233
- },
234
- },
235
234
  })
236
235
  ```
237
236
 
238
- ### CloudFront Signed Cookie Setup (Backend)
237
+ **That's it!** No backend needed. Works for public S3 buckets or CloudFront distributions.
238
+
239
+ ---
240
+
241
+ ### Scenario 2: Private Videos with CloudFront Signed Cookies (Recommended)
242
+
243
+ **When to use:** You want to restrict video access to authorized users (e.g., paid courses, premium content).
244
+
245
+ **How it works:**
246
+
247
+ 1. User logs into your app
248
+ 2. Your backend verifies the user and sets CloudFront signed cookies
249
+ 3. Player automatically sends these cookies with every video request
250
+ 4. CloudFront checks the cookies and allows/denies access
251
+
252
+ **Frontend Setup:**
253
+
254
+ ```typescript
255
+ import { WontumPlayer } from "@obipascal/player"
256
+
257
+ // STEP 1: Call your backend to set signed cookies BEFORE creating the player
258
+ async function initializePlayer() {
259
+ // This endpoint sets CloudFront cookies in the browser
260
+ await fetch("/api/auth/video-access", {
261
+ credentials: "include", // Important: include cookies
262
+ })
263
+
264
+ // STEP 2: Create player - it will automatically use the cookies
265
+ const player = new WontumPlayer({
266
+ src: "https://media.yourdomain.com/videos/lesson-1/playlist.m3u8",
267
+ container: "#player",
268
+ s3Config: {
269
+ cloudFrontDomains: ["media.yourdomain.com"], // Your CloudFront domain
270
+ signUrl: async (url) => {
271
+ // This function is called when player needs to access a video
272
+ // Call your backend to refresh/set cookies if needed
273
+ const response = await fetch("/api/auth/sign-url", {
274
+ method: "POST",
275
+ headers: { "Content-Type": "application/json" },
276
+ credentials: "include",
277
+ body: JSON.stringify({ url }),
278
+ })
279
+
280
+ if (!response.ok) {
281
+ throw new Error("Failed to authenticate video access")
282
+ }
283
+
284
+ // Backend sets cookies, return the URL
285
+ return url
286
+ },
287
+ },
288
+ })
289
+ }
290
+
291
+ initializePlayer()
292
+ ```
293
+
294
+ **Backend Setup (Node.js/Express):**
239
295
 
240
296
  ```typescript
241
- // Node.js backend example
242
- import { CloudFrontClient } from "@aws-sdk/client-cloudfront"
297
+ import express from "express"
243
298
  import { getSignedCookies } from "@aws-sdk/cloudfront-signer"
299
+ import fs from "fs"
300
+
301
+ const app = express()
302
+
303
+ // STEP 1: Create endpoint that sets CloudFront signed cookies
304
+ app.get("/api/auth/video-access", (req, res) => {
305
+ // Check if user is logged in (your authentication logic)
306
+ if (!req.user) {
307
+ return res.status(401).json({ error: "Not authenticated" })
308
+ }
244
309
 
245
- app.get("/api/video-auth", async (req, res) => {
310
+ // Define what resources user can access
311
+ const policy = {
312
+ Statement: [
313
+ {
314
+ Resource: "https://media.yourdomain.com/*", // All videos on this domain
315
+ Condition: {
316
+ DateLessThan: {
317
+ "AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour
318
+ },
319
+ },
320
+ },
321
+ ],
322
+ }
323
+
324
+ // Generate CloudFront signed cookies
325
+ const cookies = getSignedCookies({
326
+ keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID!, // Your CloudFront key pair ID
327
+ privateKey: fs.readFileSync("./cloudfront-private-key.pem", "utf8"), // Your private key
328
+ policy: JSON.stringify(policy),
329
+ })
330
+
331
+ // Set the three required cookies
332
+ res.cookie("CloudFront-Policy", cookies["CloudFront-Policy"], {
333
+ domain: ".yourdomain.com", // Use your domain
334
+ path: "/",
335
+ secure: true, // HTTPS only
336
+ httpOnly: true, // Prevent JavaScript access
337
+ sameSite: "none",
338
+ })
339
+
340
+ res.cookie("CloudFront-Signature", cookies["CloudFront-Signature"], {
341
+ domain: ".yourdomain.com",
342
+ path: "/",
343
+ secure: true,
344
+ httpOnly: true,
345
+ sameSite: "none",
346
+ })
347
+
348
+ res.cookie("CloudFront-Key-Pair-Id", cookies["CloudFront-Key-Pair-Id"], {
349
+ domain: ".yourdomain.com",
350
+ path: "/",
351
+ secure: true,
352
+ httpOnly: true,
353
+ sameSite: "none",
354
+ })
355
+
356
+ res.json({ success: true })
357
+ })
358
+
359
+ // STEP 2: Optional endpoint for on-demand signing (called by signUrl function)
360
+ app.post("/api/auth/sign-url", (req, res) => {
361
+ const { url } = req.body
362
+
363
+ // Verify user is authorized
364
+ if (!req.user) {
365
+ return res.status(401).json({ error: "Not authenticated" })
366
+ }
367
+
368
+ // You can add additional authorization logic here
369
+ // For example, check if user has access to this specific video
370
+
371
+ // Refresh cookies (same code as above)
246
372
  const policy = {
247
373
  Statement: [
248
374
  {
249
375
  Resource: "https://media.yourdomain.com/*",
250
376
  Condition: {
251
377
  DateLessThan: {
252
- "AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600, // 1 hour
378
+ "AWS:EpochTime": Math.floor(Date.now() / 1000) + 3600,
253
379
  },
254
380
  },
255
381
  },
@@ -257,43 +383,142 @@ app.get("/api/video-auth", async (req, res) => {
257
383
  }
258
384
 
259
385
  const cookies = getSignedCookies({
260
- keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID,
261
- privateKey: process.env.CLOUDFRONT_PRIVATE_KEY,
386
+ keyPairId: process.env.CLOUDFRONT_KEY_PAIR_ID!,
387
+ privateKey: fs.readFileSync("./cloudfront-private-key.pem", "utf8"),
262
388
  policy: JSON.stringify(policy),
263
389
  })
264
390
 
265
- // Set cookies
266
391
  res.cookie("CloudFront-Policy", cookies["CloudFront-Policy"], {
267
392
  domain: ".yourdomain.com",
393
+ path: "/",
268
394
  secure: true,
269
395
  httpOnly: true,
396
+ sameSite: "none",
270
397
  })
398
+
271
399
  res.cookie("CloudFront-Signature", cookies["CloudFront-Signature"], {
272
400
  domain: ".yourdomain.com",
401
+ path: "/",
273
402
  secure: true,
274
403
  httpOnly: true,
404
+ sameSite: "none",
275
405
  })
406
+
276
407
  res.cookie("CloudFront-Key-Pair-Id", cookies["CloudFront-Key-Pair-Id"], {
277
408
  domain: ".yourdomain.com",
409
+ path: "/",
278
410
  secure: true,
279
411
  httpOnly: true,
412
+ sameSite: "none",
280
413
  })
281
414
 
282
415
  res.json({ success: true })
283
416
  })
284
417
  ```
285
418
 
286
- ### Public S3/CloudFront (No Authentication)
419
+ **AWS CloudFront Setup:**
420
+
421
+ 1. Create a CloudFront key pair in AWS Console → CloudFront → Key pairs
422
+ 2. Download the private key file
423
+ 3. Set up environment variables:
424
+ ```bash
425
+ CLOUDFRONT_KEY_PAIR_ID=APKA...
426
+ ```
427
+ 4. Configure your CloudFront distribution to require signed cookies
428
+
429
+ ---
430
+
431
+ ### Scenario 3: Private S3 Videos with Presigned URLs
432
+
433
+ **When to use:** Videos are in private S3 buckets without CloudFront.
434
+
435
+ **How it works:**
436
+
437
+ 1. Your backend generates temporary presigned URLs for S3 objects
438
+ 2. Player uses these URLs to access videos
439
+ 3. URLs expire after a set time (e.g., 1 hour)
287
440
 
288
- For public videos:
441
+ **Frontend Setup:**
289
442
 
290
443
  ```typescript
444
+ import { WontumPlayer } from "@obipascal/player"
445
+
291
446
  const player = new WontumPlayer({
292
- src: "https://d1234567890.cloudfront.net/video/playlist.m3u8",
447
+ src: "s3://my-bucket/videos/lesson-1/playlist.m3u8", // S3 URI
293
448
  container: "#player",
449
+ s3Config: {
450
+ getPresignedUrl: async (s3Key) => {
451
+ // Call your backend to generate presigned URL
452
+ const response = await fetch("/api/s3/presigned-url", {
453
+ method: "POST",
454
+ headers: { "Content-Type": "application/json" },
455
+ body: JSON.stringify({ key: s3Key }),
456
+ })
457
+
458
+ if (!response.ok) {
459
+ throw new Error("Failed to get presigned URL")
460
+ }
461
+
462
+ const data = await response.json()
463
+ return data.url // Return the presigned URL
464
+ },
465
+ },
294
466
  })
295
467
  ```
296
468
 
469
+ **Backend Setup (Node.js):**
470
+
471
+ ```typescript
472
+ import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"
473
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
474
+
475
+ const s3Client = new S3Client({
476
+ region: "us-east-1",
477
+ credentials: {
478
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
479
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
480
+ },
481
+ })
482
+
483
+ app.post("/api/s3/presigned-url", async (req, res) => {
484
+ const { key } = req.body
485
+
486
+ // Verify user is authorized to access this video
487
+ if (!req.user) {
488
+ return res.status(401).json({ error: "Not authenticated" })
489
+ }
490
+
491
+ try {
492
+ // Generate presigned URL
493
+ const command = new GetObjectCommand({
494
+ Bucket: "my-bucket",
495
+ Key: key, // e.g., "videos/lesson-1/playlist.m3u8"
496
+ })
497
+
498
+ const url = await getSignedUrl(s3Client, command, {
499
+ expiresIn: 3600, // URL valid for 1 hour
500
+ })
501
+
502
+ res.json({ url })
503
+ } catch (error) {
504
+ console.error("Error generating presigned URL:", error)
505
+ res.status(500).json({ error: "Failed to generate presigned URL" })
506
+ }
507
+ })
508
+ ```
509
+
510
+ ---
511
+
512
+ ### Which Method Should I Use?
513
+
514
+ | Method | Best For | Complexity | Performance |
515
+ | ---------------------- | ---------------------------------------------- | ----------- | ------------ |
516
+ | **Public Videos** | Free content, marketing videos | ⭐ Easy | ⚡ Fast |
517
+ | **CloudFront Cookies** | ⭐ **Recommended** for paid courses, premium | ⭐⭐ Medium | ⚡⚡ Fastest |
518
+ | **S3 Presigned URLs** | Direct S3 access, simple private video hosting | ⭐⭐ Medium | ⚡ Good |
519
+
520
+ 💡 **Tip:** Use CloudFront with signed cookies for production. It's more secure and performant for HLS videos (which have many file segments).
521
+
297
522
  ## 📝 Subtitle Support
298
523
 
299
524
  ### Adding Subtitles
@@ -568,15 +793,7 @@ function CustomPlayer() {
568
793
  Wontum Player comes with 7 beautiful pre-made themes:
569
794
 
570
795
  ```typescript
571
- import {
572
- netflixTheme,
573
- youtubeTheme,
574
- modernTheme,
575
- greenTheme,
576
- cyberpunkTheme,
577
- pastelTheme,
578
- educationTheme,
579
- } from "@obipascal/player"
796
+ import { netflixTheme, youtubeTheme, modernTheme, greenTheme, cyberpunkTheme, pastelTheme, educationTheme } from "@obipascal/player"
580
797
 
581
798
  const player = new WontumPlayer({
582
799
  src: "https://media.example.com/video/playlist.m3u8",
@@ -586,6 +803,7 @@ const player = new WontumPlayer({
586
803
  ```
587
804
 
588
805
  **Available Themes:**
806
+
589
807
  - `netflixTheme()` - Netflix-inspired red and black
590
808
  - `youtubeTheme()` - YouTube-inspired red and white
591
809
  - `modernTheme()` - Modern blue gradient
@@ -634,6 +852,7 @@ const player = new WontumPlayer({
634
852
  ```
635
853
 
636
854
  **Available Brand Colors:**
855
+
637
856
  - `blue`, `lightBlue`, `darkBlue`
638
857
  - `red`, `lightRed`, `darkRed`
639
858
  - `green`, `lightGreen`, `darkGreen`
@@ -788,6 +1007,7 @@ For detailed API documentation including all methods, events, types, and configu
788
1007
  ### Quick Reference
789
1008
 
790
1009
  **Player Methods:**
1010
+
791
1011
  - **Playback:** `play()`, `pause()`, `seek(time)`, `skipForward(seconds)`, `skipBackward(seconds)`
792
1012
  - **Volume:** `setVolume(level)`, `mute()`, `unmute()`
793
1013
  - **Subtitles:** `enableSubtitles(index)`, `disableSubtitles()`, `toggleSubtitles()`, `getSubtitleTracks()`, `areSubtitlesEnabled()`
@@ -798,6 +1018,7 @@ For detailed API documentation including all methods, events, types, and configu
798
1018
  - **Lifecycle:** `destroy()`
799
1019
 
800
1020
  **Events (25 total):**
1021
+
801
1022
  - **Playback:** `play`, `pause`, `ended`, `timeupdate`, `durationchange`
802
1023
  - **Loading:** `loadstart`, `loadedmetadata`, `loadeddata`, `canplay`, `canplaythrough`
803
1024
  - **Buffering:** `waiting`, `playing`, `stalled`, `suspend`, `abort`
@@ -812,13 +1033,13 @@ For detailed API documentation including all methods, events, types, and configu
812
1033
 
813
1034
  ## 🌐 Browser Support
814
1035
 
815
- | Browser | Minimum Version |
816
- |---------|----------------|
817
- | Chrome | Latest 2 versions |
818
- | Edge | Latest 2 versions |
819
- | Firefox | Latest 2 versions |
820
- | Safari | Latest 2 versions |
821
- | iOS Safari | iOS 12+ |
1036
+ | Browser | Minimum Version |
1037
+ | -------------- | ----------------- |
1038
+ | Chrome | Latest 2 versions |
1039
+ | Edge | Latest 2 versions |
1040
+ | Firefox | Latest 2 versions |
1041
+ | Safari | Latest 2 versions |
1042
+ | iOS Safari | iOS 12+ |
822
1043
  | Android Chrome | Latest 2 versions |
823
1044
 
824
1045
  **Note:** HLS playback requires HLS.js support. Native HLS playback is supported on Safari.
@@ -1,7 +1,6 @@
1
- import { default as React } from 'react';
2
1
  import { WontumPlayer } from './player';
3
2
  import { WontumPlayerConfig, PlayerState } from './types';
4
-
3
+ import * as React from "react";
5
4
  export interface WontumPlayerReactProps extends Omit<WontumPlayerConfig, "container"> {
6
5
  /** Callback when player is ready */
7
6
  onReady?: (player: WontumPlayer) => void;
@@ -12,6 +11,8 @@ export interface WontumPlayerReactProps extends Omit<WontumPlayerConfig, "contai
12
11
  onTimeUpdate?: (currentTime: number) => void;
13
12
  onVolumeChange?: (volume: number, muted: boolean) => void;
14
13
  onError?: (error: any) => void;
14
+ onLoadedMetadata?: () => void;
15
+ onQualityChange?: (level: number) => void;
15
16
  /** Container style */
16
17
  style?: React.CSSProperties;
17
18
  /** Container className */
@@ -1,4 +1,4 @@
1
- "use strict";var at=Object.defineProperty;var lt=(c,t,e)=>t in c?at(c,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[t]=e;var o=(c,t,e)=>lt(c,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("hls.js"),v=require("react");class tt{constructor(t){o(this,"config");o(this,"sessionId");o(this,"events",[]);o(this,"sessionStartTime");o(this,"playbackStartTime",null);o(this,"totalPlayTime",0);o(this,"totalBufferTime",0);o(this,"bufferStartTime",null);o(this,"rebufferCount",0);o(this,"seekCount",0);var e;this.config=t,this.sessionId=(t==null?void 0:t.sessionId)||this.generateSessionId(),this.sessionStartTime=Date.now(),(e=this.config)!=null&&e.enabled&&this.trackEvent("session_start",this.getSessionData())}trackEvent(t,e={}){var r;if(!((r=this.config)!=null&&r.enabled))return;const s={eventType:t,timestamp:Date.now(),sessionId:this.sessionId,videoId:this.config.videoId,userId:this.config.userId,data:{...e,...this.getQoEMetrics()}};this.events.push(s),this.updateMetrics(t,e),this.config.endpoint&&this.sendEvent(s),process.env.NODE_ENV==="development"&&console.log("[Analytics]",t,s.data)}updateMetrics(t,e){switch(t){case"play":this.playbackStartTime=Date.now();break;case"pause":case"ended":this.playbackStartTime&&(this.totalPlayTime+=Date.now()-this.playbackStartTime,this.playbackStartTime=null);break;case"buffering_start":this.bufferStartTime=Date.now(),this.rebufferCount++;break;case"buffering_end":this.bufferStartTime&&(this.totalBufferTime+=Date.now()-this.bufferStartTime,this.bufferStartTime=null);break;case"seeked":this.seekCount++;break}}getQoEMetrics(){const t=Date.now()-this.sessionStartTime,e=this.totalPlayTime>0?this.totalBufferTime/this.totalPlayTime:0;return{sessionDuration:t,totalPlayTime:this.totalPlayTime,totalBufferTime:this.totalBufferTime,bufferingRatio:Math.round(e*1e3)/1e3,rebufferCount:this.rebufferCount,seekCount:this.seekCount}}getSessionData(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:`${screen.width}x${screen.height}`,viewport:`${window.innerWidth}x${window.innerHeight}`,connection:this.getConnectionInfo()}}getConnectionInfo(){const t=navigator,e=t.connection||t.mozConnection||t.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:null}async sendEvent(t){var e;if((e=this.config)!=null&&e.endpoint)try{await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(s){console.error("Failed to send analytics event:",s)}}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getEvents(){return[...this.events]}getMetrics(){return{sessionId:this.sessionId,...this.getQoEMetrics(),eventCount:this.events.length}}destroy(){var t;(t=this.config)!=null&&t.enabled&&this.trackEvent("session_end",this.getSessionData()),this.events=[]}}class et{constructor(t,e){o(this,"container");o(this,"player");o(this,"controlsContainer");o(this,"progressContainer");o(this,"progressBar");o(this,"playButton");o(this,"skipBackwardButton");o(this,"skipForwardButton");o(this,"volumeButton");o(this,"fullscreenButton");o(this,"qualityButton");o(this,"subtitleButton");o(this,"speedButton");o(this,"settingsButton");o(this,"volumeSlider");o(this,"progressInput");o(this,"hideControlsTimeout",null);o(this,"stickyControls",!1);this.container=t,this.player=e,this.injectStyles(),this.createProgressBar(),this.controlsContainer=this.createControls(),this.container.appendChild(this.controlsContainer),this.playButton=this.controlsContainer.querySelector(".wontum-play-btn"),this.skipBackwardButton=this.controlsContainer.querySelector(".wontum-skip-backward-btn"),this.skipForwardButton=this.controlsContainer.querySelector(".wontum-skip-forward-btn"),this.volumeButton=this.controlsContainer.querySelector(".wontum-volume-btn"),this.fullscreenButton=this.controlsContainer.querySelector(".wontum-fullscreen-btn"),this.qualityButton=this.controlsContainer.querySelector(".wontum-quality-btn"),this.subtitleButton=this.controlsContainer.querySelector(".wontum-subtitle-btn"),this.speedButton=this.controlsContainer.querySelector(".wontum-speed-btn"),this.settingsButton=this.controlsContainer.querySelector(".wontum-settings-btn"),this.volumeSlider=this.controlsContainer.querySelector(".wontum-volume-slider"),this.progressInput=this.container.querySelector(".wontum-progress-input"),this.progressBar=this.container.querySelector(".wontum-progress-filled"),this.stickyControls=this.player.config.stickyControls||!1,this.stickyControls&&this.controlsContainer.classList.add("sticky"),this.setupEventListeners(),this.setupPlayerEventListeners()}injectStyles(){const t="wontum-player-styles";if(document.getElementById(t))return;const e=this.player.config.theme||{},s=e.primaryColor||"#3b82f6",r=e.accentColor||"#2563eb",i=e.fontFamily||"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",l=e.controlsBackground||"linear-gradient(to top, rgba(0,0,0,0.8), transparent)",u=e.buttonHoverBg||"rgba(255, 255, 255, 0.1)",g=e.progressHeight||"6px",b=e.borderRadius||"4px",f=document.createElement("style");f.id=t,f.textContent=`
1
+ "use strict";var lt=Object.defineProperty;var ct=(l,t,e)=>t in l?lt(l,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[t]=e;var o=(l,t,e)=>ct(l,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("hls.js"),v=require("react");function ut(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const s=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,s.get?s:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const et=ut(v);class nt{constructor(t){o(this,"config");o(this,"sessionId");o(this,"events",[]);o(this,"sessionStartTime");o(this,"playbackStartTime",null);o(this,"totalPlayTime",0);o(this,"totalBufferTime",0);o(this,"bufferStartTime",null);o(this,"rebufferCount",0);o(this,"seekCount",0);var e;this.config=t,this.sessionId=(t==null?void 0:t.sessionId)||this.generateSessionId(),this.sessionStartTime=Date.now(),(e=this.config)!=null&&e.enabled&&this.trackEvent("session_start",this.getSessionData())}trackEvent(t,e={}){var r;if(!((r=this.config)!=null&&r.enabled))return;const s={eventType:t,timestamp:Date.now(),sessionId:this.sessionId,videoId:this.config.videoId,userId:this.config.userId,data:{...e,...this.getQoEMetrics()}};this.events.push(s),this.updateMetrics(t,e),this.config.endpoint&&this.sendEvent(s),process.env.NODE_ENV==="development"&&console.log("[Analytics]",t,s.data)}updateMetrics(t,e){switch(t){case"play":this.playbackStartTime=Date.now();break;case"pause":case"ended":this.playbackStartTime&&(this.totalPlayTime+=Date.now()-this.playbackStartTime,this.playbackStartTime=null);break;case"buffering_start":this.bufferStartTime=Date.now(),this.rebufferCount++;break;case"buffering_end":this.bufferStartTime&&(this.totalBufferTime+=Date.now()-this.bufferStartTime,this.bufferStartTime=null);break;case"seeked":this.seekCount++;break}}getQoEMetrics(){const t=Date.now()-this.sessionStartTime,e=this.totalPlayTime>0?this.totalBufferTime/this.totalPlayTime:0;return{sessionDuration:t,totalPlayTime:this.totalPlayTime,totalBufferTime:this.totalBufferTime,bufferingRatio:Math.round(e*1e3)/1e3,rebufferCount:this.rebufferCount,seekCount:this.seekCount}}getSessionData(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:`${screen.width}x${screen.height}`,viewport:`${window.innerWidth}x${window.innerHeight}`,connection:this.getConnectionInfo()}}getConnectionInfo(){const t=navigator,e=t.connection||t.mozConnection||t.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:null}async sendEvent(t){var e;if((e=this.config)!=null&&e.endpoint)try{await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(s){console.error("Failed to send analytics event:",s)}}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getEvents(){return[...this.events]}getMetrics(){return{sessionId:this.sessionId,...this.getQoEMetrics(),eventCount:this.events.length}}destroy(){var t;(t=this.config)!=null&&t.enabled&&this.trackEvent("session_end",this.getSessionData()),this.events=[]}}class st{constructor(t,e){o(this,"container");o(this,"player");o(this,"controlsContainer");o(this,"progressContainer");o(this,"progressBar");o(this,"playButton");o(this,"skipBackwardButton");o(this,"skipForwardButton");o(this,"volumeButton");o(this,"fullscreenButton");o(this,"qualityButton");o(this,"subtitleButton");o(this,"speedButton");o(this,"settingsButton");o(this,"volumeSlider");o(this,"progressInput");o(this,"hideControlsTimeout",null);o(this,"stickyControls",!1);this.container=t,this.player=e,this.injectStyles(),this.createProgressBar(),this.controlsContainer=this.createControls(),this.container.appendChild(this.controlsContainer),this.playButton=this.controlsContainer.querySelector(".wontum-play-btn"),this.skipBackwardButton=this.controlsContainer.querySelector(".wontum-skip-backward-btn"),this.skipForwardButton=this.controlsContainer.querySelector(".wontum-skip-forward-btn"),this.volumeButton=this.controlsContainer.querySelector(".wontum-volume-btn"),this.fullscreenButton=this.controlsContainer.querySelector(".wontum-fullscreen-btn"),this.qualityButton=this.controlsContainer.querySelector(".wontum-quality-btn"),this.subtitleButton=this.controlsContainer.querySelector(".wontum-subtitle-btn"),this.speedButton=this.controlsContainer.querySelector(".wontum-speed-btn"),this.settingsButton=this.controlsContainer.querySelector(".wontum-settings-btn"),this.volumeSlider=this.controlsContainer.querySelector(".wontum-volume-slider"),this.progressInput=this.container.querySelector(".wontum-progress-input"),this.progressBar=this.container.querySelector(".wontum-progress-filled"),this.stickyControls=this.player.config.stickyControls||!1,this.stickyControls&&this.controlsContainer.classList.add("sticky"),this.setupEventListeners(),this.setupPlayerEventListeners()}injectStyles(){const t="wontum-player-styles";if(document.getElementById(t))return;const e=this.player.config.theme||{},s=e.primaryColor||"#3b82f6",r=e.accentColor||"#2563eb",i=e.fontFamily||"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",c=e.controlsBackground||"linear-gradient(to top, rgba(0,0,0,0.8), transparent)",u=e.buttonHoverBg||"rgba(255, 255, 255, 0.1)",f=e.progressHeight||"6px",b=e.borderRadius||"4px",y=document.createElement("style");y.id=t,y.textContent=`
2
2
  .wontum-player-container {
3
3
  position: relative;
4
4
  background: #000;
@@ -6,9 +6,9 @@
6
6
  overflow: hidden;
7
7
  --primary-color: ${s};
8
8
  --accent-color: ${r};
9
- --controls-bg: ${l};
9
+ --controls-bg: ${c};
10
10
  --button-hover: ${u};
11
- --progress-height: ${g};
11
+ --progress-height: ${f};
12
12
  --border-radius: ${b};
13
13
  }
14
14
 
@@ -463,7 +463,7 @@
463
463
  transform: translateY(0) !important;
464
464
  pointer-events: all !important;
465
465
  }
466
- `,document.head.appendChild(f),this.container.classList.add("wontum-player-container")}createProgressBar(){const t=document.createElement("div");t.className="wontum-progress-container",t.innerHTML=`
466
+ `,document.head.appendChild(y),this.container.classList.add("wontum-player-container")}createProgressBar(){const t=document.createElement("div");t.className="wontum-progress-container",t.innerHTML=`
467
467
  <div class="wontum-progress-track"></div>
468
468
  <div class="wontum-progress-filled"></div>
469
469
  <input type="range" class="wontum-progress-input" min="0" max="100" value="0" step="0.1">
@@ -535,18 +535,18 @@
535
535
  <div class="wontum-loading" style="display: none;">
536
536
  <div class="wontum-spinner"></div>
537
537
  </div>
538
- `,t}setupEventListeners(){this.playButton.addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.skipBackwardButton.addEventListener("click",()=>{this.player.skipBackward(10)}),this.skipForwardButton.addEventListener("click",()=>{this.player.skipForward(10)}),this.progressInput.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value),i=this.player.getState(),l=r/100*i.duration;this.player.seek(l)}),this.volumeSlider.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value)/100;this.player.setVolume(r)}),this.volumeButton.addEventListener("click",()=>{this.player.getState().muted?this.player.unmute():this.player.mute()}),this.fullscreenButton.addEventListener("click",()=>{this.player.getState().fullscreen?this.player.exitFullscreen():this.player.enterFullscreen()}),this.qualityButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-quality-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active")}),this.subtitleButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-subtitle-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSubtitleMenu()}),this.speedButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-speed-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||i.classList.remove("active"),this.updateSpeedMenu()}),this.settingsButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-settings-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSettingsMenu()}),this.player.getVideoElement().addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.container.addEventListener("mousemove",()=>{this.showControls(),this.resetHideControlsTimeout()}),this.container.addEventListener("mouseleave",()=>{this.hideControls()})}setupPlayerEventListeners(){this.player.on("play",()=>{this.playButton.innerHTML=this.getPauseIcon()}),this.player.on("pause",()=>{this.playButton.innerHTML=this.getPlayIcon()}),this.player.on("timeupdate",t=>{const{currentTime:e}=t.data,s=this.player.getState();if(s.duration>0){const i=e/s.duration*100;this.progressBar.style.width=`${i}%`,this.progressInput.value=i.toString()}const r=this.controlsContainer.querySelector(".wontum-current-time");r.textContent=this.formatTime(e)}),this.player.on("loadedmetadata",t=>{const{duration:e}=t.data,s=this.controlsContainer.querySelector(".wontum-duration");s.textContent=this.formatTime(e),t.data.qualities&&this.updateQualityMenu(t.data.qualities)}),this.player.on("volumechange",t=>{const{volume:e,muted:s}=t.data;this.volumeSlider.value=(e*100).toString(),this.volumeButton.innerHTML=s?this.getMutedIcon():this.getVolumeIcon()}),this.player.on("waiting",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="block"}),this.player.on("canplay",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="none"})}updateSubtitleMenu(){const t=this.controlsContainer.querySelector(".wontum-subtitle-menu"),e=this.player.getSubtitleTracks();if(e.length===0){t.innerHTML='<div class="wontum-subtitle-option">No subtitles available</div>';return}const s=e.findIndex(r=>r.mode==="showing");t.innerHTML=`
538
+ `,t}setupEventListeners(){this.playButton.addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.skipBackwardButton.addEventListener("click",()=>{this.player.skipBackward(10)}),this.skipForwardButton.addEventListener("click",()=>{this.player.skipForward(10)}),this.progressInput.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value),i=this.player.getState(),c=r/100*i.duration;this.player.seek(c)}),this.volumeSlider.addEventListener("input",e=>{const s=e.target,r=parseFloat(s.value)/100;this.player.setVolume(r)}),this.volumeButton.addEventListener("click",()=>{this.player.getState().muted?this.player.unmute():this.player.mute()}),this.fullscreenButton.addEventListener("click",()=>{this.player.getState().fullscreen?this.player.exitFullscreen():this.player.enterFullscreen()}),this.qualityButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-quality-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active")}),this.subtitleButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-subtitle-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSubtitleMenu()}),this.speedButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-speed-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-settings-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||i.classList.remove("active"),this.updateSpeedMenu()}),this.settingsButton.addEventListener("click",()=>{var s,r,i;this.controlsContainer.querySelector(".wontum-settings-menu").classList.toggle("active"),(s=this.controlsContainer.querySelector(".wontum-quality-menu"))==null||s.classList.remove("active"),(r=this.controlsContainer.querySelector(".wontum-subtitle-menu"))==null||r.classList.remove("active"),(i=this.controlsContainer.querySelector(".wontum-speed-menu"))==null||i.classList.remove("active"),this.updateSettingsMenu()}),this.player.getVideoElement().addEventListener("click",()=>{this.player.getState().playing?this.player.pause():this.player.play()}),this.container.addEventListener("mousemove",()=>{this.showControls(),this.resetHideControlsTimeout()}),this.container.addEventListener("mouseleave",()=>{this.hideControls()})}setupPlayerEventListeners(){this.player.on("play",()=>{this.playButton.innerHTML=this.getPauseIcon()}),this.player.on("pause",()=>{this.playButton.innerHTML=this.getPlayIcon()}),this.player.on("timeupdate",t=>{const{currentTime:e}=t.data,s=this.player.getState();if(s.duration>0){const i=e/s.duration*100;this.progressBar.style.width=`${i}%`,this.progressInput.value=i.toString()}const r=this.controlsContainer.querySelector(".wontum-current-time");r.textContent=this.formatTime(e)}),this.player.on("loadedmetadata",t=>{const{duration:e}=t.data,s=this.controlsContainer.querySelector(".wontum-duration");s.textContent=this.formatTime(e),t.data.qualities&&this.updateQualityMenu(t.data.qualities)}),this.player.on("volumechange",t=>{const{volume:e,muted:s}=t.data;this.volumeSlider.value=(e*100).toString(),this.volumeButton.innerHTML=s?this.getMutedIcon():this.getVolumeIcon()}),this.player.on("waiting",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="block"}),this.player.on("canplay",()=>{const t=this.controlsContainer.querySelector(".wontum-loading");t.style.display="none"})}updateSubtitleMenu(){const t=this.controlsContainer.querySelector(".wontum-subtitle-menu"),e=this.player.getSubtitleTracks();if(e.length===0){t.innerHTML='<div class="wontum-subtitle-option">No subtitles available</div>';return}const s=e.findIndex(r=>r.mode==="showing");t.innerHTML=`
539
539
  <div class="wontum-subtitle-option ${s===-1?"active":""}" data-track="-1">Off</div>
540
540
  ${e.map((r,i)=>`
541
541
  <div class="wontum-subtitle-option ${i===s?"active":""}" data-track="${i}">
542
542
  ${r.label||r.language||`Track ${i+1}`}
543
543
  </div>
544
544
  `).join("")}
545
- `,t.querySelectorAll(".wontum-subtitle-option").forEach(r=>{r.addEventListener("click",i=>{const l=i.target,u=parseInt(l.dataset.track||"-1");u===-1?this.player.disableSubtitles():this.player.enableSubtitles(u),t.querySelectorAll(".wontum-subtitle-option").forEach(g=>g.classList.remove("active")),l.classList.add("active"),t.classList.remove("active")})})}updateSpeedMenu(){const t=this.controlsContainer.querySelector(".wontum-speed-menu"),s=this.player.getState().playbackRate||1,r=[.25,.5,.75,1,1.25,1.5,1.75,2];t.innerHTML=r.map(i=>`
545
+ `,t.querySelectorAll(".wontum-subtitle-option").forEach(r=>{r.addEventListener("click",i=>{const c=i.target,u=parseInt(c.dataset.track||"-1");u===-1?this.player.disableSubtitles():this.player.enableSubtitles(u),t.querySelectorAll(".wontum-subtitle-option").forEach(f=>f.classList.remove("active")),c.classList.add("active"),t.classList.remove("active")})})}updateSpeedMenu(){const t=this.controlsContainer.querySelector(".wontum-speed-menu"),s=this.player.getState().playbackRate||1,r=[.25,.5,.75,1,1.25,1.5,1.75,2];t.innerHTML=r.map(i=>`
546
546
  <div class="wontum-speed-option ${s===i?"active":""}" data-speed="${i}">
547
547
  ${i===1?"Normal":i+"x"}
548
548
  </div>
549
- `).join(""),t.querySelectorAll(".wontum-speed-option").forEach(i=>{i.addEventListener("click",l=>{const u=l.target,g=parseFloat(u.dataset.speed||"1");this.player.setPlaybackRate(g),t.querySelectorAll(".wontum-speed-option").forEach(b=>b.classList.remove("active")),u.classList.add("active"),t.classList.remove("active")})})}updateSettingsMenu(){const t=this.controlsContainer.querySelector(".wontum-settings-menu");t.innerHTML=`
549
+ `).join(""),t.querySelectorAll(".wontum-speed-option").forEach(i=>{i.addEventListener("click",c=>{const u=c.target,f=parseFloat(u.dataset.speed||"1");this.player.setPlaybackRate(f),t.querySelectorAll(".wontum-speed-option").forEach(b=>b.classList.remove("active")),u.classList.add("active"),t.classList.remove("active")})})}updateSettingsMenu(){const t=this.controlsContainer.querySelector(".wontum-settings-menu");t.innerHTML=`
550
550
  <div class="wontum-settings-option" data-setting="sticky-controls">
551
551
  <span>Sticky Controls</span>
552
552
  <div class="wontum-toggle-switch ${this.stickyControls?"active":""}"></div>
@@ -556,7 +556,7 @@
556
556
  ${t.map((s,r)=>`
557
557
  <div class="wontum-quality-option" data-quality="${r}">${s.name}</div>
558
558
  `).join("")}
559
- `,e.querySelectorAll(".wontum-quality-option").forEach(s=>{s.addEventListener("click",r=>{const i=r.target,l=parseInt(i.dataset.quality||"-1");this.player.setQuality(l),e.querySelectorAll(".wontum-quality-option").forEach(u=>u.classList.remove("active")),i.classList.add("active"),e.classList.remove("active")})})}showControls(){this.controlsContainer.classList.remove("hidden"),this.progressContainer.classList.remove("hidden")}hideControls(){if(this.stickyControls)return;this.player.getState().playing&&(this.controlsContainer.classList.add("hidden"),this.progressContainer.classList.add("hidden"))}resetHideControlsTimeout(){this.stickyControls||(this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.hideControlsTimeout=window.setTimeout(()=>{this.hideControls()},1e4))}formatTime(t){if(isNaN(t))return"0:00";const e=Math.floor(t/60),s=Math.floor(t%60);return`${e}:${s.toString().padStart(2,"0")}`}getPlayIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M8 5v14l11-7z"/></svg>'}getPauseIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/></svg>'}getVolumeIcon(){return'<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>'}getMutedIcon(){return'<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>'}getFullscreenIcon(){return'<svg viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>'}getQualityIcon(){return'<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/></svg>'}getSkipBackwardIcon(){return`<svg viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
559
+ `,e.querySelectorAll(".wontum-quality-option").forEach(s=>{s.addEventListener("click",r=>{const i=r.target,c=parseInt(i.dataset.quality||"-1");this.player.setQuality(c),e.querySelectorAll(".wontum-quality-option").forEach(u=>u.classList.remove("active")),i.classList.add("active"),e.classList.remove("active")})})}showControls(){this.controlsContainer.classList.remove("hidden"),this.progressContainer.classList.remove("hidden")}hideControls(){if(this.stickyControls)return;this.player.getState().playing&&(this.controlsContainer.classList.add("hidden"),this.progressContainer.classList.add("hidden"))}resetHideControlsTimeout(){this.stickyControls||(this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.hideControlsTimeout=window.setTimeout(()=>{this.hideControls()},1e4))}formatTime(t){if(isNaN(t))return"0:00";const e=Math.floor(t/60),s=Math.floor(t%60);return`${e}:${s.toString().padStart(2,"0")}`}getPlayIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M8 5v14l11-7z"/></svg>'}getPauseIcon(){return'<svg viewBox="0 0 24 24"><path fill="white" d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/></svg>'}getVolumeIcon(){return'<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>'}getMutedIcon(){return'<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>'}getFullscreenIcon(){return'<svg viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>'}getQualityIcon(){return'<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/></svg>'}getSkipBackwardIcon(){return`<svg viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
560
560
  <circle cx="30" cy="30" r="28" stroke="white" stroke-width="2"/>
561
561
  <!-- Circular arrow backward -->
562
562
  <path d="M30 12 A18 18 0 1 0 30 48" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/>
@@ -568,7 +568,7 @@
568
568
  <path d="M30 12 A18 18 0 1 1 30 48" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/>
569
569
  <path d="M35 12 L30 12 L30 17" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
570
570
  <text x="30" y="35" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="white" text-anchor="middle">10</text>
571
- </svg>`}getSubtitleIcon(){return'<svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></svg>'}getSpeedIcon(){return'<svg viewBox="0 0 24 24"><path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/></svg>'}getSettingsIcon(){return'<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>'}destroy(){this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.controlsContainer.remove()}}class nt{constructor(t){o(this,"config");o(this,"urlCache",new Map);o(this,"signedUrls",new Set);this.config=t}async processUrl(t){return this.isCloudFrontUrl(t)?this.signCloudFrontUrl(t):this.isS3Url(t)?this.getPresignedUrl(t):t}isCloudFrontUrl(t){var e;if(!((e=this.config)!=null&&e.cloudFrontDomains)||this.config.cloudFrontDomains.length===0)return!1;try{const s=new URL(t);return this.config.cloudFrontDomains.some(r=>s.hostname.includes(r))}catch{return!1}}isS3Url(t){return t.includes(".s3.")||t.includes("s3.amazonaws.com")||t.startsWith("s3://")}async signCloudFrontUrl(t){var e;if(this.signedUrls.has(t))return t;if((e=this.config)!=null&&e.signUrl)try{const s=await this.config.signUrl(t);return this.signedUrls.add(t),s}catch(s){throw console.error("Failed to sign CloudFront URL:",s),new Error("Failed to sign CloudFront URL")}return console.warn("No signUrl function provided. CloudFront cookies may not be set."),t}extractS3Key(t){if(t.startsWith("s3://"))return t.replace("s3://","").split("/").slice(1).join("/");const e=t.match(/s3[.-]([^.]+)\.amazonaws\.com\/(.+)/);if(e)return e[2];const s=t.match(/([^.]+)\.s3\.amazonaws\.com\/(.+)/);return s?s[2]:t}async getPresignedUrl(t){var r;const e=this.extractS3Key(t),s=this.urlCache.get(e);if(s&&s.expiresAt>Date.now())return s.url;if((r=this.config)!=null&&r.getPresignedUrl)try{const i=await this.config.getPresignedUrl(e);return this.urlCache.set(e,{url:i,expiresAt:Date.now()+50*60*1e3}),i}catch(i){throw console.error("Failed to generate presigned URL:",i),new Error("Failed to generate presigned URL for S3 object")}return console.warn("No getPresignedUrl function provided. Using direct S3 URL (requires public bucket)"),t}static constructS3Url(t,e,s="us-east-1"){return`https://${t}.s3.${s}.amazonaws.com/${e}`}static parseS3Uri(t){if(!t.startsWith("s3://"))return null;const e=t.replace("s3://","").split("/"),s=e[0],r=e.slice(1).join("/");return{bucket:s,key:r}}clearCache(){this.urlCache.clear(),this.signedUrls.clear()}}class V{constructor(t){o(this,"container");o(this,"videoElement");o(this,"hls",null);o(this,"config");o(this,"eventListeners",new Map);o(this,"analytics");o(this,"s3Handler");o(this,"uiController");o(this,"state",{playing:!1,paused:!0,ended:!1,buffering:!1,currentTime:0,duration:0,volume:1,muted:!1,playbackRate:1,quality:"auto",availableQualities:[],fullscreen:!1});if(this.config=t,this.container=typeof t.container=="string"?document.querySelector(t.container):t.container,!this.container)throw new Error("Container element not found");this.analytics=new tt(t.analytics),this.s3Handler=new nt(t.s3Config),this.videoElement=this.createVideoElement(),this.container.appendChild(this.videoElement),this.uiController=new et(this.container,this),this.setupVideoListeners(),this.loadSource(t.src),t.autoplay&&(this.videoElement.autoplay=!0),t.muted&&this.mute(),t.poster&&(this.videoElement.poster=t.poster),t.preload&&(this.videoElement.preload=t.preload),t.subtitles&&this.addSubtitleTracks(t.subtitles)}addSubtitleTracks(t){t.forEach(e=>{const s=document.createElement("track");s.kind="subtitles",s.label=e.label,s.src=e.src,s.srclang=e.srclang,e.default&&(s.default=!0),this.videoElement.appendChild(s)})}createVideoElement(){const t=document.createElement("video");return t.className="wontum-player-video",t.style.width="100%",t.style.height="100%",t.playsInline=!0,t}setupVideoListeners(){this.videoElement.addEventListener("play",()=>{this.state.playing=!0,this.state.paused=!1,this.emit("play"),this.analytics.trackEvent("play",this.getAnalyticsData())}),this.videoElement.addEventListener("pause",()=>{this.state.playing=!1,this.state.paused=!0,this.emit("pause"),this.analytics.trackEvent("pause",this.getAnalyticsData())}),this.videoElement.addEventListener("ended",()=>{this.state.ended=!0,this.state.playing=!1,this.emit("ended"),this.analytics.trackEvent("ended",this.getAnalyticsData())}),this.videoElement.addEventListener("timeupdate",()=>{this.state.currentTime=this.videoElement.currentTime,this.emit("timeupdate",{currentTime:this.state.currentTime})}),this.videoElement.addEventListener("loadedmetadata",()=>{this.state.duration=this.videoElement.duration,this.emit("loadedmetadata",{duration:this.state.duration}),this.analytics.trackEvent("loadedmetadata",this.getAnalyticsData())}),this.videoElement.addEventListener("volumechange",()=>{this.state.volume=this.videoElement.volume,this.state.muted=this.videoElement.muted,this.emit("volumechange",{volume:this.state.volume,muted:this.state.muted})}),this.videoElement.addEventListener("ratechange",()=>{this.state.playbackRate=this.videoElement.playbackRate,this.emit("ratechange",{playbackRate:this.state.playbackRate})}),this.videoElement.addEventListener("waiting",()=>{this.state.buffering=!0,this.emit("waiting"),this.analytics.trackEvent("buffering_start",this.getAnalyticsData())}),this.videoElement.addEventListener("canplay",()=>{this.state.buffering=!1,this.emit("canplay"),this.analytics.trackEvent("buffering_end",this.getAnalyticsData())}),this.videoElement.addEventListener("seeking",()=>{this.emit("seeking")}),this.videoElement.addEventListener("seeked",()=>{this.emit("seeked",{currentTime:this.state.currentTime}),this.analytics.trackEvent("seeked",this.getAnalyticsData())}),this.videoElement.addEventListener("error",t=>{const e=this.videoElement.error;this.emit("error",{error:e}),this.analytics.trackEvent("error",{...this.getAnalyticsData(),error:e==null?void 0:e.message})}),this.videoElement.addEventListener("loadstart",()=>{this.emit("loadstart")}),this.videoElement.addEventListener("loadeddata",()=>{this.emit("loadeddata")}),this.videoElement.addEventListener("canplaythrough",()=>{this.emit("canplaythrough")}),this.videoElement.addEventListener("playing",()=>{this.state.playing=!0,this.state.buffering=!1,this.emit("playing")}),this.videoElement.addEventListener("durationchange",()=>{this.state.duration=this.videoElement.duration,this.emit("durationchange",{duration:this.state.duration})}),this.videoElement.addEventListener("progress",()=>{this.emit("progress",{buffered:this.videoElement.buffered})}),this.videoElement.addEventListener("stalled",()=>{this.emit("stalled")}),this.videoElement.addEventListener("suspend",()=>{this.emit("suspend")}),this.videoElement.addEventListener("abort",()=>{this.emit("abort")}),this.videoElement.addEventListener("emptied",()=>{this.emit("emptied")}),this.videoElement.addEventListener("resize",()=>{this.emit("resize",{videoWidth:this.videoElement.videoWidth,videoHeight:this.videoElement.videoHeight})})}async loadSource(t){try{const e=await this.s3Handler.processUrl(t);if(k.isSupported())this.hls=new k(this.config.hlsConfig),this.hls.loadSource(e),this.hls.attachMedia(this.videoElement),this.hls.on(k.Events.MANIFEST_PARSED,(s,r)=>{const i=this.extractQualities(r.levels);this.state.availableQualities=i.map(l=>l.name),this.emit("loadedmetadata",{qualities:i})}),this.hls.on(k.Events.LEVEL_SWITCHED,(s,r)=>{var l;const i=(l=this.hls)==null?void 0:l.levels[r.level];i&&(this.state.quality=`${i.height}p`,this.emit("qualitychange",{quality:this.state.quality}))}),this.hls.on(k.Events.ERROR,(s,r)=>{r.fatal&&this.handleHlsError(r)});else if(this.videoElement.canPlayType("application/vnd.apple.mpegurl"))this.videoElement.src=e;else throw new Error("HLS is not supported in this browser")}catch(e){console.error("Failed to load video source:",e),this.emit("error",{error:e})}}extractQualities(t){return t.map(e=>({height:e.height,width:e.width,bitrate:e.bitrate,name:`${e.height}p`}))}handleHlsError(t){var e,s;switch(t.type){case k.ErrorTypes.NETWORK_ERROR:console.error("Network error occurred"),(e=this.hls)==null||e.startLoad();break;case k.ErrorTypes.MEDIA_ERROR:console.error("Media error occurred"),(s=this.hls)==null||s.recoverMediaError();break;default:console.error("Fatal error occurred:",t),this.destroy();break}}getAnalyticsData(){return{currentTime:this.state.currentTime,duration:this.state.duration,quality:this.state.quality,playbackRate:this.state.playbackRate,volume:this.state.volume,muted:this.state.muted}}play(){return this.videoElement.play()}pause(){this.videoElement.pause()}seek(t){this.videoElement.currentTime=t}skipForward(t=10){const e=Math.min(this.state.currentTime+t,this.state.duration);this.seek(e)}skipBackward(t=10){const e=Math.max(this.state.currentTime-t,0);this.seek(e)}setVolume(t){this.videoElement.volume=Math.max(0,Math.min(1,t))}mute(){this.videoElement.muted=!0}unmute(){this.videoElement.muted=!1}setPlaybackRate(t){this.videoElement.playbackRate=t}setQuality(t){this.hls&&(this.hls.currentLevel=t)}enterFullscreen(){this.container.requestFullscreen&&(this.container.requestFullscreen(),this.state.fullscreen=!0,this.emit("fullscreenchange",{fullscreen:!0}))}exitFullscreen(){document.exitFullscreen&&(document.exitFullscreen(),this.state.fullscreen=!1,this.emit("fullscreenchange",{fullscreen:!1}))}getState(){return{...this.state}}getVideoElement(){return this.videoElement}enableSubtitles(t){const e=this.videoElement.textTracks;for(let s=0;s<e.length;s++)e[s].mode=s===t?"showing":"hidden"}disableSubtitles(){const t=this.videoElement.textTracks;for(let e=0;e<t.length;e++)t[e].mode="hidden"}toggleSubtitles(){const t=this.videoElement.textTracks;return Array.from(t).some(s=>s.mode==="showing")?(this.disableSubtitles(),!1):t.length>0?(this.enableSubtitles(0),!0):!1}getSubtitleTracks(){return Array.from(this.videoElement.textTracks)}areSubtitlesEnabled(){const t=this.videoElement.textTracks;return Array.from(t).some(e=>e.mode==="showing")}on(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e)}off(t,e){var s;(s=this.eventListeners.get(t))==null||s.delete(e)}emit(t,e){var r;const s={type:t,data:e,timestamp:Date.now()};(r=this.eventListeners.get(t))==null||r.forEach(i=>{i(s)})}destroy(){this.hls&&(this.hls.destroy(),this.hls=null),this.uiController.destroy(),this.videoElement.remove(),this.eventListeners.clear(),this.analytics.destroy()}}var N={exports:{}},P={};/**
571
+ </svg>`}getSubtitleIcon(){return'<svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></svg>'}getSpeedIcon(){return'<svg viewBox="0 0 24 24"><path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/></svg>'}getSettingsIcon(){return'<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>'}destroy(){this.hideControlsTimeout&&clearTimeout(this.hideControlsTimeout),this.controlsContainer.remove()}}class rt{constructor(t){o(this,"config");o(this,"urlCache",new Map);o(this,"signedUrls",new Set);this.config=t}async processUrl(t){return this.isCloudFrontUrl(t)?this.signCloudFrontUrl(t):this.isS3Url(t)?this.getPresignedUrl(t):t}isCloudFrontUrl(t){var e;if(!((e=this.config)!=null&&e.cloudFrontDomains)||this.config.cloudFrontDomains.length===0)return!1;try{const s=new URL(t);return this.config.cloudFrontDomains.some(r=>s.hostname.includes(r))}catch{return!1}}isS3Url(t){return t.includes(".s3.")||t.includes("s3.amazonaws.com")||t.startsWith("s3://")}async signCloudFrontUrl(t){var e;if(this.signedUrls.has(t))return t;if((e=this.config)!=null&&e.signUrl)try{const s=await this.config.signUrl(t);return this.signedUrls.add(t),s}catch(s){throw console.error("Failed to sign CloudFront URL:",s),new Error("Failed to sign CloudFront URL")}return console.warn("No signUrl function provided. CloudFront cookies may not be set."),t}extractS3Key(t){if(t.startsWith("s3://"))return t.replace("s3://","").split("/").slice(1).join("/");const e=t.match(/s3[.-]([^.]+)\.amazonaws\.com\/(.+)/);if(e)return e[2];const s=t.match(/([^.]+)\.s3\.amazonaws\.com\/(.+)/);return s?s[2]:t}async getPresignedUrl(t){var r;const e=this.extractS3Key(t),s=this.urlCache.get(e);if(s&&s.expiresAt>Date.now())return s.url;if((r=this.config)!=null&&r.getPresignedUrl)try{const i=await this.config.getPresignedUrl(e);return this.urlCache.set(e,{url:i,expiresAt:Date.now()+50*60*1e3}),i}catch(i){throw console.error("Failed to generate presigned URL:",i),new Error("Failed to generate presigned URL for S3 object")}return console.warn("No getPresignedUrl function provided. Using direct S3 URL (requires public bucket)"),t}static constructS3Url(t,e,s="us-east-1"){return`https://${t}.s3.${s}.amazonaws.com/${e}`}static parseS3Uri(t){if(!t.startsWith("s3://"))return null;const e=t.replace("s3://","").split("/"),s=e[0],r=e.slice(1).join("/");return{bucket:s,key:r}}clearCache(){this.urlCache.clear(),this.signedUrls.clear()}}class Y{constructor(t){o(this,"container");o(this,"videoElement");o(this,"hls",null);o(this,"config");o(this,"eventListeners",new Map);o(this,"analytics");o(this,"s3Handler");o(this,"uiController");o(this,"state",{playing:!1,paused:!0,ended:!1,buffering:!1,currentTime:0,duration:0,volume:1,muted:!1,playbackRate:1,quality:"auto",availableQualities:[],fullscreen:!1});if(this.config=t,this.container=typeof t.container=="string"?document.querySelector(t.container):t.container,!this.container)throw new Error("Container element not found");this.analytics=new nt(t.analytics),this.s3Handler=new rt(t.s3Config),this.videoElement=this.createVideoElement(),this.container.appendChild(this.videoElement),this.uiController=new st(this.container,this),this.setupVideoListeners(),this.loadSource(t.src),t.autoplay&&(this.videoElement.autoplay=!0),t.muted&&this.mute(),t.poster&&(this.videoElement.poster=t.poster),t.preload&&(this.videoElement.preload=t.preload),t.subtitles&&this.addSubtitleTracks(t.subtitles)}addSubtitleTracks(t){t.forEach(e=>{const s=document.createElement("track");s.kind="subtitles",s.label=e.label,s.src=e.src,s.srclang=e.srclang,e.default&&(s.default=!0),this.videoElement.appendChild(s)})}createVideoElement(){const t=document.createElement("video");return t.className="wontum-player-video",t.style.width="100%",t.style.height="100%",t.playsInline=!0,t}setupVideoListeners(){this.videoElement.addEventListener("play",()=>{this.state.playing=!0,this.state.paused=!1,this.emit("play"),this.analytics.trackEvent("play",this.getAnalyticsData())}),this.videoElement.addEventListener("pause",()=>{this.state.playing=!1,this.state.paused=!0,this.emit("pause"),this.analytics.trackEvent("pause",this.getAnalyticsData())}),this.videoElement.addEventListener("ended",()=>{this.state.ended=!0,this.state.playing=!1,this.emit("ended"),this.analytics.trackEvent("ended",this.getAnalyticsData())}),this.videoElement.addEventListener("timeupdate",()=>{this.state.currentTime=this.videoElement.currentTime,this.emit("timeupdate",{currentTime:this.state.currentTime})}),this.videoElement.addEventListener("loadedmetadata",()=>{this.state.duration=this.videoElement.duration,this.emit("loadedmetadata",{duration:this.state.duration}),this.analytics.trackEvent("loadedmetadata",this.getAnalyticsData())}),this.videoElement.addEventListener("volumechange",()=>{this.state.volume=this.videoElement.volume,this.state.muted=this.videoElement.muted,this.emit("volumechange",{volume:this.state.volume,muted:this.state.muted})}),this.videoElement.addEventListener("ratechange",()=>{this.state.playbackRate=this.videoElement.playbackRate,this.emit("ratechange",{playbackRate:this.state.playbackRate})}),this.videoElement.addEventListener("waiting",()=>{this.state.buffering=!0,this.emit("waiting"),this.analytics.trackEvent("buffering_start",this.getAnalyticsData())}),this.videoElement.addEventListener("canplay",()=>{this.state.buffering=!1,this.emit("canplay"),this.analytics.trackEvent("buffering_end",this.getAnalyticsData())}),this.videoElement.addEventListener("seeking",()=>{this.emit("seeking")}),this.videoElement.addEventListener("seeked",()=>{this.emit("seeked",{currentTime:this.state.currentTime}),this.analytics.trackEvent("seeked",this.getAnalyticsData())}),this.videoElement.addEventListener("error",t=>{const e=this.videoElement.error;this.emit("error",{error:e}),this.analytics.trackEvent("error",{...this.getAnalyticsData(),error:e==null?void 0:e.message})}),this.videoElement.addEventListener("loadstart",()=>{this.emit("loadstart")}),this.videoElement.addEventListener("loadeddata",()=>{this.emit("loadeddata")}),this.videoElement.addEventListener("canplaythrough",()=>{this.emit("canplaythrough")}),this.videoElement.addEventListener("playing",()=>{this.state.playing=!0,this.state.buffering=!1,this.emit("playing")}),this.videoElement.addEventListener("durationchange",()=>{this.state.duration=this.videoElement.duration,this.emit("durationchange",{duration:this.state.duration})}),this.videoElement.addEventListener("progress",()=>{this.emit("progress",{buffered:this.videoElement.buffered})}),this.videoElement.addEventListener("stalled",()=>{this.emit("stalled")}),this.videoElement.addEventListener("suspend",()=>{this.emit("suspend")}),this.videoElement.addEventListener("abort",()=>{this.emit("abort")}),this.videoElement.addEventListener("emptied",()=>{this.emit("emptied")}),this.videoElement.addEventListener("resize",()=>{this.emit("resize",{videoWidth:this.videoElement.videoWidth,videoHeight:this.videoElement.videoHeight})})}async loadSource(t){try{const e=await this.s3Handler.processUrl(t);if(E.isSupported())this.hls=new E(this.config.hlsConfig),this.hls.loadSource(e),this.hls.attachMedia(this.videoElement),this.hls.on(E.Events.MANIFEST_PARSED,(s,r)=>{const i=this.extractQualities(r.levels);this.state.availableQualities=i.map(c=>c.name),this.emit("loadedmetadata",{qualities:i})}),this.hls.on(E.Events.LEVEL_SWITCHED,(s,r)=>{var c;const i=(c=this.hls)==null?void 0:c.levels[r.level];i&&(this.state.quality=`${i.height}p`,this.emit("qualitychange",{quality:this.state.quality}))}),this.hls.on(E.Events.ERROR,(s,r)=>{r.fatal&&this.handleHlsError(r)});else if(this.videoElement.canPlayType("application/vnd.apple.mpegurl"))this.videoElement.src=e;else throw new Error("HLS is not supported in this browser")}catch(e){console.error("Failed to load video source:",e),this.emit("error",{error:e})}}extractQualities(t){return t.map(e=>({height:e.height,width:e.width,bitrate:e.bitrate,name:`${e.height}p`}))}handleHlsError(t){var e,s;switch(t.type){case E.ErrorTypes.NETWORK_ERROR:console.error("Network error occurred"),(e=this.hls)==null||e.startLoad();break;case E.ErrorTypes.MEDIA_ERROR:console.error("Media error occurred"),(s=this.hls)==null||s.recoverMediaError();break;default:console.error("Fatal error occurred:",t),this.destroy();break}}getAnalyticsData(){return{currentTime:this.state.currentTime,duration:this.state.duration,quality:this.state.quality,playbackRate:this.state.playbackRate,volume:this.state.volume,muted:this.state.muted}}play(){return this.videoElement.play()}pause(){this.videoElement.pause()}seek(t){this.videoElement.currentTime=t}skipForward(t=10){const e=Math.min(this.state.currentTime+t,this.state.duration);this.seek(e)}skipBackward(t=10){const e=Math.max(this.state.currentTime-t,0);this.seek(e)}setVolume(t){this.videoElement.volume=Math.max(0,Math.min(1,t))}mute(){this.videoElement.muted=!0}unmute(){this.videoElement.muted=!1}setPlaybackRate(t){this.videoElement.playbackRate=t}setQuality(t){this.hls&&(this.hls.currentLevel=t)}enterFullscreen(){this.container.requestFullscreen&&(this.container.requestFullscreen(),this.state.fullscreen=!0,this.emit("fullscreenchange",{fullscreen:!0}))}exitFullscreen(){document.exitFullscreen&&(document.exitFullscreen(),this.state.fullscreen=!1,this.emit("fullscreenchange",{fullscreen:!1}))}getState(){return{...this.state}}getVideoElement(){return this.videoElement}enableSubtitles(t){const e=this.videoElement.textTracks;for(let s=0;s<e.length;s++)e[s].mode=s===t?"showing":"hidden"}disableSubtitles(){const t=this.videoElement.textTracks;for(let e=0;e<t.length;e++)t[e].mode="hidden"}toggleSubtitles(){const t=this.videoElement.textTracks;return Array.from(t).some(s=>s.mode==="showing")?(this.disableSubtitles(),!1):t.length>0?(this.enableSubtitles(0),!0):!1}getSubtitleTracks(){return Array.from(this.videoElement.textTracks)}areSubtitlesEnabled(){const t=this.videoElement.textTracks;return Array.from(t).some(e=>e.mode==="showing")}on(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e)}off(t,e){var s;(s=this.eventListeners.get(t))==null||s.delete(e)}emit(t,e){var r;const s={type:t,data:e,timestamp:Date.now()};(r=this.eventListeners.get(t))==null||r.forEach(i=>{i(s)})}destroy(){this.hls&&(this.hls.destroy(),this.hls=null),this.uiController.destroy(),this.videoElement.remove(),this.eventListeners.clear(),this.analytics.destroy()}}var W={exports:{}},q={};/**
572
572
  * @license React
573
573
  * react-jsx-runtime.production.js
574
574
  *
@@ -576,7 +576,7 @@
576
576
  *
577
577
  * This source code is licensed under the MIT license found in the
578
578
  * LICENSE file in the root directory of this source tree.
579
- */var Z;function ct(){if(Z)return P;Z=1;var c=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function e(s,r,i){var l=null;if(i!==void 0&&(l=""+i),r.key!==void 0&&(l=""+r.key),"key"in r){i={};for(var u in r)u!=="key"&&(i[u]=r[u])}else i=r;return r=i.ref,{$$typeof:c,type:s,key:l,ref:r!==void 0?r:null,props:i}}return P.Fragment=t,P.jsx=e,P.jsxs=e,P}var A={};/**
579
+ */var K;function dt(){if(K)return q;K=1;var l=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function e(s,r,i){var c=null;if(i!==void 0&&(c=""+i),r.key!==void 0&&(c=""+r.key),"key"in r){i={};for(var u in r)u!=="key"&&(i[u]=r[u])}else i=r;return r=i.ref,{$$typeof:l,type:s,key:c,ref:r!==void 0?r:null,props:i}}return q.Fragment=t,q.jsx=e,q.jsxs=e,q}var P={};/**
580
580
  * @license React
581
581
  * react-jsx-runtime.development.js
582
582
  *
@@ -584,9 +584,9 @@
584
584
  *
585
585
  * This source code is licensed under the MIT license found in the
586
586
  * LICENSE file in the root directory of this source tree.
587
- */var K;function ut(){return K||(K=1,process.env.NODE_ENV!=="production"&&function(){function c(n){if(n==null)return null;if(typeof n=="function")return n.$$typeof===B?null:n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case E:return"Fragment";case F:return"Profiler";case I:return"StrictMode";case q:return"Suspense";case _:return"SuspenseList";case y:return"Activity"}if(typeof n=="object")switch(typeof n.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),n.$$typeof){case M:return"Portal";case L:return n.displayName||"Context";case O:return(n._context.displayName||"Context")+".Consumer";case R:var a=n.render;return n=n.displayName,n||(n=a.displayName||a.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case j:return a=n.displayName||null,a!==null?a:c(n.type)||"Memo";case p:a=n._payload,n=n._init;try{return c(n(a))}catch{}}return null}function t(n){return""+n}function e(n){try{t(n);var a=!1}catch{a=!0}if(a){a=console;var d=a.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&n[Symbol.toStringTag]||n.constructor.name||"Object";return d.call(a,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),t(n)}}function s(n){if(n===E)return"<>";if(typeof n=="object"&&n!==null&&n.$$typeof===p)return"<...>";try{var a=c(n);return a?"<"+a+">":"<...>"}catch{return"<...>"}}function r(){var n=z.A;return n===null?null:n.getOwner()}function i(){return Error("react-stack-top-frame")}function l(n){if(W.call(n,"key")){var a=Object.getOwnPropertyDescriptor(n,"key").get;if(a&&a.isReactWarning)return!1}return n.key!==void 0}function u(n,a){function d(){Y||(Y=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",a))}d.isReactWarning=!0,Object.defineProperty(n,"key",{get:d,configurable:!0})}function g(){var n=c(this.type);return Q[n]||(Q[n]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),n=this.props.ref,n!==void 0?n:null}function b(n,a,d,h,$,D){var m=d.ref;return n={$$typeof:T,type:n,key:a,props:d,_owner:h},(m!==void 0?m:null)!==null?Object.defineProperty(n,"ref",{enumerable:!1,get:g}):Object.defineProperty(n,"ref",{enumerable:!1,value:null}),n._store={},Object.defineProperty(n._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(n,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(n,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:$}),Object.defineProperty(n,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.freeze&&(Object.freeze(n.props),Object.freeze(n)),n}function f(n,a,d,h,$,D){var m=a.children;if(m!==void 0)if(h)if(it(m)){for(h=0;h<m.length;h++)S(m[h]);Object.freeze&&Object.freeze(m)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else S(m);if(W.call(a,"key")){m=c(n);var x=Object.keys(a).filter(function(ot){return ot!=="key"});h=0<x.length?"{key: someKey, "+x.join(": ..., ")+": ...}":"{key: someKey}",G[m+h]||(x=0<x.length?"{"+x.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
587
+ */var tt;function ht(){return tt||(tt=1,process.env.NODE_ENV!=="production"&&function(){function l(n){if(n==null)return null;if(typeof n=="function")return n.$$typeof===z?null:n.displayName||n.name||null;if(typeof n=="string")return n;switch(n){case x:return"Fragment";case $:return"Profiler";case B:return"StrictMode";case H:return"Suspense";case N:return"SuspenseList";case R:return"Activity"}if(typeof n=="object")switch(typeof n.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),n.$$typeof){case I:return"Portal";case j:return n.displayName||"Context";case O:return(n._context.displayName||"Context")+".Consumer";case F:var a=n.render;return n=n.displayName,n||(n=a.displayName||a.name||"",n=n!==""?"ForwardRef("+n+")":"ForwardRef"),n;case L:return a=n.displayName||null,a!==null?a:l(n.type)||"Memo";case k:a=n._payload,n=n._init;try{return l(n(a))}catch{}}return null}function t(n){return""+n}function e(n){try{t(n);var a=!1}catch{a=!0}if(a){a=console;var d=a.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&n[Symbol.toStringTag]||n.constructor.name||"Object";return d.call(a,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),t(n)}}function s(n){if(n===x)return"<>";if(typeof n=="object"&&n!==null&&n.$$typeof===k)return"<...>";try{var a=l(n);return a?"<"+a+">":"<...>"}catch{return"<...>"}}function r(){var n=_.A;return n===null?null:n.getOwner()}function i(){return Error("react-stack-top-frame")}function c(n){if(p.call(n,"key")){var a=Object.getOwnPropertyDescriptor(n,"key").get;if(a&&a.isReactWarning)return!1}return n.key!==void 0}function u(n,a){function d(){Q||(Q=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",a))}d.isReactWarning=!0,Object.defineProperty(n,"key",{get:d,configurable:!0})}function f(){var n=l(this.type);return J[n]||(J[n]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),n=this.props.ref,n!==void 0?n:null}function b(n,a,d,h,D,U){var m=d.ref;return n={$$typeof:T,type:n,key:a,props:d,_owner:h},(m!==void 0?m:null)!==null?Object.defineProperty(n,"ref",{enumerable:!1,get:f}):Object.defineProperty(n,"ref",{enumerable:!1,value:null}),n._store={},Object.defineProperty(n._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(n,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(n,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.defineProperty(n,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:U}),Object.freeze&&(Object.freeze(n.props),Object.freeze(n)),n}function y(n,a,d,h,D,U){var m=a.children;if(m!==void 0)if(h)if(g(m)){for(h=0;h<m.length;h++)A(m[h]);Object.freeze&&Object.freeze(m)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else A(m);if(p.call(a,"key")){m=l(n);var C=Object.keys(a).filter(function(at){return at!=="key"});h=0<C.length?"{key: someKey, "+C.join(": ..., ")+": ...}":"{key: someKey}",Z[m+h]||(C=0<C.length?"{"+C.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
588
588
  let props = %s;
589
589
  <%s {...props} />
590
590
  React keys must be passed directly to JSX without using spread:
591
591
  let props = %s;
592
- <%s key={someKey} {...props} />`,h,m,x,m),G[m+h]=!0)}if(m=null,d!==void 0&&(e(d),m=""+d),l(a)&&(e(a.key),m=""+a.key),"key"in a){d={};for(var U in a)U!=="key"&&(d[U]=a[U])}else d=a;return m&&u(d,typeof n=="function"?n.displayName||n.name||"Unknown":n),b(n,m,d,r(),$,D)}function S(n){C(n)?n._store&&(n._store.validated=1):typeof n=="object"&&n!==null&&n.$$typeof===p&&(n._payload.status==="fulfilled"?C(n._payload.value)&&n._payload.value._store&&(n._payload.value._store.validated=1):n._store&&(n._store.validated=1))}function C(n){return typeof n=="object"&&n!==null&&n.$$typeof===T}var w=v,T=Symbol.for("react.transitional.element"),M=Symbol.for("react.portal"),E=Symbol.for("react.fragment"),I=Symbol.for("react.strict_mode"),F=Symbol.for("react.profiler"),O=Symbol.for("react.consumer"),L=Symbol.for("react.context"),R=Symbol.for("react.forward_ref"),q=Symbol.for("react.suspense"),_=Symbol.for("react.suspense_list"),j=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),B=Symbol.for("react.client.reference"),z=w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,W=Object.prototype.hasOwnProperty,it=Array.isArray,H=console.createTask?console.createTask:function(){return null};w={react_stack_bottom_frame:function(n){return n()}};var Y,Q={},J=w.react_stack_bottom_frame.bind(w,i)(),X=H(s(i)),G={};A.Fragment=E,A.jsx=function(n,a,d){var h=1e4>z.recentlyCreatedOwnerStacks++;return f(n,a,d,!1,h?Error("react-stack-top-frame"):J,h?H(s(n)):X)},A.jsxs=function(n,a,d){var h=1e4>z.recentlyCreatedOwnerStacks++;return f(n,a,d,!0,h?Error("react-stack-top-frame"):J,h?H(s(n)):X)}}()),A}process.env.NODE_ENV==="production"?N.exports=ct():N.exports=ut();var st=N.exports;const dt=c=>{const{src:t,autoplay:e,muted:s,controls:r=!0,poster:i,preload:l,theme:u,s3Config:g,analytics:b,hlsConfig:f,onReady:S,onPlay:C,onPause:w,onEnded:T,onTimeUpdate:M,onVolumeChange:E,onError:I,style:F,className:O,width:L="100%",height:R="500px"}=c,q=v.useRef(null),_=v.useRef(null);return v.useEffect(()=>{if(!q.current)return;const j={src:t,container:q.current,autoplay:e,muted:s,controls:r,poster:i,preload:l,theme:u,s3Config:g,analytics:b,hlsConfig:f},p=new V(j);return _.current=p,C&&p.on("play",C),w&&p.on("pause",w),T&&p.on("ended",T),I&&p.on("error",y=>{var B;return I((B=y.data)==null?void 0:B.error)}),M&&p.on("timeupdate",y=>M(y.data.currentTime)),E&&p.on("volumechange",y=>E(y.data.volume,y.data.muted)),S&&S(p),()=>{p.destroy(),_.current=null}},[t]),v.useEffect(()=>{_.current},[e,s,r]),st.jsx("div",{ref:q,className:O,style:{width:typeof L=="number"?`${L}px`:L,height:typeof R=="number"?`${R}px`:R,...F}})},ht=c=>{const[t,e]=v.useState(null),[s,r]=v.useState(null),i=v.useRef(null);return v.useEffect(()=>{if(!i.current)return;const l=new V({...c,container:i.current});e(l);const u=()=>{r(l.getState())};return l.on("play",u),l.on("pause",u),l.on("timeupdate",u),l.on("volumechange",u),l.on("loadedmetadata",u),()=>{l.destroy()}},[c.src]),{containerRef:i,player:t,state:s}},rt=v.createContext({player:null,state:null}),mt=c=>{const{player:t,children:e}=c,[s,r]=v.useState(t.getState());return v.useEffect(()=>{const i=()=>{r(t.getState())};return t.on("play",i),t.on("pause",i),t.on("timeupdate",i),t.on("volumechange",i),t.on("loadedmetadata",i),()=>{}},[t]),st.jsx(rt.Provider,{value:{player:t,state:s},children:e})},pt=()=>{const c=v.useContext(rt);if(!c.player)throw new Error("useWontumPlayerContext must be used within WontumPlayerProvider");return c};exports.Analytics=tt;exports.S3Handler=nt;exports.UIController=et;exports.WontumPlayer=V;exports.WontumPlayerProvider=mt;exports.WontumPlayerReact=dt;exports.useWontumPlayer=ht;exports.useWontumPlayerContext=pt;
592
+ <%s key={someKey} {...props} />`,h,m,C,m),Z[m+h]=!0)}if(m=null,d!==void 0&&(e(d),m=""+d),c(a)&&(e(a.key),m=""+a.key),"key"in a){d={};for(var V in a)V!=="key"&&(d[V]=a[V])}else d=a;return m&&u(d,typeof n=="function"?n.displayName||n.name||"Unknown":n),b(n,m,d,r(),D,U)}function A(n){M(n)?n._store&&(n._store.validated=1):typeof n=="object"&&n!==null&&n.$$typeof===k&&(n._payload.status==="fulfilled"?M(n._payload.value)&&n._payload.value._store&&(n._payload.value._store.validated=1):n._store&&(n._store.validated=1))}function M(n){return typeof n=="object"&&n!==null&&n.$$typeof===T}var w=v,T=Symbol.for("react.transitional.element"),I=Symbol.for("react.portal"),x=Symbol.for("react.fragment"),B=Symbol.for("react.strict_mode"),$=Symbol.for("react.profiler"),O=Symbol.for("react.consumer"),j=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),H=Symbol.for("react.suspense"),N=Symbol.for("react.suspense_list"),L=Symbol.for("react.memo"),k=Symbol.for("react.lazy"),R=Symbol.for("react.activity"),z=Symbol.for("react.client.reference"),_=w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,p=Object.prototype.hasOwnProperty,g=Array.isArray,S=console.createTask?console.createTask:function(){return null};w={react_stack_bottom_frame:function(n){return n()}};var Q,J={},X=w.react_stack_bottom_frame.bind(w,i)(),G=S(s(i)),Z={};P.Fragment=x,P.jsx=function(n,a,d){var h=1e4>_.recentlyCreatedOwnerStacks++;return y(n,a,d,!1,h?Error("react-stack-top-frame"):X,h?S(s(n)):G)},P.jsxs=function(n,a,d){var h=1e4>_.recentlyCreatedOwnerStacks++;return y(n,a,d,!0,h?Error("react-stack-top-frame"):X,h?S(s(n)):G)}}()),P}process.env.NODE_ENV==="production"?W.exports=dt():W.exports=ht();var it=W.exports;const mt=l=>{const{src:t,autoplay:e,muted:s,controls:r=!0,poster:i,preload:c,theme:u,s3Config:f,analytics:b,hlsConfig:y,subtitles:A,stickyControls:M,onReady:w,onPlay:T,onPause:I,onEnded:x,onTimeUpdate:B,onVolumeChange:$,onError:O,onLoadedMetadata:j,onQualityChange:F,style:H,className:N,width:L="100%",height:k="500px"}=l,R=v.useRef(null),z=v.useRef(null);return v.useEffect(()=>{if(!R.current)return;const _={src:t,container:R.current,autoplay:e,muted:s,controls:r,poster:i,preload:c,theme:u,s3Config:f,analytics:b,hlsConfig:y,subtitles:A,stickyControls:M},p=new Y(_);return z.current=p,T&&p.on("play",T),I&&p.on("pause",I),x&&p.on("ended",x),O&&p.on("error",g=>{var S;return O((S=g.data)==null?void 0:S.error)}),j&&p.on("loadedmetadata",j),F&&p.on("qualitychange",g=>F(g.data.level)),B&&p.on("timeupdate",g=>B(g.data.currentTime)),$&&p.on("volumechange",g=>$(g.data.volume,g.data.muted)),w&&w(p),()=>{p.destroy(),z.current=null}},[t]),it.jsx("div",{ref:R,className:N,style:{width:typeof L=="number"?`${L}px`:L,height:typeof k=="number"?`${k}px`:k,...H}})},pt=l=>{const[t,e]=v.useState(null),[s,r]=v.useState(null),i=v.useRef(null);return v.useEffect(()=>{if(!i.current)return;const c=new Y({...l,container:i.current});e(c);const u=()=>{r(c.getState())};return c.on("play",u),c.on("pause",u),c.on("timeupdate",u),c.on("volumechange",u),c.on("loadedmetadata",u),()=>{c.destroy()}},[l.src]),{containerRef:i,player:t,state:s}},ot=et.createContext({player:null,state:null}),vt=l=>{const{player:t,children:e}=l,[s,r]=v.useState(t.getState());return v.useEffect(()=>{const i=()=>{r(t.getState())};return t.on("play",i),t.on("pause",i),t.on("timeupdate",i),t.on("volumechange",i),t.on("loadedmetadata",i),()=>{}},[t]),it.jsx(ot.Provider,{value:{player:t,state:s},children:e})},gt=()=>{const l=et.useContext(ot);if(!l.player)throw new Error("useWontumPlayerContext must be used within WontumPlayerProvider");return l};exports.Analytics=nt;exports.S3Handler=rt;exports.UIController=st;exports.WontumPlayer=Y;exports.WontumPlayerProvider=vt;exports.WontumPlayerReact=mt;exports.useWontumPlayer=pt;exports.useWontumPlayerContext=gt;
@@ -1,9 +1,10 @@
1
1
  var at = Object.defineProperty;
2
2
  var lt = (c, t, e) => t in c ? at(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e;
3
3
  var o = (c, t, e) => lt(c, typeof t != "symbol" ? t + "" : t, e);
4
- import w from "hls.js";
5
- import Y, { useRef as U, useEffect as $, useState as V } from "react";
6
- class ct {
4
+ import k from "hls.js";
5
+ import * as nt from "react";
6
+ import ct, { useRef as V, useEffect as Q, useState as W } from "react";
7
+ class ut {
7
8
  constructor(t) {
8
9
  o(this, "config");
9
10
  o(this, "sessionId");
@@ -117,7 +118,7 @@ class ct {
117
118
  (t = this.config) != null && t.enabled && this.trackEvent("session_end", this.getSessionData()), this.events = [];
118
119
  }
119
120
  }
120
- class ut {
121
+ class dt {
121
122
  constructor(t, e) {
122
123
  o(this, "container");
123
124
  o(this, "player");
@@ -144,8 +145,8 @@ class ut {
144
145
  injectStyles() {
145
146
  const t = "wontum-player-styles";
146
147
  if (document.getElementById(t)) return;
147
- const e = this.player.config.theme || {}, s = e.primaryColor || "#3b82f6", r = e.accentColor || "#2563eb", i = e.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", l = e.controlsBackground || "linear-gradient(to top, rgba(0,0,0,0.8), transparent)", u = e.buttonHoverBg || "rgba(255, 255, 255, 0.1)", v = e.progressHeight || "6px", y = e.borderRadius || "4px", g = document.createElement("style");
148
- g.id = t, g.textContent = `
148
+ const e = this.player.config.theme || {}, s = e.primaryColor || "#3b82f6", r = e.accentColor || "#2563eb", i = e.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", l = e.controlsBackground || "linear-gradient(to top, rgba(0,0,0,0.8), transparent)", u = e.buttonHoverBg || "rgba(255, 255, 255, 0.1)", g = e.progressHeight || "6px", y = e.borderRadius || "4px", f = document.createElement("style");
149
+ f.id = t, f.textContent = `
149
150
  .wontum-player-container {
150
151
  position: relative;
151
152
  background: #000;
@@ -155,7 +156,7 @@ class ut {
155
156
  --accent-color: ${r};
156
157
  --controls-bg: ${l};
157
158
  --button-hover: ${u};
158
- --progress-height: ${v};
159
+ --progress-height: ${g};
159
160
  --border-radius: ${y};
160
161
  }
161
162
 
@@ -610,7 +611,7 @@ class ut {
610
611
  transform: translateY(0) !important;
611
612
  pointer-events: all !important;
612
613
  }
613
- `, document.head.appendChild(g), this.container.classList.add("wontum-player-container");
614
+ `, document.head.appendChild(f), this.container.classList.add("wontum-player-container");
614
615
  }
615
616
  createProgressBar() {
616
617
  const t = document.createElement("div");
@@ -775,7 +776,7 @@ class ut {
775
776
  `, t.querySelectorAll(".wontum-subtitle-option").forEach((r) => {
776
777
  r.addEventListener("click", (i) => {
777
778
  const l = i.target, u = parseInt(l.dataset.track || "-1");
778
- u === -1 ? this.player.disableSubtitles() : this.player.enableSubtitles(u), t.querySelectorAll(".wontum-subtitle-option").forEach((v) => v.classList.remove("active")), l.classList.add("active"), t.classList.remove("active");
779
+ u === -1 ? this.player.disableSubtitles() : this.player.enableSubtitles(u), t.querySelectorAll(".wontum-subtitle-option").forEach((g) => g.classList.remove("active")), l.classList.add("active"), t.classList.remove("active");
779
780
  });
780
781
  });
781
782
  }
@@ -789,8 +790,8 @@ class ut {
789
790
  `
790
791
  ).join(""), t.querySelectorAll(".wontum-speed-option").forEach((i) => {
791
792
  i.addEventListener("click", (l) => {
792
- const u = l.target, v = parseFloat(u.dataset.speed || "1");
793
- this.player.setPlaybackRate(v), t.querySelectorAll(".wontum-speed-option").forEach((y) => y.classList.remove("active")), u.classList.add("active"), t.classList.remove("active");
793
+ const u = l.target, g = parseFloat(u.dataset.speed || "1");
794
+ this.player.setPlaybackRate(g), t.querySelectorAll(".wontum-speed-option").forEach((y) => y.classList.remove("active")), u.classList.add("active"), t.classList.remove("active");
794
795
  });
795
796
  });
796
797
  }
@@ -890,7 +891,7 @@ class ut {
890
891
  this.hideControlsTimeout && clearTimeout(this.hideControlsTimeout), this.controlsContainer.remove();
891
892
  }
892
893
  }
893
- class dt {
894
+ class ht {
894
895
  constructor(t) {
895
896
  o(this, "config");
896
897
  o(this, "urlCache", /* @__PURE__ */ new Map());
@@ -994,7 +995,7 @@ class dt {
994
995
  this.urlCache.clear(), this.signedUrls.clear();
995
996
  }
996
997
  }
997
- class nt {
998
+ class st {
998
999
  constructor(t) {
999
1000
  o(this, "container");
1000
1001
  o(this, "videoElement");
@@ -1020,7 +1021,7 @@ class nt {
1020
1021
  });
1021
1022
  if (this.config = t, this.container = typeof t.container == "string" ? document.querySelector(t.container) : t.container, !this.container)
1022
1023
  throw new Error("Container element not found");
1023
- this.analytics = new ct(t.analytics), this.s3Handler = new dt(t.s3Config), this.videoElement = this.createVideoElement(), this.container.appendChild(this.videoElement), this.uiController = new ut(this.container, this), this.setupVideoListeners(), this.loadSource(t.src), t.autoplay && (this.videoElement.autoplay = !0), t.muted && this.mute(), t.poster && (this.videoElement.poster = t.poster), t.preload && (this.videoElement.preload = t.preload), t.subtitles && this.addSubtitleTracks(t.subtitles);
1024
+ this.analytics = new ut(t.analytics), this.s3Handler = new ht(t.s3Config), this.videoElement = this.createVideoElement(), this.container.appendChild(this.videoElement), this.uiController = new dt(this.container, this), this.setupVideoListeners(), this.loadSource(t.src), t.autoplay && (this.videoElement.autoplay = !0), t.muted && this.mute(), t.poster && (this.videoElement.poster = t.poster), t.preload && (this.videoElement.preload = t.preload), t.subtitles && this.addSubtitleTracks(t.subtitles);
1024
1025
  }
1025
1026
  addSubtitleTracks(t) {
1026
1027
  t.forEach((e) => {
@@ -1088,15 +1089,15 @@ class nt {
1088
1089
  async loadSource(t) {
1089
1090
  try {
1090
1091
  const e = await this.s3Handler.processUrl(t);
1091
- if (w.isSupported())
1092
- this.hls = new w(this.config.hlsConfig), this.hls.loadSource(e), this.hls.attachMedia(this.videoElement), this.hls.on(w.Events.MANIFEST_PARSED, (s, r) => {
1092
+ if (k.isSupported())
1093
+ this.hls = new k(this.config.hlsConfig), this.hls.loadSource(e), this.hls.attachMedia(this.videoElement), this.hls.on(k.Events.MANIFEST_PARSED, (s, r) => {
1093
1094
  const i = this.extractQualities(r.levels);
1094
1095
  this.state.availableQualities = i.map((l) => l.name), this.emit("loadedmetadata", { qualities: i });
1095
- }), this.hls.on(w.Events.LEVEL_SWITCHED, (s, r) => {
1096
+ }), this.hls.on(k.Events.LEVEL_SWITCHED, (s, r) => {
1096
1097
  var l;
1097
1098
  const i = (l = this.hls) == null ? void 0 : l.levels[r.level];
1098
1099
  i && (this.state.quality = `${i.height}p`, this.emit("qualitychange", { quality: this.state.quality }));
1099
- }), this.hls.on(w.Events.ERROR, (s, r) => {
1100
+ }), this.hls.on(k.Events.ERROR, (s, r) => {
1100
1101
  r.fatal && this.handleHlsError(r);
1101
1102
  });
1102
1103
  else if (this.videoElement.canPlayType("application/vnd.apple.mpegurl"))
@@ -1118,10 +1119,10 @@ class nt {
1118
1119
  handleHlsError(t) {
1119
1120
  var e, s;
1120
1121
  switch (t.type) {
1121
- case w.ErrorTypes.NETWORK_ERROR:
1122
+ case k.ErrorTypes.NETWORK_ERROR:
1122
1123
  console.error("Network error occurred"), (e = this.hls) == null || e.startLoad();
1123
1124
  break;
1124
- case w.ErrorTypes.MEDIA_ERROR:
1125
+ case k.ErrorTypes.MEDIA_ERROR:
1125
1126
  console.error("Media error occurred"), (s = this.hls) == null || s.recoverMediaError();
1126
1127
  break;
1127
1128
  default:
@@ -1242,7 +1243,7 @@ class nt {
1242
1243
  this.hls && (this.hls.destroy(), this.hls = null), this.uiController.destroy(), this.videoElement.remove(), this.eventListeners.clear(), this.analytics.destroy();
1243
1244
  }
1244
1245
  }
1245
- var W = { exports: {} }, q = {};
1246
+ var Y = { exports: {} }, _ = {};
1246
1247
  /**
1247
1248
  * @license React
1248
1249
  * react-jsx-runtime.production.js
@@ -1253,8 +1254,8 @@ var W = { exports: {} }, q = {};
1253
1254
  * LICENSE file in the root directory of this source tree.
1254
1255
  */
1255
1256
  var tt;
1256
- function ht() {
1257
- if (tt) return q;
1257
+ function mt() {
1258
+ if (tt) return _;
1258
1259
  tt = 1;
1259
1260
  var c = Symbol.for("react.transitional.element"), t = Symbol.for("react.fragment");
1260
1261
  function e(s, r, i) {
@@ -1272,9 +1273,9 @@ function ht() {
1272
1273
  props: i
1273
1274
  };
1274
1275
  }
1275
- return q.Fragment = t, q.jsx = e, q.jsxs = e, q;
1276
+ return _.Fragment = t, _.jsx = e, _.jsxs = e, _;
1276
1277
  }
1277
- var P = {};
1278
+ var q = {};
1278
1279
  /**
1279
1280
  * @license React
1280
1281
  * react-jsx-runtime.development.js
@@ -1285,43 +1286,43 @@ var P = {};
1285
1286
  * LICENSE file in the root directory of this source tree.
1286
1287
  */
1287
1288
  var et;
1288
- function mt() {
1289
+ function pt() {
1289
1290
  return et || (et = 1, process.env.NODE_ENV !== "production" && function() {
1290
1291
  function c(n) {
1291
1292
  if (n == null) return null;
1292
1293
  if (typeof n == "function")
1293
- return n.$$typeof === I ? null : n.displayName || n.name || null;
1294
+ return n.$$typeof === O ? null : n.displayName || n.name || null;
1294
1295
  if (typeof n == "string") return n;
1295
1296
  switch (n) {
1296
- case k:
1297
+ case E:
1297
1298
  return "Fragment";
1298
- case F:
1299
+ case B:
1299
1300
  return "Profiler";
1300
- case M:
1301
+ case I:
1301
1302
  return "StrictMode";
1302
- case R:
1303
+ case D:
1303
1304
  return "Suspense";
1304
- case _:
1305
+ case H:
1305
1306
  return "SuspenseList";
1306
- case f:
1307
+ case L:
1307
1308
  return "Activity";
1308
1309
  }
1309
1310
  if (typeof n == "object")
1310
1311
  switch (typeof n.tag == "number" && console.error(
1311
1312
  "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
1312
1313
  ), n.$$typeof) {
1313
- case A:
1314
+ case M:
1314
1315
  return "Portal";
1315
- case T:
1316
+ case F:
1316
1317
  return n.displayName || "Context";
1317
- case z:
1318
+ case $:
1318
1319
  return (n._context.displayName || "Context") + ".Consumer";
1319
- case L:
1320
+ case z:
1320
1321
  var a = n.render;
1321
1322
  return n = n.displayName, n || (n = a.displayName || a.name || "", n = n !== "" ? "ForwardRef(" + n + ")" : "ForwardRef"), n;
1322
- case O:
1323
+ case T:
1323
1324
  return a = n.displayName || null, a !== null ? a : c(n.type) || "Memo";
1324
- case p:
1325
+ case w:
1325
1326
  a = n._payload, n = n._init;
1326
1327
  try {
1327
1328
  return c(n(a));
@@ -1351,8 +1352,8 @@ function mt() {
1351
1352
  }
1352
1353
  }
1353
1354
  function s(n) {
1354
- if (n === k) return "<>";
1355
- if (typeof n == "object" && n !== null && n.$$typeof === p)
1355
+ if (n === E) return "<>";
1356
+ if (typeof n == "object" && n !== null && n.$$typeof === w)
1356
1357
  return "<...>";
1357
1358
  try {
1358
1359
  var a = c(n);
@@ -1362,14 +1363,14 @@ function mt() {
1362
1363
  }
1363
1364
  }
1364
1365
  function r() {
1365
- var n = j.A;
1366
+ var n = R.A;
1366
1367
  return n === null ? null : n.getOwner();
1367
1368
  }
1368
1369
  function i() {
1369
1370
  return Error("react-stack-top-frame");
1370
1371
  }
1371
1372
  function l(n) {
1372
- if (Q.call(n, "key")) {
1373
+ if (p.call(n, "key")) {
1373
1374
  var a = Object.getOwnPropertyDescriptor(n, "key").get;
1374
1375
  if (a && a.isReactWarning) return !1;
1375
1376
  }
@@ -1387,13 +1388,13 @@ function mt() {
1387
1388
  configurable: !0
1388
1389
  });
1389
1390
  }
1390
- function v() {
1391
+ function g() {
1391
1392
  var n = c(this.type);
1392
1393
  return X[n] || (X[n] = !0, console.error(
1393
1394
  "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
1394
1395
  )), n = this.props.ref, n !== void 0 ? n : null;
1395
1396
  }
1396
- function y(n, a, d, h, B, H) {
1397
+ function y(n, a, d, h, j, N) {
1397
1398
  var m = d.ref;
1398
1399
  return n = {
1399
1400
  $$typeof: C,
@@ -1403,7 +1404,7 @@ function mt() {
1403
1404
  _owner: h
1404
1405
  }, (m !== void 0 ? m : null) !== null ? Object.defineProperty(n, "ref", {
1405
1406
  enumerable: !1,
1406
- get: v
1407
+ get: g
1407
1408
  }) : Object.defineProperty(n, "ref", { enumerable: !1, value: null }), n._store = {}, Object.defineProperty(n._store, "validated", {
1408
1409
  configurable: !1,
1409
1410
  enumerable: !1,
@@ -1418,33 +1419,33 @@ function mt() {
1418
1419
  configurable: !1,
1419
1420
  enumerable: !1,
1420
1421
  writable: !0,
1421
- value: B
1422
+ value: j
1422
1423
  }), Object.defineProperty(n, "_debugTask", {
1423
1424
  configurable: !1,
1424
1425
  enumerable: !1,
1425
1426
  writable: !0,
1426
- value: H
1427
+ value: N
1427
1428
  }), Object.freeze && (Object.freeze(n.props), Object.freeze(n)), n;
1428
1429
  }
1429
- function g(n, a, d, h, B, H) {
1430
+ function f(n, a, d, h, j, N) {
1430
1431
  var m = a.children;
1431
1432
  if (m !== void 0)
1432
1433
  if (h)
1433
- if (it(m)) {
1434
+ if (v(m)) {
1434
1435
  for (h = 0; h < m.length; h++)
1435
- x(m[h]);
1436
+ P(m[h]);
1436
1437
  Object.freeze && Object.freeze(m);
1437
1438
  } else
1438
1439
  console.error(
1439
1440
  "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
1440
1441
  );
1441
- else x(m);
1442
- if (Q.call(a, "key")) {
1442
+ else P(m);
1443
+ if (p.call(a, "key")) {
1443
1444
  m = c(n);
1444
- var E = Object.keys(a).filter(function(ot) {
1445
+ var S = Object.keys(a).filter(function(ot) {
1445
1446
  return ot !== "key";
1446
1447
  });
1447
- h = 0 < E.length ? "{key: someKey, " + E.join(": ..., ") + ": ...}" : "{key: someKey}", K[m + h] || (E = 0 < E.length ? "{" + E.join(": ..., ") + ": ...}" : "{}", console.error(
1448
+ h = 0 < S.length ? "{key: someKey, " + S.join(": ..., ") + ": ...}" : "{key: someKey}", K[m + h] || (S = 0 < S.length ? "{" + S.join(": ..., ") + ": ...}" : "{}", console.error(
1448
1449
  `A props object containing a "key" prop is being spread into JSX:
1449
1450
  let props = %s;
1450
1451
  <%s {...props} />
@@ -1453,14 +1454,14 @@ React keys must be passed directly to JSX without using spread:
1453
1454
  <%s key={someKey} {...props} />`,
1454
1455
  h,
1455
1456
  m,
1456
- E,
1457
+ S,
1457
1458
  m
1458
1459
  ), K[m + h] = !0);
1459
1460
  }
1460
1461
  if (m = null, d !== void 0 && (e(d), m = "" + d), l(a) && (e(a.key), m = "" + a.key), "key" in a) {
1461
1462
  d = {};
1462
- for (var N in a)
1463
- N !== "key" && (d[N] = a[N]);
1463
+ for (var U in a)
1464
+ U !== "key" && (d[U] = a[U]);
1464
1465
  } else d = a;
1465
1466
  return m && u(
1466
1467
  d,
@@ -1470,17 +1471,17 @@ React keys must be passed directly to JSX without using spread:
1470
1471
  m,
1471
1472
  d,
1472
1473
  r(),
1473
- B,
1474
- H
1474
+ j,
1475
+ N
1475
1476
  );
1476
1477
  }
1477
- function x(n) {
1478
- S(n) ? n._store && (n._store.validated = 1) : typeof n == "object" && n !== null && n.$$typeof === p && (n._payload.status === "fulfilled" ? S(n._payload.value) && n._payload.value._store && (n._payload.value._store.validated = 1) : n._store && (n._store.validated = 1));
1478
+ function P(n) {
1479
+ A(n) ? n._store && (n._store.validated = 1) : typeof n == "object" && n !== null && n.$$typeof === w && (n._payload.status === "fulfilled" ? A(n._payload.value) && n._payload.value._store && (n._payload.value._store.validated = 1) : n._store && (n._store.validated = 1));
1479
1480
  }
1480
- function S(n) {
1481
+ function A(n) {
1481
1482
  return typeof n == "object" && n !== null && n.$$typeof === C;
1482
1483
  }
1483
- var b = Y, C = Symbol.for("react.transitional.element"), A = Symbol.for("react.portal"), k = Symbol.for("react.fragment"), M = Symbol.for("react.strict_mode"), F = Symbol.for("react.profiler"), z = Symbol.for("react.consumer"), T = Symbol.for("react.context"), L = Symbol.for("react.forward_ref"), R = Symbol.for("react.suspense"), _ = Symbol.for("react.suspense_list"), O = Symbol.for("react.memo"), p = Symbol.for("react.lazy"), f = Symbol.for("react.activity"), I = Symbol.for("react.client.reference"), j = b.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Q = Object.prototype.hasOwnProperty, it = Array.isArray, D = console.createTask ? console.createTask : function() {
1484
+ var b = ct, C = Symbol.for("react.transitional.element"), M = Symbol.for("react.portal"), E = Symbol.for("react.fragment"), I = Symbol.for("react.strict_mode"), B = Symbol.for("react.profiler"), $ = Symbol.for("react.consumer"), F = Symbol.for("react.context"), z = Symbol.for("react.forward_ref"), D = Symbol.for("react.suspense"), H = Symbol.for("react.suspense_list"), T = Symbol.for("react.memo"), w = Symbol.for("react.lazy"), L = Symbol.for("react.activity"), O = Symbol.for("react.client.reference"), R = b.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, p = Object.prototype.hasOwnProperty, v = Array.isArray, x = console.createTask ? console.createTask : function() {
1484
1485
  return null;
1485
1486
  };
1486
1487
  b = {
@@ -1491,33 +1492,33 @@ React keys must be passed directly to JSX without using spread:
1491
1492
  var J, X = {}, G = b.react_stack_bottom_frame.bind(
1492
1493
  b,
1493
1494
  i
1494
- )(), Z = D(s(i)), K = {};
1495
- P.Fragment = k, P.jsx = function(n, a, d) {
1496
- var h = 1e4 > j.recentlyCreatedOwnerStacks++;
1497
- return g(
1495
+ )(), Z = x(s(i)), K = {};
1496
+ q.Fragment = E, q.jsx = function(n, a, d) {
1497
+ var h = 1e4 > R.recentlyCreatedOwnerStacks++;
1498
+ return f(
1498
1499
  n,
1499
1500
  a,
1500
1501
  d,
1501
1502
  !1,
1502
1503
  h ? Error("react-stack-top-frame") : G,
1503
- h ? D(s(n)) : Z
1504
+ h ? x(s(n)) : Z
1504
1505
  );
1505
- }, P.jsxs = function(n, a, d) {
1506
- var h = 1e4 > j.recentlyCreatedOwnerStacks++;
1507
- return g(
1506
+ }, q.jsxs = function(n, a, d) {
1507
+ var h = 1e4 > R.recentlyCreatedOwnerStacks++;
1508
+ return f(
1508
1509
  n,
1509
1510
  a,
1510
1511
  d,
1511
1512
  !0,
1512
1513
  h ? Error("react-stack-top-frame") : G,
1513
- h ? D(s(n)) : Z
1514
+ h ? x(s(n)) : Z
1514
1515
  );
1515
1516
  };
1516
- }()), P;
1517
+ }()), q;
1517
1518
  }
1518
- process.env.NODE_ENV === "production" ? W.exports = ht() : W.exports = mt();
1519
- var st = W.exports;
1520
- const ft = (c) => {
1519
+ process.env.NODE_ENV === "production" ? Y.exports = mt() : Y.exports = pt();
1520
+ var rt = Y.exports;
1521
+ const yt = (c) => {
1521
1522
  const {
1522
1523
  src: t,
1523
1524
  autoplay: e,
@@ -1526,61 +1527,65 @@ const ft = (c) => {
1526
1527
  poster: i,
1527
1528
  preload: l,
1528
1529
  theme: u,
1529
- s3Config: v,
1530
+ s3Config: g,
1530
1531
  analytics: y,
1531
- hlsConfig: g,
1532
- onReady: x,
1533
- onPlay: S,
1534
- onPause: b,
1535
- onEnded: C,
1536
- onTimeUpdate: A,
1537
- onVolumeChange: k,
1538
- onError: M,
1539
- style: F,
1540
- className: z,
1532
+ hlsConfig: f,
1533
+ subtitles: P,
1534
+ stickyControls: A,
1535
+ onReady: b,
1536
+ onPlay: C,
1537
+ onPause: M,
1538
+ onEnded: E,
1539
+ onTimeUpdate: I,
1540
+ onVolumeChange: B,
1541
+ onError: $,
1542
+ onLoadedMetadata: F,
1543
+ onQualityChange: z,
1544
+ style: D,
1545
+ className: H,
1541
1546
  width: T = "100%",
1542
- height: L = "500px"
1543
- } = c, R = U(null), _ = U(null);
1544
- return $(() => {
1545
- if (!R.current) return;
1546
- const O = {
1547
+ height: w = "500px"
1548
+ } = c, L = V(null), O = V(null);
1549
+ return Q(() => {
1550
+ if (!L.current) return;
1551
+ const R = {
1547
1552
  src: t,
1548
- container: R.current,
1553
+ container: L.current,
1549
1554
  autoplay: e,
1550
1555
  muted: s,
1551
1556
  controls: r,
1552
1557
  poster: i,
1553
1558
  preload: l,
1554
1559
  theme: u,
1555
- s3Config: v,
1560
+ s3Config: g,
1556
1561
  analytics: y,
1557
- hlsConfig: g
1558
- }, p = new nt(O);
1559
- return _.current = p, S && p.on("play", S), b && p.on("pause", b), C && p.on("ended", C), M && p.on("error", (f) => {
1560
- var I;
1561
- return M((I = f.data) == null ? void 0 : I.error);
1562
- }), A && p.on("timeupdate", (f) => A(f.data.currentTime)), k && p.on("volumechange", (f) => k(f.data.volume, f.data.muted)), x && x(p), () => {
1563
- p.destroy(), _.current = null;
1562
+ hlsConfig: f,
1563
+ subtitles: P,
1564
+ stickyControls: A
1565
+ }, p = new st(R);
1566
+ return O.current = p, C && p.on("play", C), M && p.on("pause", M), E && p.on("ended", E), $ && p.on("error", (v) => {
1567
+ var x;
1568
+ return $((x = v.data) == null ? void 0 : x.error);
1569
+ }), F && p.on("loadedmetadata", F), z && p.on("qualitychange", (v) => z(v.data.level)), I && p.on("timeupdate", (v) => I(v.data.currentTime)), B && p.on("volumechange", (v) => B(v.data.volume, v.data.muted)), b && b(p), () => {
1570
+ p.destroy(), O.current = null;
1564
1571
  };
1565
- }, [t]), $(() => {
1566
- _.current;
1567
- }, [e, s, r]), /* @__PURE__ */ st.jsx(
1572
+ }, [t]), /* @__PURE__ */ rt.jsx(
1568
1573
  "div",
1569
1574
  {
1570
- ref: R,
1571
- className: z,
1575
+ ref: L,
1576
+ className: H,
1572
1577
  style: {
1573
1578
  width: typeof T == "number" ? `${T}px` : T,
1574
- height: typeof L == "number" ? `${L}px` : L,
1575
- ...F
1579
+ height: typeof w == "number" ? `${w}px` : w,
1580
+ ...D
1576
1581
  }
1577
1582
  }
1578
1583
  );
1579
- }, yt = (c) => {
1580
- const [t, e] = V(null), [s, r] = V(null), i = U(null);
1581
- return $(() => {
1584
+ }, bt = (c) => {
1585
+ const [t, e] = W(null), [s, r] = W(null), i = V(null);
1586
+ return Q(() => {
1582
1587
  if (!i.current) return;
1583
- const l = new nt({
1588
+ const l = new st({
1584
1589
  ...c,
1585
1590
  container: i.current
1586
1591
  });
@@ -1596,31 +1601,31 @@ const ft = (c) => {
1596
1601
  player: t,
1597
1602
  state: s
1598
1603
  };
1599
- }, rt = Y.createContext({
1604
+ }, it = nt.createContext({
1600
1605
  player: null,
1601
1606
  state: null
1602
- }), bt = (c) => {
1603
- const { player: t, children: e } = c, [s, r] = V(t.getState());
1604
- return $(() => {
1607
+ }), wt = (c) => {
1608
+ const { player: t, children: e } = c, [s, r] = W(t.getState());
1609
+ return Q(() => {
1605
1610
  const i = () => {
1606
1611
  r(t.getState());
1607
1612
  };
1608
1613
  return t.on("play", i), t.on("pause", i), t.on("timeupdate", i), t.on("volumechange", i), t.on("loadedmetadata", i), () => {
1609
1614
  };
1610
- }, [t]), /* @__PURE__ */ st.jsx(rt.Provider, { value: { player: t, state: s }, children: e });
1611
- }, wt = () => {
1612
- const c = Y.useContext(rt);
1615
+ }, [t]), /* @__PURE__ */ rt.jsx(it.Provider, { value: { player: t, state: s }, children: e });
1616
+ }, kt = () => {
1617
+ const c = nt.useContext(it);
1613
1618
  if (!c.player)
1614
1619
  throw new Error("useWontumPlayerContext must be used within WontumPlayerProvider");
1615
1620
  return c;
1616
1621
  };
1617
1622
  export {
1618
- ct as Analytics,
1619
- dt as S3Handler,
1620
- ut as UIController,
1621
- nt as WontumPlayer,
1622
- bt as WontumPlayerProvider,
1623
- ft as WontumPlayerReact,
1624
- yt as useWontumPlayer,
1625
- wt as useWontumPlayerContext
1623
+ ut as Analytics,
1624
+ ht as S3Handler,
1625
+ dt as UIController,
1626
+ st as WontumPlayer,
1627
+ wt as WontumPlayerProvider,
1628
+ yt as WontumPlayerReact,
1629
+ bt as useWontumPlayer,
1630
+ kt as useWontumPlayerContext
1626
1631
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obipascal/player",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A modern HLS video player SDK for educational platforms with S3 integration",
5
5
  "main": "dist/wontum-player.cjs.js",
6
6
  "module": "dist/wontum-player.esm.js",