@moviie/player-expo 0.5.5 → 0.6.1

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
@@ -247,8 +247,8 @@ Or use `PLAYER_API_EVENTS.ENDED` with `useMoviieEvent` for a generic handler.
247
247
 
248
248
  ## Requirements
249
249
 
250
- - Expo SDK 52+
251
- - `expo-video` 2+
250
+ - Expo SDK 53+
251
+ - `expo-video` 3+
252
252
  - Dev client required — `expo-video` does not work in Expo Go
253
253
 
254
254
  ---
@@ -5,7 +5,7 @@ import * as Application from 'expo-application';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
 
7
7
  // src/constants.ts
8
- var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.5.5";
8
+ var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.6.1";
9
9
  var MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1e3;
10
10
  var MOVIIE_PLAYBACK_PROFILE = {
11
11
  VSL: "vsl",
@@ -290,5 +290,5 @@ function MoviieProvider({
290
290
  }
291
291
 
292
292
  export { EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV, EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV, MOVIIE_BRANDING_MARKETING_ORIGIN, MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN, MOVIIE_BRANDING_UTM_PARAM_MEDIUM, MOVIIE_BRANDING_UTM_PARAM_SOURCE, MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH, MOVIIE_EMBED_BRAND_UTM, MOVIIE_EMBED_BRAND_VIEW_BOX, MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE, MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS, MOVIIE_PLAYBACK_PROFILE, MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR, MOVIIE_PLAYER_EXPO_PKG_VERSION, MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS, MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX, MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX, MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT, MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX, MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS, MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX, MOVIIE_SKIN_CENTER_PLAY_ICON_PX, MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY, MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT, MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX, MOVIIE_SKIN_CHROME_FOREGROUND_HEX, MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX, MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA, MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA, MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID, MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID, MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT, MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS, MOVIIE_SKIN_CONTROLS_FADE_MS, MOVIIE_SKIN_CONTROL_ICON_PX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START, MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT, MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX, MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS, MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT, MOVIIE_SKIN_DEFAULT_ACCENT_HEX, MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_FULLSCREEN_TOP_ICON_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT, MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX, MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX, MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX, MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT, MOVIIE_SKIN_LAYOUT_SCALE_MAX, MOVIIE_SKIN_LAYOUT_SCALE_MIN, MOVIIE_SKIN_SEEK_ICON_PX, MOVIIE_SKIN_SEEK_JUMP_SECONDS, MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX, MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA, MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS, MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS, MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP, MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP, MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA, MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX, MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER, MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP, MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX, MOVIIE_SKIN_TOP_ICON_CAST_VISUAL_SCALE, MOVIIE_SKIN_TOP_ICON_FULLSCREEN_VISUAL_SCALE, MOVIIE_SKIN_TOP_ICON_PIP_VISUAL_SCALE, MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD, MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP, MOVIIE_SMART_PROGRESS_CONFIG, MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS, MOVIIE_SMART_PROGRESS_Z_INDEX, MOVIIE_VIDEO_DEFAULT_CONTENT_FIT, MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY, MOVIIE_WATCH_EMBED_JS_PATH, MOVIIE_WATCH_ORIGIN_DEFAULT, MoviieProvider, SecureStoreViewerTokenStore, useMoviieContext, warnOnce };
293
- //# sourceMappingURL=chunk-XMG66JV7.mjs.map
294
- //# sourceMappingURL=chunk-XMG66JV7.mjs.map
293
+ //# sourceMappingURL=chunk-TWUGAJRM.mjs.map
294
+ //# sourceMappingURL=chunk-TWUGAJRM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/apply-expo-moviie-endpoints.ts","../src/lib/warn-once.ts","../src/secure-store-viewer-token-store.ts","../src/platform/native-application-id.ts","../src/platform/platform-client-info.ts","../src/provider/moviie-provider.tsx"],"names":["MemoryViewerTokenStore"],"mappings":";;;;;;;AAAO,IAAM,8BAAA,GAAiC;AAEvC,IAAM,mCAAA,GAAsC,IAAI,EAAA,GAAK;AAGrD,IAAM,uBAAA,GAA0B;AAAA,EACrC,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ;AACV;AAMO,IAAM,4BAAA,GAA+B;AAAA,EAC1C,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,gBAAA,EAAkB;AACpB;AAGO,IAAM,wCAAA,GAA2C;AAGjD,IAAM,mCAAA,GAAsC;AAE5C,IAAM,6BAAA,GAAgC;AAMtC,IAAM,uCAAA,GAA0C;AAGhD,IAAM,oCAAA,GAAuC;AAG7C,IAAM,gCAAA,GAAmC;AAAA,EAC9C,QAAA,EAAU,SAAA;AAAA,EACV,UAAA,EAAY;AACd;AAEO,IAAM,gCAAA,GAAmC;AAGzC,IAAM,2BAAA,GAA8B;AAKpC,IAAM,mCAAA,GAAsC;AAG5C,IAAM,0BAAA,GAA6B;AAMnC,IAAM,uCAAA,GAA0C;AAUhD,IAAM,mCAAA,GAAsC;AAM5C,IAAM,sCAAA,GAAyC;AAE/C,IAAM,gCAAA,GAAmC;AACzC,IAAM,gCAAA,GAAmC;AACzC,IAAM,kCAAA,GAAqC;AAM3C,IAAM,sBAAA,GAAyB;AAAA,EACpC,MAAA,EAAQ,qBAAA;AAAA,EACR,MAAA,EAAQ,mBAAA;AAAA,EACR,QAAA,EAAU;AACZ;AAEO,IAAM,8BAAA,GAAiC;AAMvC,IAAM,iCAAA,GAAoC;AAE1C,IAAM,4BAAA,GAA+B;AAIrC,IAAM,2BAAA,GAA8B;AAMpC,IAAM,qCAAA,GAAwC;AAG9C,IAAM,4BAAA,GAA+B;AAKrC,IAAM,4BAAA,GAA+B;AAMrC,IAAM,sCAAA,GAAyC;AAO/C,IAAM,2DAAA,GAA8D;AAGpE,IAAM,6CAAA,GAAgD;AAKtD,IAAM,8DAAA,GAAiE;AAKvE,IAAM,oDAAA,GAAuD;AAO7D,IAAM,wDAAA,GAA2D;AAQjE,IAAM,sCAAA,GAAyC;AAC/C,IAAM,qCAAA,GAAwC;AAC9C,IAAM,4CAAA,GAA+C;AAOrD,IAAM,mDAAA,GAAsD;AAG5D,IAAM,+CAAA,GAAkD;AAGxD,IAAM,oCAAA,GAAuC,GAAA;AAG7C,IAAM,mCAAA,GACX,cAAc,oCAAoC,CAAA,CAAA;AAG7C,IAAM,uCAAA,GAA0C;AAKhD,IAAM,0CAAA,GAA6C;AAGnD,IAAM,qCAAA,GAAwC;AAG9C,IAAM,sCAAA,GAAyC;AAO/C,IAAM,uDAAA,GAA0D;AAMhE,IAAM,6DAAA,GAAgE;AAMtE,IAAM,oDAAA,GAAuD;AAG7D,IAAM,8CAAA,GACX;AAEK,IAAM,2CAAA,GACX;AAGK,IAAM,qCAAA,GAAwC;AAG9C,IAAM,iCAAA,GAAoC;AAM1C,IAAM,yCAAA,GAA4C;AAAA,EACvD,SAAA,EAAW,CAAA;AAAA,EACX,cAAA,EAAgB,CAAA;AAAA,EAChB,eAAA,EAAiB;AACnB;AAMO,IAAM,2CAAA,GAA8C;AAKpD,IAAM,8CAAA,GAAiD;AAGvD,IAAM,+CAAA,GAAkD;AAKxD,IAAM,+CAAA,GAAkD;AAGxD,IAAM,kDAAA,GAAqD;AAM3D,IAAM,+CAAA,GAAkD;AAKxD,IAAM,yDAAA,GAA4D;AAGlE,IAAM,wCAAA,GAA2C;AAEjD,IAAM,6BAAA,GAAgC;AAEtC,IAAM,+BAAA,GAAkC;AAMxC,IAAM,sDAAA,GAAyD;AAM/D,IAAM,sDAAA,GAAyD;AAG/D,IAAM,wBAAA,GAA2B;AAGjC,IAAM,wCAAA,GAA2C;AAGjD,IAAM,gDAAA,GAAmD;AAGzD,IAAM,kCAAA,GAAqC;AAG3C,IAAM,sCAAA,GAAyC;AAG/C,IAAM,8CAAA,GAAiD;AAMvD,IAAM,gDAAA,GAAmD;AAKzD,IAAM,iDAAA,GAAoD;AAK1D,IAAM,0CAAA,GAA6C;AAMnD,IAAM,6CAAA,GAAgD;AAGtD,IAAM,yCAAA,GAA4C;AAGlD,IAAM,sCAAA,GAAyC;AAG/C,IAAM,sCAAA,GAAyC;AAG/C,IAAM,mDAAA,GAAsD;AAM5D,IAAM,6CAAA,GAAgD;AAMtD,IAAM,mDAAA,GAAsD;AAG5D,IAAM,uCAAA,GAA0C;AAGhD,IAAM,wCAAA,GAA2C;AAGjD,IAAM,yCAAA,GAA4C;AAMlD,IAAM,mDAAA,GAAsD;AAG5D,IAAM,2BAAA,GAA8B;AAGpC,IAAM,0CAAA,GAA6C;AC9V1D,SAAS,UAAU,GAAA,EAA6C;AAC9D,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,MAAA;AACpC,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,OAAO,QAAQ,MAAA,GAAS,CAAA,GAAI,QAAQ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,GAAI,MAAA;AAC5D;AAGA,IAAM,OAAA,GACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,GACA,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK,QAAA,KAAa,YAAA;AAElE,IAAI,OAAA,EAAS;AACX,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,OAAA,CAAQ,GAAA,CAAI,mCAAmC,CAAC,CAAA;AAC7E,EAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,OAAA,CAAQ,GAAA,CAAI,sCAAsC,CAAC,CAAA;AAEnF,EAAA,MAAM,OAAwD,EAAC;AAC/D,EAAA,IAAI,UAAA,IAAc,IAAA,EAAM,IAAA,CAAK,UAAA,GAAa,UAAA;AAC1C,EAAA,IAAI,aAAA,IAAiB,IAAA,EAAM,IAAA,CAAK,aAAA,GAAgB,aAAA;AAEhD,EAAA,IAAI,IAAA,CAAK,UAAA,IAAc,IAAA,IAAQ,IAAA,CAAK,iBAAiB,IAAA,EAAM;AACzD,IAAA,wBAAA,CAAyB,IAAI,CAAA;AAAA,EAC/B;AACF;;;ACtCA,IAAM,UAAA,uBAAiB,GAAA,EAAY;AAE5B,SAAS,QAAA,CAAS,KAAa,OAAA,EAAuB;AAC3D,EAAA,IAAI,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA,EAAG;AACvB,IAAA;AAAA,EACF;AACA,EAAA,UAAA,CAAW,IAAI,GAAG,CAAA;AAElB,EAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AACtB;;;ACZO,IAAM,oCAAA,GAAuC;AAEpD,IAAM,4BAAA,GACJ,0OAAA;AAQF,SAAS,iBAAiB,KAAA,EAAyC;AACjE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAO,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,IAAY,OAAO,EAAE,SAAA,KAAc,QAAA;AAC/D;AAEO,IAAM,8BAAN,MAA8D;AAAA,EAClD,QAAA;AAAA,EACA,UAAA;AAAA,EAEjB,YAAY,OAAA,EAAgE;AAC1E,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,EAAS,QAAA,IAAY,IAAI,sBAAA,EAAuB;AAChE,IAAA,IAAA,CAAK,UAAA,GAAa,SAAS,UAAA,IAAc,oCAAA;AAAA,EAC3C;AAAA,EAEA,MAAc,eAAA,GAAsE;AAClF,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,OAAO,mBAAmB,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,CAAS,oCAAoC,4BAA4B,CAAA;AACzE,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,GAAA,GAA8B;AAClC,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,eAAA,EAAgB;AAC/C,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,IAAA,CAAK,SAAS,GAAA,EAAI;AAAA,IAC3B;AACA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,YAAA,CAAa,KAAK,UAAU,CAAA;AAC1D,MAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,MAAA,MAAM,MAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACtC,MAAA,IAAI,CAAC,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC7B,QAAA,MAAM,YAAY,eAAA,CAAgB,IAAA,CAAK,UAAU,CAAA,CAAE,MAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AACjE,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,IAAI,MAAA,CAAO,SAAA,IAAa,IAAA,CAAK,GAAA,EAAI,EAAG;AAClC,QAAA,MAAM,YAAY,eAAA,CAAgB,IAAA,CAAK,UAAU,CAAA,CAAE,MAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AACjE,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,MAAA,CAAO,KAAA;AAAA,IAChB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA,CAAK,SAAS,GAAA,EAAI;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,GAAA,CAAI,KAAA,EAAe,MAAA,EAA+B;AACtD,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,eAAA,EAAgB;AAC/C,IAAA,MAAM,QAAA,GAA2B;AAAA,MAC/B,KAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAAI;AAAA,KAChD;AACA,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,EAAO,MAAM,CAAA;AACrC,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,YAAY,YAAA,CAAa,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,IAC1E,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,EAAO,MAAM,CAAA;AAAA,IACvC;AAAA,EACF;AACF;AC7EO,SAAS,uBAAA,GAA8C;AAC5D,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAiB,WAAA,CAAA,aAAA;AACvB,IAAA,OAAO,EAAA,IAAM,KAAA,CAAA;AAAA,EACf,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;;;ACHA,IAAI,MAAA,GAAkC,IAAA;AAE/B,SAAS,wBAAwB,UAAA,EAAsC;AAC5E,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAK,QAAA,CAAS,EAAA;AACpB,EAAA,MAAM,WACJ,EAAA,KAAO,KAAA,GAAQ,KAAA,GAAQ,EAAA,KAAO,YAAY,SAAA,GAAY,KAAA;AAExD,EAAA,MAAM,QAAA,GACJ,QAAA,KAAa,KAAA,GAAQ,MAAA,GAAY,uBAAA,EAAwB;AAE3D,EAAA,MAAA,GAAS;AAAA,IACP,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,OAAO,MAAA;AACT;ACGA,IAAM,aAAA,GAAgB,cAAyC,IAAI,CAAA;AAEnE,IAAI,eAAA,GAA6C,IAAA;AAEjD,SAAS,0BAAA,GAAiD;AACxD,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,MAAM,UAAA,GAAa,8BAAA;AACnB,IAAA,MAAM,UAAA,GAAa,wBAAwB,UAAU,CAAA;AACrD,IAAA,MAAM,gBAAA,GAAmB,IAAIA,sBAAAA,EAAuB;AACpD,IAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa;AAAA,MAC9B,cAAA,EAAgB,MAAA;AAAA,MAChB,UAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,eAAA,GAAkB;AAAA,MAChB,MAAA;AAAA,MACA,gBAAA;AAAA,MACA,cAAA,EAAgB,IAAA;AAAA,MAChB,UAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAkB,kBAAA,CAAmB;AAAA,QACnC,UAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACA,EAAA,OAAO,eAAA;AACT;AAEO,SAAS,gBAAA,GAAuC;AACrD,EAAA,MAAM,GAAA,GAAM,WAAW,aAAa,CAAA;AACpC,EAAA,OAAO,OAAO,0BAAA,EAA2B;AAC3C;AAEO,SAAS,cAAA,CAAe;AAAA,EAC7B,cAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAA0B;AAC9C,IAAA,MAAM,UAAA,GAAa,8BAAA;AACnB,IAAA,MAAM,UAAA,GAAa,wBAAwB,UAAU,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,gBAAgB,IAAA,EAAK;AACxC,IAAA,MAAM,gBAAA,GAAmB,IAAI,2BAAA,EAA4B;AACzD,IAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa;AAAA,MAC9B,gBAAgB,UAAA,IAAc,MAAA;AAAA,MAC9B,UAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,MAAM,mBAAmB,kBAAA,CAAmB;AAAA,MAC1C,gBAAgB,UAAA,IAAc,MAAA;AAAA,MAC9B,UAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,gBAAA;AAAA,MACA,gBAAgB,UAAA,IAAc,IAAA;AAAA,MAC9B,UAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AAEnB,EAAA,uBACE,GAAA,CAAC,aAAA,CAAc,QAAA,EAAd,EAAuB,OAAe,QAAA,EAAS,CAAA;AAEpD","file":"chunk-XMG66JV7.mjs","sourcesContent":["export const MOVIIE_PLAYER_EXPO_PKG_VERSION = '0.5.5' as const\n\nexport const MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1000\n\n/** Playback profile strings returned by the playback API (aligned with web embed). */\nexport const MOVIIE_PLAYBACK_PROFILE = {\n VSL: 'vsl',\n CUSTOM: 'custom',\n} as const\n\n/**\n * Smart Progress curve — mirrors {@link SMART_PROGRESS_CONFIG} on the web embed\n * (`apps/web/src/app/embed/[id]/constants.ts`).\n */\nexport const MOVIIE_SMART_PROGRESS_CONFIG = {\n R1: 0.18,\n P1: 0.62,\n R2: 0.8,\n P2: 0.95,\n P_MAX_BEFORE_END: 0.99,\n} as const\n\n/** Fill animation duration (ms); aligns with web `.moviie-smart-progress-fill` transition. */\nexport const MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS = 150 as const\n\n/** Absolute bottom bar height (dp) for native Smart Progress strip. */\nexport const MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP = 12 as const\n\nexport const MOVIIE_SMART_PROGRESS_Z_INDEX = 34 as const\n\n/**\n * SecureStore key prefix for resume position (`{prefix}{embedId}`).\n * Embed IDs are UUIDs from the API.\n */\nexport const MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX = 'moviie.resume_position.' as const\n\n/** Debounce interval before persisting resume position while playing. */\nexport const MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS = 5000 as const\n\n/** Matches embed/web framing defaults when `contentFit` is omitted on `MoviieVideo`. */\nexport const MOVIIE_VIDEO_DEFAULT_CONTENT_FIT = {\n VERTICAL: 'contain',\n HORIZONTAL: 'cover',\n} as const\n\nexport const MOVIIE_BRANDING_MARKETING_ORIGIN = 'https://moviie.ai' as const\n\n/** Origin público da página watch/embed (sem barra final). Override: `EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN`. */\nexport const MOVIIE_WATCH_ORIGIN_DEFAULT = 'https://watch.moviie.ai' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` para override do origin watch/embed em Expo Web (`resolveMoviieWatchOrigin`).\n */\nexport const EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV = 'EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN' as const\n\n/** Path público do script da API JS do embed (relativo ao watch origin). */\nexport const MOVIIE_WATCH_EMBED_JS_PATH = '/embed.js' as const\n\n/**\n * Atributo único no `<script>` injectado em Expo Web para evitar duplicar `embed.js`\n * quando há vários `MoviieVideo` montados.\n */\nexport const MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR = 'data-moviie-player-expo-embed-js' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base da API Moviie em **dev only**.\n * O Metro inlina qualquer `EXPO_PUBLIC_*` em build time, sem precisar de\n * `expo-constants`. Em produção o SDK usa sempre o default `https://api.moviie.ai/v1`.\n *\n * Exemplo `.env.local`:\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n */\nexport const EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_API_BASE_URL' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base de telemetria em **dev only**.\n * Caso omitida, deriva-se de `{origin}/telemetry/v1` a partir de `apiBaseUrl`.\n */\nexport const EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL' as const\n\nexport const MOVIIE_BRANDING_UTM_PARAM_SOURCE = 'utm_source' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_MEDIUM = 'utm_medium' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN = 'utm_campaign' as const\n\nexport const MOVIIE_BRANDING_UTM_SOURCE_VALUE = 'player-expo' as const\nexport const MOVIIE_BRANDING_UTM_MEDIUM_VALUE = 'branding' as const\n\n/** Espelha `PLAYER_EMBED_BRAND_UTM` do embed web (`apps/web/src/app/embed/[id]/constants.ts`). */\nexport const MOVIIE_EMBED_BRAND_UTM = {\n SOURCE: 'moviie_embed_player',\n MEDIUM: 'video_control_bar',\n CAMPAIGN: 'logo_click',\n} as const\n\nexport const MOVIIE_SKIN_DEFAULT_ACCENT_HEX = '#6366f1' as const\n\n/**\n * Valor legado para a prop `controlsAutoHideMs` / `autoHideMs`: o chrome da skin Moviie já não\n * usa temporizador para ocultar — só ao toque fora ou ações (play, seek).\n */\nexport const MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS = 3000 as const\n\nexport const MOVIIE_SKIN_CONTROLS_FADE_MS = 240 as const\n\nexport const MOVIIE_SKIN_WATERMARK_OPACITY = 0.7 as const\n\nexport const MOVIIE_SKIN_CONTROL_ICON_PX = 22 as const\n\n/**\n * Largura lógica de referência do layout da skin (ex.: frame Figma / iPhone ~390pt).\n * Dimensões em `MOVIIE_SKIN_*_AT_REFERENCE` / tokens da timeline escalam com `windowWidth`.\n */\nexport const MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT = 390 as const\n\n/** Limite inferior do factor de escala (telefones mais estreitos). */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MIN = 0.72 as const\n\n/**\n * Limite superior do factor de escala: não aumenta além do design de referência em ecrãs largos.\n */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MAX = 1 as const\n\n/**\n * Distância do HUD inferior (tempo, marca) às bordas laterais do vídeo e ao padding interno do relógio —\n * valor na largura de referência ({@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX = 6 as const\n\n/**\n * Espaço entre a linha do relógio/marca e o topo da área da timeline — referência.\n * Separado de {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para poder encostar ao footer sem afetar margens horizontais.\n * Valor 0 = máximo colado (útil para experimentar layout).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT = 0 as const\n\n/** Hit slop do wordmark e do fullscreen substituto no HUD inferior — px (valor físico independente da escala do layout). */\nexport const MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX = 8 as const\n\n/**\n * Diâmetro da película circular dos botões do HUD inferior (fullscreen, PiP, cast) — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT = 44 as const\n\n/**\n * Tamanho do ícone dentro dessa película — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT = 26 as const\n\n/**\n * Ícones do canto superior (cast, PiP, fullscreen) sem película, com marca visível — referência.\n * Cada ícone aplica seu próprio fator de compensação visual sobre este valor, pois os\n * paths SVG têm densidades de preenchimento diferentes dentro do viewBox.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_TOP_ICON_AT_REFERENCE_PT = 36 as const\n\n/**\n * Fatores de escala visual por ícone do canto superior.\n * Cast/PiP usam viewBox 0 0 24 24 (Material); Fullscreen usa viewBox 0 0 32 32 (media-icons 1.1.5).\n * As densidades de preenchimento são semelhantes entre si, mas Cast (Material 24px) ocupa mais\n * área visual que Fullscreen (32px com cantos L), daí o cast ter escala ligeiramente menor.\n */\nexport const MOVIIE_SKIN_TOP_ICON_CAST_VISUAL_SCALE = 0.65 as const\nexport const MOVIIE_SKIN_TOP_ICON_PIP_VISUAL_SCALE = 0.8 as const\nexport const MOVIIE_SKIN_TOP_ICON_FULLSCREEN_VISUAL_SCALE = 0.8 as const\n\n/**\n * Espaço entre botões da linha direita do HUD (cast, PiP, fullscreen) — referência.\n * Maior que {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para evitar toques acidentais\n * em botões adjacentes.\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT = 10 as const\n\n/** Raio dos cantos do indicador de tempo — valor na largura de referência. */\nexport const MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX = 6 as const\n\n/** Opacidade da película preta detrás dos botões de chrome (0–1). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA = 0.5 as const\n\n/** Película preta por detrás dos elementos de chrome (timing, ícones). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA =\n `rgba(0,0,0,${MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA})` as const\n\n/** Opacidade dos controlos do chrome no estado normal (repouso). */\nexport const MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY = 1 as const\n\n/**\n * Opacidade dos controlos do chrome ao premir — feedback visual (seek, play, fullscreen).\n */\nexport const MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY = 0.72 as const\n\n/** Preto nos stops do degradê vertical da skin (opacidade via `stopOpacity`). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX = '#000000' as const\n\n/** Opacidade na borda “cheia” do degradê (outro extremo é totalmente transparente). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA = 0.62 as const\n\n/**\n * Altura da faixa reservada ao degradê nas bordas — referência (maior = mais “respiro” transparente).\n * O escuro concentra-se junto à borda via {@link MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION}.\n * O inferior acrescenta a altura da timeline quando a barra de progresso está visível.\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT = 104 as const\n\n/**\n * Ao longo da faixa, fração [0–1] medida a partir da borda escura até estar 100% transparente.\n * Ex.: 0.48 → ~48% da altura da faixa com degradê; o resto é totalmente transparente (valor intermédio entre faixa longa e lábio rente à borda).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION = 0.48 as const\n\n/**\n * Altura mínima transparente entre faixa superior e inferior após escalar somas —\n * evita sobreposição das duas faixas (“película” em todo o vídeo).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX = 56 as const\n\n/** IDs estáveis para `LinearGradient` em SVG (skin chrome). */\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID =\n 'moviie_skin_chrome_gradient_bottom_edge' as const\n\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID =\n 'moviie_skin_chrome_gradient_top_edge' as const\n\n/** Volume normalizado (0–1) abaixo disto usa o ícone `volume-low` como no Vidstack. */\nexport const MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD = 0.45 as const\n\n/** Foreground dos ícones e texto da skin (branco sólido). */\nexport const MOVIIE_SKIN_CHROME_FOREGROUND_HEX = '#ffffff' as const\n\n/**\n * Espelha valores numéricos de `OrientationLock` do pacote `expo-screen-orientation` (SDK 52).\n * Mantidos aqui para funções puras e testes Vitest sem resolver o entry nativo do Expo.\n */\nexport const MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE = {\n LANDSCAPE: 5,\n LANDSCAPE_LEFT: 6,\n LANDSCAPE_RIGHT: 7,\n} as const\n\nexport type MoviieExpoOrientationLockValue =\n (typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE)[keyof typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE]\n\n/** Duração da transição (rotação + escala) do fullscreen JS na skin Moviie. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS = 420 as const\n\n/**\n * Rotação final em graus no eixo Z (sentido horário no React Native): vídeo + chrome giram juntos.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES = 90 as const\n\n/** Escala inicial ao entrar em fullscreen (anima até 1). Saída anima de 1 até este valor. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START = 0.78 as const\n\n/**\n * `contentFit` no fullscreen rotacionado: preenche a altura útil do palco; barras laterais ficam a preto do palco.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT = 'contain' as const\n\n/** Fundo do palco em fullscreen JS e placeholder inline durante o modo expandido. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX = '#000000' as const\n\n/**\n * Margem extra (dp/pt) para dentro dos safe area insets no palco fullscreen rotacionado —\n * evita cortar chrome por cantos redondos / overshoot da animação.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX = 12 as const\n\n/**\n * Reforço da margem do HUD/timeline em fullscreen rotacionado (escala com {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT = 14 as const\n\n/** Margem de buffer (s) abaixo da cabeça de reprodução para detetar stalls em HLS. */\nexport const MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS = 0.35 as const\n\nexport const MOVIIE_SKIN_SEEK_JUMP_SECONDS = 10 as const\n\nexport const MOVIIE_SKIN_CENTER_PLAY_ICON_PX = 40 as const\n\n/**\n * Diâmetro da película circular do play/pause central — referência.\n * Entre o círculo compacto (~52) e o layout antigo (~108 na referência).\n */\nexport const MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT = 80 as const\n\n/**\n * Diâmetro da película circular dos botões seek (±10 s) junto ao play — referência.\n * Compacto em torno do ícone ({@link MOVIIE_SKIN_SEEK_ICON_PX}); inferior ao play.\n */\nexport const MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT = 46 as const\n\n/** Ícone seek ±10 s no cluster central — referência (escala com layout). */\nexport const MOVIIE_SKIN_SEEK_ICON_PX = 28 as const\n\n/** Espaço horizontal entre botões do cluster central — valor na largura de referência. */\nexport const MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX = 12 as const\n\n/** Tamanho do texto do relógio — valor na largura de referência. */\nexport const MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT = 12 as const\n\n/** Altura da faixa única da timeline — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX = 3 as const\n\n/** Diâmetro do thumb de scrub — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX = 14 as const\n\n/** Padding vertical acima da timeline — referência (0 = mínimo para testes de densidade). */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX = 0 as const\n\n/**\n * Padding vertical mínimo (dp lógico) por cima do rail dentro da área do vídeo — bem menor que antes:\n * o alvo tátil prioritário é {@link MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP} por baixo do frame.\n */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP = 2 as const\n\n/**\n * Expansão lateral modesta (`View.hitSlop`) — evita faixa enorme dentro do vídeo.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP = 3 as const\n\n/**\n * Pouca expansão para cima: apenas cobrir metade superior do thumb / gestos desde logo acima do trilho.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP = 2 as const\n\n/**\n * Expansão inferior dominante — cobre o thumb quando ultrapassa o limite inferior do vídeo\n * (`hitSlop` não ocupa layout dentro do frame; toques contam por baixo da overlay).\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP = 14 as const\n\n/** Trilho base da timeline: branco ~30%. */\nexport const MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA = 'rgba(255,255,255,0.3)' as const\n\n/** Camada de buffer sobre o trilho (mesma cor/opacidade que o trilho). */\nexport const MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA = MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA\n\n/** Contorno do thumb da timeline para contraste sobre vídeo claro. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA = 'rgba(0,0,0,0.35)' as const\n\n/** Diâmetro do thumb durante scrub (drag) relativamente ao thumb em repouso. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER = 1.65 as const\n\n/**\n * Segundos antes do fim onde o progresso mostrado fixa em 100% quando não está a reproduzir —\n * o `currentTime` do motor costuma ficar ligeiramente abaixo de `duration` no fim.\n */\nexport const MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS = 0.15 as const\n\n/**\n * Distância máxima (s) entre a posição de release do scrub e um boundary de capítulo\n * para que o snap automático seja ativado.\n */\nexport const MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS = 2 as const\n\n/** Área do `ActivityIndicator` small no overlay de buffering — valor na largura de referência. */\nexport const MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX = 28 as const\n\n/** Largura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX = 173 as const\n\n/** Altura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX = 46 as const\n\n/**\n * Largura visual alvo do wordmark quando `windowWidth` = {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}\n * (entre o tamanho compacto antigo e o artboard completo).\n */\nexport const MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT = 68 as const\n\n/** ViewBox do SVG wordmark Moviie (173×46). */\nexport const MOVIIE_EMBED_BRAND_VIEW_BOX = '0 0 173 46' as const\n\n/** Espessura do traço das letras “ii” no wordmark (coordenadas do viewBox). */\nexport const MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH = 3 as const\n","/**\n * Configura endpoints da API Moviie a partir de **variáveis de ambiente**\n * `EXPO_PUBLIC_MOVIIE_API_BASE_URL` e (raro) `EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL`.\n *\n * **Override é apenas para desenvolvimento local.** Apps em produção usam o\n * default `https://api.moviie.ai/v1`. Por isso este módulo:\n *\n * - Só aplica o override quando `__DEV__ === true` (Metro/Hermes dev mode);\n * - Não depende de `expo-constants` — usa só `process.env.*` que o Metro inlina\n * em build time para qualquer var `EXPO_PUBLIC_*`;\n * - Falha silenciosamente em produção (var inexistente → default do SDK).\n *\n * Vars relevantes (definidas em `.env.local` no consumer):\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n * EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL=http://localhost:3000/telemetry/v1\n */\nimport { configureMoviieEndpoints } from '@moviie/player-sdk'\n\nimport {\n EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV,\n EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV,\n} from './constants'\n\nfunction normalize(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed.replace(/\\/+$/, '') : undefined\n}\n\n// `__DEV__` é definido pelo bundler RN. Em web build (Vite/Next) cai pra `process.env.NODE_ENV`.\nconst devMode =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\nif (devMode) {\n const apiBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV])\n const eventsBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV])\n\n const opts: { apiBaseUrl?: string; eventsBaseUrl?: string } = {}\n if (apiBaseUrl != null) opts.apiBaseUrl = apiBaseUrl\n if (eventsBaseUrl != null) opts.eventsBaseUrl = eventsBaseUrl\n\n if (opts.apiBaseUrl != null || opts.eventsBaseUrl != null) {\n configureMoviieEndpoints(opts)\n }\n}\n","/**\n * Console warning idempotente por chave. Útil para dependências opcionais ausentes:\n * dispara uma única vez por sessão para a mesma chave, evitando ruído no console.\n *\n * Reusável para qualquer feature gated por dep opcional (cast, DRM custom,\n * analytics provider, etc.).\n */\n\nconst FIRED_KEYS = new Set<string>()\n\nexport function warnOnce(key: string, message: string): void {\n if (FIRED_KEYS.has(key)) {\n return\n }\n FIRED_KEYS.add(key)\n // eslint-disable-next-line no-console\n console.warn(message)\n}\n\n/** Limpa o set de chaves disparadas. Use apenas em testes. */\nexport function __resetWarnOnceForTests(): void {\n FIRED_KEYS.clear()\n}\n","import type { ViewerTokenStore } from '@moviie/player-sdk'\nimport { MemoryViewerTokenStore } from '@moviie/player-sdk'\n\nimport { warnOnce } from './lib/warn-once'\n\nexport const MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY = 'moviie_viewer_token_v1' as const\n\nconst SECURE_STORE_MISSING_WARNING =\n '[@moviie/player-expo] `expo-secure-store` não está instalado — viewer token será mantido apenas em memória (perde ao matar app). ' +\n 'Instala com `pnpm add expo-secure-store` se quiseres persistência entre sessões.'\n\ninterface StoredEnvelope {\n token: string\n expiresAt: number\n}\n\nfunction isStoredEnvelope(value: unknown): value is StoredEnvelope {\n if (!value || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n return typeof v.token === 'string' && typeof v.expiresAt === 'number'\n}\n\nexport class SecureStoreViewerTokenStore implements ViewerTokenStore {\n private readonly fallback: ViewerTokenStore\n private readonly storageKey: string\n\n constructor(options?: { fallback?: ViewerTokenStore; storageKey?: string }) {\n this.fallback = options?.fallback ?? new MemoryViewerTokenStore()\n this.storageKey = options?.storageKey ?? MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY\n }\n\n private async loadSecureStore(): Promise<typeof import('expo-secure-store') | null> {\n try {\n return await import('expo-secure-store')\n } catch {\n warnOnce('moviie:expo-secure-store-missing', SECURE_STORE_MISSING_WARNING)\n return null\n }\n }\n\n async get(): Promise<string | null> {\n const SecureStore = await this.loadSecureStore()\n if (!SecureStore) {\n return this.fallback.get()\n }\n try {\n const raw = await SecureStore.getItemAsync(this.storageKey)\n if (!raw) return null\n const parsed: unknown = JSON.parse(raw)\n if (!isStoredEnvelope(parsed)) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n if (parsed.expiresAt <= Date.now()) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n return parsed.token\n } catch {\n return this.fallback.get()\n }\n }\n\n async set(token: string, ttlSec: number): Promise<void> {\n const SecureStore = await this.loadSecureStore()\n const envelope: StoredEnvelope = {\n token,\n expiresAt: Date.now() + Math.max(0, ttlSec) * 1000,\n }\n if (!SecureStore) {\n await this.fallback.set(token, ttlSec)\n return\n }\n try {\n await SecureStore.setItemAsync(this.storageKey, JSON.stringify(envelope))\n } catch {\n await this.fallback.set(token, ttlSec)\n }\n }\n}\n","import * as Application from \"expo-application\"\n\nexport function readNativeApplicationId(): string | undefined {\n try {\n const id = Application.applicationId\n return id ?? undefined\n } catch {\n return undefined\n }\n}\n","import { Platform } from \"react-native\"\n\nimport type { MoviieClientInfo } from \"@moviie/player-sdk\"\n\nimport { readNativeApplicationId } from \"./native-application-id\"\n\nlet cached: MoviieClientInfo | null = null\n\nexport function buildPlatformClientInfo(sdkVersion: string): MoviieClientInfo {\n if (cached) {\n return cached\n }\n\n const os = Platform.OS\n const platform: MoviieClientInfo[\"platform\"] =\n os === \"ios\" ? \"ios\" : os === \"android\" ? \"android\" : \"web\"\n\n const bundleId =\n platform === \"web\" ? undefined : readNativeApplicationId()\n\n cached = {\n platform,\n bundleId,\n sdkVersion,\n }\n return cached\n}\n\nexport function resetPlatformClientInfoCache(): void {\n cached = null\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\"\n\nimport {\n buildClientHeaders,\n MemoryViewerTokenStore,\n MoviieClient,\n type MoviieClientInfo,\n type ViewerTokenStore,\n} from \"@moviie/player-sdk\"\n\nimport { MOVIIE_PLAYER_EXPO_PKG_VERSION } from \"../constants\"\nimport { buildPlatformClientInfo } from \"../platform/platform-client-info\"\nimport { SecureStoreViewerTokenStore } from \"../secure-store-viewer-token-store\"\n\nexport interface MoviieContextValue {\n client: MoviieClient\n viewerTokenStore: ViewerTokenStore\n publishableKey: string | null\n clientInfo: MoviieClientInfo\n sdkVersion: string\n /** Headers reused by TelemetryClient (Bearer + X-Moviie-Client when aplicável) */\n telemetryHeaders: Record<string, string>\n}\n\nconst MoviieContext = createContext<MoviieContextValue | null>(null)\n\nlet fallbackContext: MoviieContextValue | null = null\n\nfunction getOrCreateFallbackContext(): MoviieContextValue {\n if (!fallbackContext) {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const viewerTokenStore = new MemoryViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: undefined,\n clientInfo,\n sdkVersion,\n })\n fallbackContext = {\n client,\n viewerTokenStore,\n publishableKey: null,\n clientInfo,\n sdkVersion,\n telemetryHeaders: buildClientHeaders({\n clientInfo,\n sdkVersion,\n }),\n }\n }\n return fallbackContext\n}\n\nexport function useMoviieContext(): MoviieContextValue {\n const ctx = useContext(MoviieContext)\n return ctx ?? getOrCreateFallbackContext()\n}\n\nexport function MoviieProvider({\n publishableKey,\n children,\n}: {\n publishableKey?: string | null\n children: ReactNode\n}) {\n const value = useMemo((): MoviieContextValue => {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const trimmedKey = publishableKey?.trim()\n const viewerTokenStore = new SecureStoreViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n const telemetryHeaders = buildClientHeaders({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n return {\n client,\n viewerTokenStore,\n publishableKey: trimmedKey ?? null,\n clientInfo,\n sdkVersion,\n telemetryHeaders,\n }\n }, [publishableKey])\n\n return (\n <MoviieContext.Provider value={value}>{children}</MoviieContext.Provider>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/apply-expo-moviie-endpoints.ts","../src/lib/warn-once.ts","../src/secure-store-viewer-token-store.ts","../src/platform/native-application-id.ts","../src/platform/platform-client-info.ts","../src/provider/moviie-provider.tsx"],"names":["MemoryViewerTokenStore"],"mappings":"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","file":"chunk-TWUGAJRM.mjs","sourcesContent":["export const MOVIIE_PLAYER_EXPO_PKG_VERSION = '0.6.1' as const\n\nexport const MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1000\n\n/** Playback profile strings returned by the playback API (aligned with web embed). */\nexport const MOVIIE_PLAYBACK_PROFILE = {\n VSL: 'vsl',\n CUSTOM: 'custom',\n} as const\n\n/**\n * Smart Progress curve — mirrors {@link SMART_PROGRESS_CONFIG} on the web embed\n * (`apps/web/src/app/embed/[id]/constants.ts`).\n */\nexport const MOVIIE_SMART_PROGRESS_CONFIG = {\n R1: 0.18,\n P1: 0.62,\n R2: 0.8,\n P2: 0.95,\n P_MAX_BEFORE_END: 0.99,\n} as const\n\n/** Fill animation duration (ms); aligns with web `.moviie-smart-progress-fill` transition. */\nexport const MOVIIE_SMART_PROGRESS_FILL_TRANSITION_MS = 150 as const\n\n/** Absolute bottom bar height (dp) for native Smart Progress strip. */\nexport const MOVIIE_SMART_PROGRESS_BAR_HEIGHT_DP = 12 as const\n\nexport const MOVIIE_SMART_PROGRESS_Z_INDEX = 34 as const\n\n/**\n * SecureStore key prefix for resume position (`{prefix}{embedId}`).\n * Embed IDs are UUIDs from the API.\n */\nexport const MOVIIE_REMEMBER_POSITION_STORAGE_PREFIX = 'moviie.resume_position.' as const\n\n/** Debounce interval before persisting resume position while playing. */\nexport const MOVIIE_REMEMBER_POSITION_DEBOUNCE_MS = 5000 as const\n\n/** Matches embed/web framing defaults when `contentFit` is omitted on `MoviieVideo`. */\nexport const MOVIIE_VIDEO_DEFAULT_CONTENT_FIT = {\n VERTICAL: 'contain',\n HORIZONTAL: 'cover',\n} as const\n\nexport const MOVIIE_BRANDING_MARKETING_ORIGIN = 'https://moviie.ai' as const\n\n/** Origin público da página watch/embed (sem barra final). Override: `EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN`. */\nexport const MOVIIE_WATCH_ORIGIN_DEFAULT = 'https://watch.moviie.ai' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` para override do origin watch/embed em Expo Web (`resolveMoviieWatchOrigin`).\n */\nexport const EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN_ENV = 'EXPO_PUBLIC_MOVIIE_WATCH_ORIGIN' as const\n\n/** Path público do script da API JS do embed (relativo ao watch origin). */\nexport const MOVIIE_WATCH_EMBED_JS_PATH = '/embed.js' as const\n\n/**\n * Atributo único no `<script>` injectado em Expo Web para evitar duplicar `embed.js`\n * quando há vários `MoviieVideo` montados.\n */\nexport const MOVIIE_PLAYER_EXPO_EMBED_JS_MARKER_ATTR = 'data-moviie-player-expo-embed-js' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base da API Moviie em **dev only**.\n * O Metro inlina qualquer `EXPO_PUBLIC_*` em build time, sem precisar de\n * `expo-constants`. Em produção o SDK usa sempre o default `https://api.moviie.ai/v1`.\n *\n * Exemplo `.env.local`:\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n */\nexport const EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_API_BASE_URL' as const\n\n/**\n * Variável `EXPO_PUBLIC_*` que override a base de telemetria em **dev only**.\n * Caso omitida, deriva-se de `{origin}/telemetry/v1` a partir de `apiBaseUrl`.\n */\nexport const EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV = 'EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL' as const\n\nexport const MOVIIE_BRANDING_UTM_PARAM_SOURCE = 'utm_source' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_MEDIUM = 'utm_medium' as const\nexport const MOVIIE_BRANDING_UTM_PARAM_CAMPAIGN = 'utm_campaign' as const\n\nexport const MOVIIE_BRANDING_UTM_SOURCE_VALUE = 'player-expo' as const\nexport const MOVIIE_BRANDING_UTM_MEDIUM_VALUE = 'branding' as const\n\n/** Espelha `PLAYER_EMBED_BRAND_UTM` do embed web (`apps/web/src/app/embed/[id]/constants.ts`). */\nexport const MOVIIE_EMBED_BRAND_UTM = {\n SOURCE: 'moviie_embed_player',\n MEDIUM: 'video_control_bar',\n CAMPAIGN: 'logo_click',\n} as const\n\nexport const MOVIIE_SKIN_DEFAULT_ACCENT_HEX = '#6366f1' as const\n\n/**\n * Valor legado para a prop `controlsAutoHideMs` / `autoHideMs`: o chrome da skin Moviie já não\n * usa temporizador para ocultar — só ao toque fora ou ações (play, seek).\n */\nexport const MOVIIE_SKIN_CONTROLS_AUTO_HIDE_MS = 3000 as const\n\nexport const MOVIIE_SKIN_CONTROLS_FADE_MS = 240 as const\n\nexport const MOVIIE_SKIN_WATERMARK_OPACITY = 0.7 as const\n\nexport const MOVIIE_SKIN_CONTROL_ICON_PX = 22 as const\n\n/**\n * Largura lógica de referência do layout da skin (ex.: frame Figma / iPhone ~390pt).\n * Dimensões em `MOVIIE_SKIN_*_AT_REFERENCE` / tokens da timeline escalam com `windowWidth`.\n */\nexport const MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT = 390 as const\n\n/** Limite inferior do factor de escala (telefones mais estreitos). */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MIN = 0.72 as const\n\n/**\n * Limite superior do factor de escala: não aumenta além do design de referência em ecrãs largos.\n */\nexport const MOVIIE_SKIN_LAYOUT_SCALE_MAX = 1 as const\n\n/**\n * Distância do HUD inferior (tempo, marca) às bordas laterais do vídeo e ao padding interno do relógio —\n * valor na largura de referência ({@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX = 6 as const\n\n/**\n * Espaço entre a linha do relógio/marca e o topo da área da timeline — referência.\n * Separado de {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para poder encostar ao footer sem afetar margens horizontais.\n * Valor 0 = máximo colado (útil para experimentar layout).\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_ABOVE_TIMELINE_GAP_AT_REFERENCE_PT = 0 as const\n\n/** Hit slop do wordmark e do fullscreen substituto no HUD inferior — px (valor físico independente da escala do layout). */\nexport const MOVIIE_SKIN_FLOATING_HUD_TRAILING_HIT_SLOP_PX = 8 as const\n\n/**\n * Diâmetro da película circular dos botões do HUD inferior (fullscreen, PiP, cast) — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_SCRIM_DIAMETER_AT_REFERENCE_PT = 44 as const\n\n/**\n * Tamanho do ícone dentro dessa película — referência.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_ICON_AT_REFERENCE_PT = 26 as const\n\n/**\n * Ícones do canto superior (cast, PiP, fullscreen) sem película, com marca visível — referência.\n * Cada ícone aplica seu próprio fator de compensação visual sobre este valor, pois os\n * paths SVG têm densidades de preenchimento diferentes dentro do viewBox.\n */\nexport const MOVIIE_SKIN_FLOATING_FULLSCREEN_TOP_ICON_AT_REFERENCE_PT = 36 as const\n\n/**\n * Fatores de escala visual por ícone do canto superior.\n * Cast/PiP usam viewBox 0 0 24 24 (Material); Fullscreen usa viewBox 0 0 32 32 (media-icons 1.1.5).\n * As densidades de preenchimento são semelhantes entre si, mas Cast (Material 24px) ocupa mais\n * área visual que Fullscreen (32px com cantos L), daí o cast ter escala ligeiramente menor.\n */\nexport const MOVIIE_SKIN_TOP_ICON_CAST_VISUAL_SCALE = 0.65 as const\nexport const MOVIIE_SKIN_TOP_ICON_PIP_VISUAL_SCALE = 0.8 as const\nexport const MOVIIE_SKIN_TOP_ICON_FULLSCREEN_VISUAL_SCALE = 0.8 as const\n\n/**\n * Espaço entre botões da linha direita do HUD (cast, PiP, fullscreen) — referência.\n * Maior que {@link MOVIIE_SKIN_FLOATING_HUD_EDGE_INSET_PX} para evitar toques acidentais\n * em botões adjacentes.\n */\nexport const MOVIIE_SKIN_FLOATING_HUD_BUTTON_GAP_AT_REFERENCE_PT = 10 as const\n\n/** Raio dos cantos do indicador de tempo — valor na largura de referência. */\nexport const MOVIIE_SKIN_FLOATING_HUD_CLOCK_CORNER_RADIUS_PX = 6 as const\n\n/** Opacidade da película preta detrás dos botões de chrome (0–1). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA = 0.5 as const\n\n/** Película preta por detrás dos elementos de chrome (timing, ícones). */\nexport const MOVIIE_SKIN_CHROME_SCRIM_BLACK_RGBA =\n `rgba(0,0,0,${MOVIIE_SKIN_CHROME_SCRIM_BLACK_ALPHA})` as const\n\n/** Opacidade dos controlos do chrome no estado normal (repouso). */\nexport const MOVIIE_SKIN_CHROME_CONTROL_REST_OPACITY = 1 as const\n\n/**\n * Opacidade dos controlos do chrome ao premir — feedback visual (seek, play, fullscreen).\n */\nexport const MOVIIE_SKIN_CHROME_CONTROL_PRESSED_OPACITY = 0.72 as const\n\n/** Preto nos stops do degradê vertical da skin (opacidade via `stopOpacity`). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_BLACK_HEX = '#000000' as const\n\n/** Opacidade na borda “cheia” do degradê (outro extremo é totalmente transparente). */\nexport const MOVIIE_SKIN_CHROME_GRADIENT_EDGE_ALPHA = 0.62 as const\n\n/**\n * Altura da faixa reservada ao degradê nas bordas — referência (maior = mais “respiro” transparente).\n * O escuro concentra-se junto à borda via {@link MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION}.\n * O inferior acrescenta a altura da timeline quando a barra de progresso está visível.\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_HEIGHT_AT_REFERENCE_PT = 104 as const\n\n/**\n * Ao longo da faixa, fração [0–1] medida a partir da borda escura até estar 100% transparente.\n * Ex.: 0.48 → ~48% da altura da faixa com degradê; o resto é totalmente transparente (valor intermédio entre faixa longa e lábio rente à borda).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_EDGE_SOLID_FADE_END_FRACTION = 0.48 as const\n\n/**\n * Altura mínima transparente entre faixa superior e inferior após escalar somas —\n * evita sobreposição das duas faixas (“película” em todo o vídeo).\n */\nexport const MOVIIE_SKIN_CHROME_EDGE_GRADIENT_MIN_CLEAR_MIDDLE_PX = 56 as const\n\n/** IDs estáveis para `LinearGradient` em SVG (skin chrome). */\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_BOTTOM_EDGE_ID =\n 'moviie_skin_chrome_gradient_bottom_edge' as const\n\nexport const MOVIIE_SKIN_CHROME_SVG_GRADIENT_TOP_EDGE_ID =\n 'moviie_skin_chrome_gradient_top_edge' as const\n\n/** Volume normalizado (0–1) abaixo disto usa o ícone `volume-low` como no Vidstack. */\nexport const MOVIIE_SKIN_VOLUME_LOW_ICON_THRESHOLD = 0.45 as const\n\n/** Foreground dos ícones e texto da skin (branco sólido). */\nexport const MOVIIE_SKIN_CHROME_FOREGROUND_HEX = '#ffffff' as const\n\n/**\n * Espelha valores numéricos de `OrientationLock` do pacote `expo-screen-orientation` (SDK 52).\n * Mantidos aqui para funções puras e testes Vitest sem resolver o entry nativo do Expo.\n */\nexport const MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE = {\n LANDSCAPE: 5,\n LANDSCAPE_LEFT: 6,\n LANDSCAPE_RIGHT: 7,\n} as const\n\nexport type MoviieExpoOrientationLockValue =\n (typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE)[keyof typeof MOVIIE_EXPO_SCREEN_ORIENTATION_LOCK_VALUE]\n\n/** Duração da transição (rotação + escala) do fullscreen JS na skin Moviie. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_TRANSITION_MS = 420 as const\n\n/**\n * Rotação final em graus no eixo Z (sentido horário no React Native): vídeo + chrome giram juntos.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ROTATE_Z_DEGREES = 90 as const\n\n/** Escala inicial ao entrar em fullscreen (anima até 1). Saída anima de 1 até este valor. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_ENTER_SCALE_START = 0.78 as const\n\n/**\n * `contentFit` no fullscreen rotacionado: preenche a altura útil do palco; barras laterais ficam a preto do palco.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_VIDEO_CONTENT_FIT = 'contain' as const\n\n/** Fundo do palco em fullscreen JS e placeholder inline durante o modo expandido. */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_BACKGROUND_HEX = '#000000' as const\n\n/**\n * Margem extra (dp/pt) para dentro dos safe area insets no palco fullscreen rotacionado —\n * evita cortar chrome por cantos redondos / overshoot da animação.\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_STAGE_OVERSCAN_PX = 12 as const\n\n/**\n * Reforço da margem do HUD/timeline em fullscreen rotacionado (escala com {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}).\n */\nexport const MOVIIE_SKIN_CUSTOM_FULLSCREEN_HUD_EDGE_BOOST_REFERENCE_PT = 14 as const\n\n/** Margem de buffer (s) abaixo da cabeça de reprodução para detetar stalls em HLS. */\nexport const MOVIIE_SKIN_BUFFER_UNDERRUN_LEAD_SECONDS = 0.35 as const\n\nexport const MOVIIE_SKIN_SEEK_JUMP_SECONDS = 10 as const\n\nexport const MOVIIE_SKIN_CENTER_PLAY_ICON_PX = 40 as const\n\n/**\n * Diâmetro da película circular do play/pause central — referência.\n * Entre o círculo compacto (~52) e o layout antigo (~108 na referência).\n */\nexport const MOVIIE_SKIN_CENTER_PLAY_SCRIM_DIAMETER_AT_REFERENCE_PT = 80 as const\n\n/**\n * Diâmetro da película circular dos botões seek (±10 s) junto ao play — referência.\n * Compacto em torno do ícone ({@link MOVIIE_SKIN_SEEK_ICON_PX}); inferior ao play.\n */\nexport const MOVIIE_SKIN_CENTER_SEEK_SCRIM_DIAMETER_AT_REFERENCE_PT = 46 as const\n\n/** Ícone seek ±10 s no cluster central — referência (escala com layout). */\nexport const MOVIIE_SKIN_SEEK_ICON_PX = 28 as const\n\n/** Espaço horizontal entre botões do cluster central — valor na largura de referência. */\nexport const MOVIIE_SKIN_CENTER_CLUSTER_COLUMN_GAP_PX = 12 as const\n\n/** Tamanho do texto do relógio — valor na largura de referência. */\nexport const MOVIIE_SKIN_CLOCK_TEXT_FONT_SIZE_AT_REFERENCE_PT = 12 as const\n\n/** Altura da faixa única da timeline — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_BAR_HEIGHT_PX = 3 as const\n\n/** Diâmetro do thumb de scrub — valor na largura de referência. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DIAMETER_PX = 14 as const\n\n/** Padding vertical acima da timeline — referência (0 = mínimo para testes de densidade). */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_PADDING_VERTICAL_PX = 0 as const\n\n/**\n * Padding vertical mínimo (dp lógico) por cima do rail dentro da área do vídeo — bem menor que antes:\n * o alvo tátil prioritário é {@link MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP} por baixo do frame.\n */\nexport const MOVIIE_SKIN_TIMELINE_TOUCH_EXPANSION_VERTICAL_DP = 2 as const\n\n/**\n * Expansão lateral modesta (`View.hitSlop`) — evita faixa enorme dentro do vídeo.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_HORIZONTAL_DP = 3 as const\n\n/**\n * Pouca expansão para cima: apenas cobrir metade superior do thumb / gestos desde logo acima do trilho.\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP = 2 as const\n\n/**\n * Expansão inferior dominante — cobre o thumb quando ultrapassa o limite inferior do vídeo\n * (`hitSlop` não ocupa layout dentro do frame; toques contam por baixo da overlay).\n */\nexport const MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_BOTTOM_DP = 14 as const\n\n/** Trilho base da timeline: branco ~30%. */\nexport const MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA = 'rgba(255,255,255,0.3)' as const\n\n/** Camada de buffer sobre o trilho (mesma cor/opacidade que o trilho). */\nexport const MOVIIE_SKIN_TIMELINE_BUFFER_LAYER_RGBA = MOVIIE_SKIN_TIMELINE_RAIL_BACKGROUND_RGBA\n\n/** Contorno do thumb da timeline para contraste sobre vídeo claro. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_BORDER_RGBA = 'rgba(0,0,0,0.35)' as const\n\n/** Diâmetro do thumb durante scrub (drag) relativamente ao thumb em repouso. */\nexport const MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER = 1.65 as const\n\n/**\n * Segundos antes do fim onde o progresso mostrado fixa em 100% quando não está a reproduzir —\n * o `currentTime` do motor costuma ficar ligeiramente abaixo de `duration` no fim.\n */\nexport const MOVIIE_SKIN_TIMELINE_END_SNAP_EPSILON_SECONDS = 0.15 as const\n\n/**\n * Distância máxima (s) entre a posição de release do scrub e um boundary de capítulo\n * para que o snap automático seja ativado.\n */\nexport const MOVIIE_SKIN_TIMELINE_CHAPTER_SNAP_THRESHOLD_SECONDS = 2 as const\n\n/** Área do `ActivityIndicator` small no overlay de buffering — valor na largura de referência. */\nexport const MOVIIE_SKIN_BUFFERING_INDICATOR_SLOT_PX = 28 as const\n\n/** Largura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_WIDTH_PX = 173 as const\n\n/** Altura intrínseca do SVG wordmark (viewBox). */\nexport const MOVIIE_SKIN_BRAND_MARK_ARTBOARD_HEIGHT_PX = 46 as const\n\n/**\n * Largura visual alvo do wordmark quando `windowWidth` = {@link MOVIIE_SKIN_LAYOUT_REFERENCE_WIDTH_PT}\n * (entre o tamanho compacto antigo e o artboard completo).\n */\nexport const MOVIIE_SKIN_BRAND_MARK_TARGET_WIDTH_AT_REFERENCE_PT = 68 as const\n\n/** ViewBox do SVG wordmark Moviie (173×46). */\nexport const MOVIIE_EMBED_BRAND_VIEW_BOX = '0 0 173 46' as const\n\n/** Espessura do traço das letras “ii” no wordmark (coordenadas do viewBox). */\nexport const MOVIIE_EMBED_BRAND_LETTERMARK_STROKE_WIDTH = 3 as const\n","/**\n * Configura endpoints da API Moviie a partir de **variáveis de ambiente**\n * `EXPO_PUBLIC_MOVIIE_API_BASE_URL` e (raro) `EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL`.\n *\n * **Override é apenas para desenvolvimento local.** Apps em produção usam o\n * default `https://api.moviie.ai/v1`. Por isso este módulo:\n *\n * - Só aplica o override quando `__DEV__ === true` (Metro/Hermes dev mode);\n * - Não depende de `expo-constants` — usa só `process.env.*` que o Metro inlina\n * em build time para qualquer var `EXPO_PUBLIC_*`;\n * - Falha silenciosamente em produção (var inexistente → default do SDK).\n *\n * Vars relevantes (definidas em `.env.local` no consumer):\n * EXPO_PUBLIC_MOVIIE_API_BASE_URL=http://localhost:3000/api/v1\n * EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL=http://localhost:3000/telemetry/v1\n */\nimport { configureMoviieEndpoints } from '@moviie/player-sdk'\n\nimport {\n EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV,\n EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV,\n} from './constants'\n\nfunction normalize(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed.replace(/\\/+$/, '') : undefined\n}\n\n// `__DEV__` é definido pelo bundler RN. Em web build (Vite/Next) cai pra `process.env.NODE_ENV`.\nconst devMode =\n typeof __DEV__ !== 'undefined'\n ? __DEV__\n : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\nif (devMode) {\n const apiBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_API_BASE_URL_ENV])\n const eventsBaseUrl = normalize(process.env[EXPO_PUBLIC_MOVIIE_EVENTS_BASE_URL_ENV])\n\n const opts: { apiBaseUrl?: string; eventsBaseUrl?: string } = {}\n if (apiBaseUrl != null) opts.apiBaseUrl = apiBaseUrl\n if (eventsBaseUrl != null) opts.eventsBaseUrl = eventsBaseUrl\n\n if (opts.apiBaseUrl != null || opts.eventsBaseUrl != null) {\n configureMoviieEndpoints(opts)\n }\n}\n","/**\n * Console warning idempotente por chave. Útil para dependências opcionais ausentes:\n * dispara uma única vez por sessão para a mesma chave, evitando ruído no console.\n *\n * Reusável para qualquer feature gated por dep opcional (cast, DRM custom,\n * analytics provider, etc.).\n */\n\nconst FIRED_KEYS = new Set<string>()\n\nexport function warnOnce(key: string, message: string): void {\n if (FIRED_KEYS.has(key)) {\n return\n }\n FIRED_KEYS.add(key)\n // eslint-disable-next-line no-console\n console.warn(message)\n}\n\n/** Limpa o set de chaves disparadas. Use apenas em testes. */\nexport function __resetWarnOnceForTests(): void {\n FIRED_KEYS.clear()\n}\n","import type { ViewerTokenStore } from '@moviie/player-sdk'\nimport { MemoryViewerTokenStore } from '@moviie/player-sdk'\n\nimport { warnOnce } from './lib/warn-once'\n\nexport const MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY = 'moviie_viewer_token_v1' as const\n\nconst SECURE_STORE_MISSING_WARNING =\n '[@moviie/player-expo] `expo-secure-store` não está instalado — viewer token será mantido apenas em memória (perde ao matar app). ' +\n 'Instala com `pnpm add expo-secure-store` se quiseres persistência entre sessões.'\n\ninterface StoredEnvelope {\n token: string\n expiresAt: number\n}\n\nfunction isStoredEnvelope(value: unknown): value is StoredEnvelope {\n if (!value || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n return typeof v.token === 'string' && typeof v.expiresAt === 'number'\n}\n\nexport class SecureStoreViewerTokenStore implements ViewerTokenStore {\n private readonly fallback: ViewerTokenStore\n private readonly storageKey: string\n\n constructor(options?: { fallback?: ViewerTokenStore; storageKey?: string }) {\n this.fallback = options?.fallback ?? new MemoryViewerTokenStore()\n this.storageKey = options?.storageKey ?? MOVIIE_VIEWER_TOKEN_SECURE_STORE_KEY\n }\n\n private async loadSecureStore(): Promise<typeof import('expo-secure-store') | null> {\n try {\n return await import('expo-secure-store')\n } catch {\n warnOnce('moviie:expo-secure-store-missing', SECURE_STORE_MISSING_WARNING)\n return null\n }\n }\n\n async get(): Promise<string | null> {\n const SecureStore = await this.loadSecureStore()\n if (!SecureStore) {\n return this.fallback.get()\n }\n try {\n const raw = await SecureStore.getItemAsync(this.storageKey)\n if (!raw) return null\n const parsed: unknown = JSON.parse(raw)\n if (!isStoredEnvelope(parsed)) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n if (parsed.expiresAt <= Date.now()) {\n await SecureStore.deleteItemAsync(this.storageKey).catch(() => {})\n return null\n }\n return parsed.token\n } catch {\n return this.fallback.get()\n }\n }\n\n async set(token: string, ttlSec: number): Promise<void> {\n const SecureStore = await this.loadSecureStore()\n const envelope: StoredEnvelope = {\n token,\n expiresAt: Date.now() + Math.max(0, ttlSec) * 1000,\n }\n if (!SecureStore) {\n await this.fallback.set(token, ttlSec)\n return\n }\n try {\n await SecureStore.setItemAsync(this.storageKey, JSON.stringify(envelope))\n } catch {\n await this.fallback.set(token, ttlSec)\n }\n }\n}\n","import * as Application from \"expo-application\"\n\nexport function readNativeApplicationId(): string | undefined {\n try {\n const id = Application.applicationId\n return id ?? undefined\n } catch {\n return undefined\n }\n}\n","import { Platform } from \"react-native\"\n\nimport type { MoviieClientInfo } from \"@moviie/player-sdk\"\n\nimport { readNativeApplicationId } from \"./native-application-id\"\n\nlet cached: MoviieClientInfo | null = null\n\nexport function buildPlatformClientInfo(sdkVersion: string): MoviieClientInfo {\n if (cached) {\n return cached\n }\n\n const os = Platform.OS\n const platform: MoviieClientInfo[\"platform\"] =\n os === \"ios\" ? \"ios\" : os === \"android\" ? \"android\" : \"web\"\n\n const bundleId =\n platform === \"web\" ? undefined : readNativeApplicationId()\n\n cached = {\n platform,\n bundleId,\n sdkVersion,\n }\n return cached\n}\n\nexport function resetPlatformClientInfoCache(): void {\n cached = null\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\"\n\nimport {\n buildClientHeaders,\n MemoryViewerTokenStore,\n MoviieClient,\n type MoviieClientInfo,\n type ViewerTokenStore,\n} from \"@moviie/player-sdk\"\n\nimport { MOVIIE_PLAYER_EXPO_PKG_VERSION } from \"../constants\"\nimport { buildPlatformClientInfo } from \"../platform/platform-client-info\"\nimport { SecureStoreViewerTokenStore } from \"../secure-store-viewer-token-store\"\n\nexport interface MoviieContextValue {\n client: MoviieClient\n viewerTokenStore: ViewerTokenStore\n publishableKey: string | null\n clientInfo: MoviieClientInfo\n sdkVersion: string\n /** Headers reused by TelemetryClient (Bearer + X-Moviie-Client when aplicável) */\n telemetryHeaders: Record<string, string>\n}\n\nconst MoviieContext = createContext<MoviieContextValue | null>(null)\n\nlet fallbackContext: MoviieContextValue | null = null\n\nfunction getOrCreateFallbackContext(): MoviieContextValue {\n if (!fallbackContext) {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const viewerTokenStore = new MemoryViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: undefined,\n clientInfo,\n sdkVersion,\n })\n fallbackContext = {\n client,\n viewerTokenStore,\n publishableKey: null,\n clientInfo,\n sdkVersion,\n telemetryHeaders: buildClientHeaders({\n clientInfo,\n sdkVersion,\n }),\n }\n }\n return fallbackContext\n}\n\nexport function useMoviieContext(): MoviieContextValue {\n const ctx = useContext(MoviieContext)\n return ctx ?? getOrCreateFallbackContext()\n}\n\nexport function MoviieProvider({\n publishableKey,\n children,\n}: {\n publishableKey?: string | null\n children: ReactNode\n}) {\n const value = useMemo((): MoviieContextValue => {\n const sdkVersion = MOVIIE_PLAYER_EXPO_PKG_VERSION\n const clientInfo = buildPlatformClientInfo(sdkVersion)\n const trimmedKey = publishableKey?.trim()\n const viewerTokenStore = new SecureStoreViewerTokenStore()\n const client = new MoviieClient({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n const telemetryHeaders = buildClientHeaders({\n publishableKey: trimmedKey || undefined,\n clientInfo,\n sdkVersion,\n })\n return {\n client,\n viewerTokenStore,\n publishableKey: trimmedKey ?? null,\n clientInfo,\n sdkVersion,\n telemetryHeaders,\n }\n }, [publishableKey])\n\n return (\n <MoviieContext.Provider value={value}>{children}</MoviieContext.Provider>\n )\n}\n"]}
package/dist/index.cjs CHANGED
@@ -46,7 +46,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
46
46
  });
47
47
 
48
48
  // src/constants.ts
49
- var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.5.5";
49
+ var MOVIIE_PLAYER_EXPO_PKG_VERSION = "0.6.1";
50
50
  var MOVIIE_PLAYBACK_MEMORY_CACHE_TTL_MS = 5 * 60 * 1e3;
51
51
  var MOVIIE_PLAYBACK_PROFILE = {
52
52
  VSL: "vsl",
@@ -436,12 +436,19 @@ function useMoviiePlayback(args) {
436
436
  }
437
437
 
438
438
  // src/lib/safe-player-access.ts
439
- var NATIVE_SHARED_OBJECT_ERROR_PATTERN = /NativeSharedObjectNotFoundException|Unable to find the native shared object/i;
439
+ var NATIVE_SHARED_OBJECT_ERROR_PATTERN = /NativeSharedObjectNotFoundException|Unable to find the native shared object|shared object that was already released|cannot be cast to type .*VideoPlayer.*received .*Integer/i;
440
440
  function isDisposedNativePlayerError(error) {
441
441
  if (!(error instanceof Error)) {
442
442
  return false;
443
443
  }
444
- return NATIVE_SHARED_OBJECT_ERROR_PATTERN.test(error.message);
444
+ if (NATIVE_SHARED_OBJECT_ERROR_PATTERN.test(error.message)) {
445
+ return true;
446
+ }
447
+ const cause = error.cause;
448
+ if (cause instanceof Error) {
449
+ return NATIVE_SHARED_OBJECT_ERROR_PATTERN.test(cause.message);
450
+ }
451
+ return false;
445
452
  }
446
453
  function safeInvokePlayerOperation(operation) {
447
454
  try {
@@ -900,20 +907,11 @@ function useMoviieEvent(player, eventName, handler) {
900
907
  return;
901
908
  }
902
909
  if (eventName === playerTypes.PLAYER_API_EVENTS.TIME_UPDATE) {
903
- const previousInterval = safeReadPlayerProperty(() => player.timeUpdateEventInterval, 0);
904
- if (previousInterval <= 0) {
905
- safeInvokePlayerOperation(() => {
906
- player.timeUpdateEventInterval = 0.25;
907
- });
908
- }
909
910
  const sub = player.addListener("timeUpdate", () => {
910
911
  handler();
911
912
  });
912
913
  return () => {
913
914
  sub.remove();
914
- safeInvokePlayerOperation(() => {
915
- player.timeUpdateEventInterval = previousInterval;
916
- });
917
915
  };
918
916
  }
919
917
  if (eventName === playerTypes.PLAYER_API_EVENTS.PLAY) {
@@ -1505,46 +1503,52 @@ function computePlaybackBuffering(state) {
1505
1503
  }
1506
1504
  return false;
1507
1505
  }
1506
+ function readPlaybackUiSnapshot(player) {
1507
+ return {
1508
+ bufferedPosition: safeReadPlayerProperty(() => player.bufferedPosition, 0),
1509
+ currentTime: safeReadPlayerProperty(() => player.currentTime, 0),
1510
+ duration: safeReadPlayerProperty(() => player.duration, 0),
1511
+ playing: safeReadPlayerProperty(() => player.playing, false),
1512
+ status: safeReadPlayerProperty(() => player.status, "idle")
1513
+ };
1514
+ }
1508
1515
  function usePlaybackUiSync(player) {
1509
- const [snapshot, setSnapshot] = React.useState({
1510
- bufferedPosition: player.bufferedPosition,
1511
- currentTime: player.currentTime,
1512
- duration: player.duration,
1513
- playing: player.playing,
1514
- status: player.status
1515
- });
1516
+ const [snapshot, setSnapshot] = React.useState(() => readPlaybackUiSnapshot(player));
1516
1517
  React.useEffect(() => {
1517
1518
  const subscriptions = [
1518
1519
  player.addListener("timeUpdate", ({ currentTime }) => {
1519
1520
  setSnapshot((previous) => ({
1520
1521
  ...previous,
1521
- bufferedPosition: player.bufferedPosition,
1522
+ bufferedPosition: safeReadPlayerProperty(
1523
+ () => player.bufferedPosition,
1524
+ previous.bufferedPosition
1525
+ ),
1522
1526
  currentTime,
1523
- duration: player.duration,
1524
- status: player.status
1527
+ duration: safeReadPlayerProperty(() => player.duration, previous.duration),
1528
+ status: safeReadPlayerProperty(() => player.status, previous.status)
1525
1529
  }));
1526
1530
  }),
1527
1531
  player.addListener("playingChange", ({ isPlaying }) => {
1528
1532
  setSnapshot((previous) => ({
1529
1533
  ...previous,
1530
1534
  playing: isPlaying,
1531
- bufferedPosition: player.bufferedPosition,
1532
- status: player.status
1535
+ bufferedPosition: safeReadPlayerProperty(
1536
+ () => player.bufferedPosition,
1537
+ previous.bufferedPosition
1538
+ ),
1539
+ status: safeReadPlayerProperty(() => player.status, previous.status)
1533
1540
  }));
1534
1541
  }),
1535
1542
  player.addListener("sourceChange", () => {
1536
- setSnapshot({
1537
- bufferedPosition: player.bufferedPosition,
1538
- currentTime: player.currentTime,
1539
- duration: player.duration,
1540
- playing: player.playing,
1541
- status: player.status
1542
- });
1543
+ setSnapshot(readPlaybackUiSnapshot(player));
1543
1544
  }),
1544
1545
  player.addListener("statusChange", ({ status }) => {
1545
1546
  setSnapshot((previous) => ({
1546
1547
  ...previous,
1547
- bufferedPosition: player.bufferedPosition,
1548
+ bufferedPosition: safeReadPlayerProperty(
1549
+ () => player.bufferedPosition,
1550
+ previous.bufferedPosition
1551
+ ),
1548
1552
  status
1549
1553
  }));
1550
1554
  }),
@@ -1552,10 +1556,13 @@ function usePlaybackUiSync(player) {
1552
1556
  setSnapshot((previous) => ({
1553
1557
  ...previous,
1554
1558
  playing: false,
1555
- bufferedPosition: player.bufferedPosition,
1556
- currentTime: player.currentTime,
1557
- duration: player.duration,
1558
- status: player.status
1559
+ bufferedPosition: safeReadPlayerProperty(
1560
+ () => player.bufferedPosition,
1561
+ previous.bufferedPosition
1562
+ ),
1563
+ currentTime: safeReadPlayerProperty(() => player.currentTime, previous.currentTime),
1564
+ duration: safeReadPlayerProperty(() => player.duration, previous.duration),
1565
+ status: safeReadPlayerProperty(() => player.status, previous.status)
1559
1566
  }));
1560
1567
  })
1561
1568
  ];
@@ -1567,9 +1574,7 @@ function usePlaybackUiSync(player) {
1567
1574
  }, [player]);
1568
1575
  return snapshot;
1569
1576
  }
1570
- var MoviieSkinChromeContext = React.createContext(
1571
- null
1572
- );
1577
+ var MoviieSkinChromeContext = React.createContext(null);
1573
1578
  function useMoviieSkinChrome() {
1574
1579
  const ctx = React.useContext(MoviieSkinChromeContext);
1575
1580
  if (ctx == null) {
@@ -1612,15 +1617,17 @@ function MoviieSkinChromeProvider({
1612
1617
  const ui = usePlaybackUiSync(player);
1613
1618
  const [chromeVisible, setChromeVisible] = React.useState(visibleByDefault);
1614
1619
  const [timelineScrubClockSeconds, setTimelineScrubClockSeconds] = React.useState(null);
1620
+ const playerIsLive = safeReadPlayerProperty(() => player.isLive, false);
1621
+ const playerLoop = safeReadPlayerProperty(() => player.loop, false);
1615
1622
  const playbackEndedForChrome = React.useMemo(
1616
1623
  () => computeMoviiePlaybackEnded({
1617
1624
  playing: ui.playing,
1618
1625
  currentTime: ui.currentTime,
1619
1626
  duration: ui.duration,
1620
- isLive: player.isLive,
1621
- loop: player.loop
1627
+ isLive: playerIsLive,
1628
+ loop: playerLoop
1622
1629
  }),
1623
- [ui.playing, ui.currentTime, ui.duration, player.isLive, player.loop]
1630
+ [ui.playing, ui.currentTime, ui.duration, playerIsLive, playerLoop]
1624
1631
  );
1625
1632
  React.useEffect(() => {
1626
1633
  if (playbackEndedForChrome) {
@@ -1643,28 +1650,40 @@ function MoviieSkinChromeProvider({
1643
1650
  setChromeVisible(false);
1644
1651
  }, []);
1645
1652
  const togglePlay = React.useCallback(() => {
1646
- if (player.playing) {
1647
- player.pause();
1653
+ const isPlaying = safeReadPlayerProperty(() => player.playing, false);
1654
+ if (isPlaying) {
1655
+ safeInvokePlayerOperation(() => player.pause());
1648
1656
  return;
1649
1657
  }
1650
- if (computeMoviiePlaybackEnded({
1658
+ const ended = computeMoviiePlaybackEnded({
1651
1659
  playing: false,
1652
- currentTime: player.currentTime,
1653
- duration: player.duration,
1654
- isLive: player.isLive,
1655
- loop: player.loop
1656
- })) {
1657
- player.currentTime = 0;
1658
- }
1659
- player.play();
1660
+ currentTime: safeReadPlayerProperty(() => player.currentTime, 0),
1661
+ duration: safeReadPlayerProperty(() => player.duration, 0),
1662
+ isLive: safeReadPlayerProperty(() => player.isLive, false),
1663
+ loop: safeReadPlayerProperty(() => player.loop, false)
1664
+ });
1665
+ if (ended) {
1666
+ safeInvokePlayerOperation(() => {
1667
+ player.currentTime = 0;
1668
+ });
1669
+ }
1670
+ safeInvokePlayerOperation(() => player.play());
1660
1671
  setChromeVisible(false);
1661
1672
  }, [player]);
1662
1673
  const seekBack = React.useCallback(() => {
1663
- void player.seekBy(-MOVIIE_SKIN_SEEK_JUMP_SECONDS);
1674
+ safeInvokePlayerOperation(() => {
1675
+ void silenceDisposedPlayerRejection(
1676
+ Promise.resolve(player.seekBy(-MOVIIE_SKIN_SEEK_JUMP_SECONDS))
1677
+ );
1678
+ });
1664
1679
  setChromeVisible(false);
1665
1680
  }, [player]);
1666
1681
  const seekForward = React.useCallback(() => {
1667
- void player.seekBy(MOVIIE_SKIN_SEEK_JUMP_SECONDS);
1682
+ safeInvokePlayerOperation(() => {
1683
+ void silenceDisposedPlayerRejection(
1684
+ Promise.resolve(player.seekBy(MOVIIE_SKIN_SEEK_JUMP_SECONDS))
1685
+ );
1686
+ });
1668
1687
  setChromeVisible(false);
1669
1688
  }, [player]);
1670
1689
  const toggleFullscreen = React.useCallback(() => {
@@ -1687,10 +1706,10 @@ function MoviieSkinChromeProvider({
1687
1706
  const isBuffering = React.useMemo(
1688
1707
  () => computePlaybackBuffering({
1689
1708
  ...ui,
1690
- isLive: player.isLive,
1691
- loop: player.loop
1709
+ isLive: playerIsLive,
1710
+ loop: playerLoop
1692
1711
  }),
1693
- [ui, player.isLive, player.loop]
1712
+ [ui, playerIsLive, playerLoop]
1694
1713
  );
1695
1714
  const value = React.useMemo(
1696
1715
  () => ({
@@ -2112,22 +2131,13 @@ function createMoviieSkinBottomTimelineStyles(layout) {
2112
2131
  });
2113
2132
  }
2114
2133
  function MoviieSkinBottomTimeline() {
2115
- const {
2116
- playback,
2117
- chromeVisible,
2118
- layout,
2119
- player,
2120
- setTimelineScrubClockSeconds,
2121
- ui
2122
- } = useMoviieSkinChrome();
2123
- const styles6 = React.useMemo(
2124
- () => createMoviieSkinBottomTimelineStyles(layout),
2125
- [layout]
2126
- );
2134
+ const { playback, chromeVisible, layout, player, setTimelineScrubClockSeconds, ui } = useMoviieSkinChrome();
2135
+ const styles6 = React.useMemo(() => createMoviieSkinBottomTimelineStyles(layout), [layout]);
2127
2136
  const { controls } = playback;
2128
2137
  const accent = resolveSkinAccentColor(playback.branding.primaryColor);
2129
2138
  const foreground = MOVIIE_SKIN_CHROME_FOREGROUND_HEX;
2130
- const durationOk = controls.showProgress && Number.isFinite(ui.duration) && ui.duration > 0 && !player.isLive;
2139
+ const playerIsLive = safeReadPlayerProperty(() => player.isLive, false);
2140
+ const durationOk = controls.showProgress && Number.isFinite(ui.duration) && ui.duration > 0 && !playerIsLive;
2131
2141
  const progressRatioLive = computePlaybackProgressRatio({
2132
2142
  currentTime: ui.currentTime,
2133
2143
  duration: ui.duration,
@@ -2168,28 +2178,18 @@ function MoviieSkinBottomTimeline() {
2168
2178
  React.useEffect(() => {
2169
2179
  thumbBaseDiamSV.value = layout.timelineThumbDiameterPx;
2170
2180
  barHeightSV.value = layout.timelineBarHeightPx;
2171
- }, [
2172
- layout.timelineThumbDiameterPx,
2173
- layout.timelineBarHeightPx,
2174
- thumbBaseDiamSV,
2175
- barHeightSV
2176
- ]);
2181
+ }, [layout.timelineThumbDiameterPx, layout.timelineBarHeightPx, thumbBaseDiamSV, barHeightSV]);
2177
2182
  React.useEffect(() => {
2178
2183
  chromeVisibleSV.value = chromeVisible;
2179
2184
  if (chromeVisible) {
2180
2185
  timelineAccentEngagedSV.value = false;
2181
2186
  awaitingUnlockSV.value = false;
2182
2187
  }
2183
- }, [
2184
- chromeVisible,
2185
- chromeVisibleSV,
2186
- timelineAccentEngagedSV,
2187
- awaitingUnlockSV
2188
- ]);
2188
+ }, [chromeVisible, chromeVisibleSV, timelineAccentEngagedSV, awaitingUnlockSV]);
2189
2189
  React.useEffect(() => {
2190
2190
  const sub = player.addListener("statusChange", ({ status }) => {
2191
2191
  if (shouldResumeRef.current && status === "readyToPlay" && !isDraggingRef.current) {
2192
- player.play();
2192
+ safeInvokePlayerOperation(() => player.play());
2193
2193
  }
2194
2194
  });
2195
2195
  return () => sub.remove();
@@ -2212,9 +2212,7 @@ function MoviieSkinBottomTimeline() {
2212
2212
  () => chromeVisibleSV.value || isDraggingSV.value || timelineAccentEngagedSV.value
2213
2213
  );
2214
2214
  const thumbDiamSV = AnimatedReanimated.useDerivedValue(
2215
- () => isDraggingSV.value ? Math.round(
2216
- thumbBaseDiamSV.value * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER
2217
- ) : thumbBaseDiamSV.value
2215
+ () => isDraggingSV.value ? Math.round(thumbBaseDiamSV.value * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER) : thumbBaseDiamSV.value
2218
2216
  );
2219
2217
  const progressBarStyle = AnimatedReanimated.useAnimatedStyle(() => ({
2220
2218
  backgroundColor: showAccentSV.value ? accent : foreground,
@@ -2245,7 +2243,7 @@ function MoviieSkinBottomTimeline() {
2245
2243
  const onScrubBegin = React.useCallback(() => {
2246
2244
  isDraggingRef.current = true;
2247
2245
  if (!shouldResumeRef.current) {
2248
- shouldResumeRef.current = player.playing;
2246
+ shouldResumeRef.current = safeReadPlayerProperty(() => player.playing, false);
2249
2247
  }
2250
2248
  }, [player]);
2251
2249
  const onScrubUpdate = React.useCallback(
@@ -2265,9 +2263,11 @@ function MoviieSkinBottomTimeline() {
2265
2263
  durationSeconds: dur,
2266
2264
  chapters: chaptersRef.current
2267
2265
  });
2268
- player.currentTime = targetTime;
2266
+ safeInvokePlayerOperation(() => {
2267
+ player.currentTime = targetTime;
2268
+ });
2269
2269
  if (shouldResumeRef.current) {
2270
- player.play();
2270
+ safeInvokePlayerOperation(() => player.play());
2271
2271
  }
2272
2272
  },
2273
2273
  [setTimelineScrubClockSeconds, player, durationSV]
@@ -2369,9 +2369,7 @@ function MoviieSkinBottomTimeline() {
2369
2369
  }
2370
2370
  const unifiedSlotHeightPx = Math.max(
2371
2371
  layout.timelineThumbDiameterPx,
2372
- Math.round(
2373
- layout.timelineThumbDiameterPx * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER
2374
- )
2372
+ Math.round(layout.timelineThumbDiameterPx * MOVIIE_SKIN_TIMELINE_THUMB_DRAG_DIAMETER_MULTIPLIER)
2375
2373
  );
2376
2374
  const scrubHitSlop = {
2377
2375
  top: MOVIIE_SKIN_TIMELINE_SCRUB_HIT_SLOP_TOP_DP,
@@ -2454,13 +2452,14 @@ var styles = reactNative.StyleSheet.create({
2454
2452
  function MoviieSkinSmartProgress() {
2455
2453
  const { playback, player, timelineScrubClockSeconds, ui } = useMoviieSkinChrome();
2456
2454
  const accent = resolveSkinAccentColor(playback.branding.primaryColor);
2457
- const durationOk = playback.smartProgressEnabled && Number.isFinite(ui.duration) && ui.duration > 0 && !player.isLive;
2458
- const [barVisible, setBarVisible] = React.useState(() => !player.muted);
2459
- const hasUserInteractedRef = React.useRef(!player.muted);
2455
+ const durationOk = playback.smartProgressEnabled && Number.isFinite(ui.duration) && ui.duration > 0 && !safeReadPlayerProperty(() => player.isLive, false);
2456
+ const initialMuted = safeReadPlayerProperty(() => player.muted, true);
2457
+ const [barVisible, setBarVisible] = React.useState(() => !initialMuted);
2458
+ const hasUserInteractedRef = React.useRef(!initialMuted);
2460
2459
  const lastDisplayedRef = React.useRef(0);
2461
2460
  const progressAnim = React.useRef(new reactNative.Animated.Value(0)).current;
2462
2461
  const syncMutedVisibility = React.useCallback(() => {
2463
- const muted = player.muted;
2462
+ const muted = safeReadPlayerProperty(() => player.muted, true);
2464
2463
  if (!muted) {
2465
2464
  hasUserInteractedRef.current = true;
2466
2465
  setBarVisible(true);
@@ -2806,18 +2805,20 @@ function MoviieSkinVideoOverlay() {
2806
2805
  const { controls } = playback;
2807
2806
  const fg = MOVIIE_SKIN_CHROME_FOREGROUND_HEX;
2808
2807
  const clockDisplaySeconds = timelineScrubClockSeconds ?? ui.currentTime;
2808
+ const playerIsLive = safeReadPlayerProperty(() => player.isLive, false);
2809
+ const playerLoop = safeReadPlayerProperty(() => player.loop, false);
2809
2810
  const playbackEndedForUi = React.useMemo(
2810
2811
  () => computeMoviiePlaybackEnded({
2811
2812
  playing: ui.playing,
2812
2813
  currentTime: clockDisplaySeconds,
2813
2814
  duration: ui.duration,
2814
- isLive: player.isLive,
2815
- loop: player.loop
2815
+ isLive: playerIsLive,
2816
+ loop: playerLoop
2816
2817
  }),
2817
- [ui.playing, clockDisplaySeconds, ui.duration, player.isLive, player.loop]
2818
+ [ui.playing, clockDisplaySeconds, ui.duration, playerIsLive, playerLoop]
2818
2819
  );
2819
2820
  const { centerSeekBackwardEnabled, centerSeekForwardEnabled } = React.useMemo(() => {
2820
- const alignSeekButtonsWithPlay = controls.showPlay && !player.isLive;
2821
+ const alignSeekButtonsWithPlay = controls.showPlay && !playerIsLive;
2821
2822
  const hideSeekClusterAtEnd = playbackEndedForUi;
2822
2823
  return {
2823
2824
  centerSeekBackwardEnabled: !hideSeekClusterAtEnd && (controls.seekBackwardEnabled || alignSeekButtonsWithPlay),
@@ -2827,7 +2828,7 @@ function MoviieSkinVideoOverlay() {
2827
2828
  controls.seekBackwardEnabled,
2828
2829
  controls.seekForwardEnabled,
2829
2830
  controls.showPlay,
2830
- player.isLive,
2831
+ playerIsLive,
2831
2832
  playbackEndedForUi
2832
2833
  ]);
2833
2834
  const centerPlayShowsReplay = playbackEndedForUi;
@@ -3627,7 +3628,7 @@ var MoviieVideoImpl = React.forwardRef(
3627
3628
  React.useEffect(() => {
3628
3629
  if (!castAdapter?.isAvailable() || !playback || !player) return;
3629
3630
  if (castState !== "connected") return;
3630
- const startSeconds = player.currentTime ?? 0;
3631
+ const startSeconds = safeReadPlayerProperty(() => player.currentTime, 0);
3631
3632
  void castAdapter.loadMedia({
3632
3633
  uri: playback.playback.uri,
3633
3634
  title: playback.title,
@@ -3635,10 +3636,7 @@ var MoviieVideoImpl = React.forwardRef(
3635
3636
  durationSeconds: playback.durationSeconds ?? null,
3636
3637
  startSeconds
3637
3638
  }).then(() => {
3638
- try {
3639
- player.pause();
3640
- } catch {
3641
- }
3639
+ safeInvokePlayerOperation(() => player.pause());
3642
3640
  }).catch(() => {
3643
3641
  });
3644
3642
  }, [castAdapter, castState, playback, player]);