@nationaldesignstudio/react 0.6.0 → 0.7.0

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.
Files changed (106) hide show
  1. package/dist/accordion/index.d.ts +95 -0
  2. package/dist/accordion/index.js +143 -0
  3. package/dist/accordion/index.js.map +1 -0
  4. package/dist/background/index.d.ts +149 -0
  5. package/dist/background/index.js +200 -0
  6. package/dist/background/index.js.map +1 -0
  7. package/dist/banner/index.d.ts +101 -0
  8. package/dist/banner/index.js +81 -0
  9. package/dist/banner/index.js.map +1 -0
  10. package/dist/blurred-video-backdrop/index.d.ts +233 -0
  11. package/dist/blurred-video-backdrop/index.js +266 -0
  12. package/dist/blurred-video-backdrop/index.js.map +1 -0
  13. package/dist/button/index.d.ts +180 -0
  14. package/dist/button/index.js +169 -0
  15. package/dist/button/index.js.map +1 -0
  16. package/dist/button-B2g5fH9b.d.ts +152 -0
  17. package/dist/card/index.d.ts +406 -0
  18. package/dist/card/index.js +219 -0
  19. package/dist/card/index.js.map +1 -0
  20. package/dist/card-grid/index.d.ts +90 -0
  21. package/dist/card-grid/index.js +74 -0
  22. package/dist/card-grid/index.js.map +1 -0
  23. package/dist/component-registry.md +136 -2
  24. package/dist/dev-toolbar/index.d.ts +8 -0
  25. package/dist/dev-toolbar/index.js +206 -0
  26. package/dist/dev-toolbar/index.js.map +1 -0
  27. package/dist/dialog/index.d.ts +268 -0
  28. package/dist/dialog/index.js +288 -0
  29. package/dist/dialog/index.js.map +1 -0
  30. package/dist/faq-section/index.d.ts +47 -0
  31. package/dist/faq-section/index.js +152 -0
  32. package/dist/faq-section/index.js.map +1 -0
  33. package/dist/grid-overlay/index.d.ts +10 -0
  34. package/dist/grid-overlay/index.js +38 -0
  35. package/dist/grid-overlay/index.js.map +1 -0
  36. package/dist/hero/index.d.ts +462 -0
  37. package/dist/hero/index.js +494 -0
  38. package/dist/hero/index.js.map +1 -0
  39. package/dist/hooks/index.d.ts +150 -0
  40. package/dist/hooks/index.js +339 -0
  41. package/dist/hooks/index.js.map +1 -0
  42. package/dist/index.d.ts +46 -5339
  43. package/dist/index.js +157 -4080
  44. package/dist/index.js.map +1 -1
  45. package/dist/input/index.d.ts +404 -0
  46. package/dist/input/index.js +393 -0
  47. package/dist/input/index.js.map +1 -0
  48. package/dist/navbar/index.d.ts +68 -0
  49. package/dist/navbar/index.js +227 -0
  50. package/dist/navbar/index.js.map +1 -0
  51. package/dist/ndstudio-footer/index.d.ts +32 -0
  52. package/dist/ndstudio-footer/index.js +35 -0
  53. package/dist/ndstudio-footer/index.js.map +1 -0
  54. package/dist/pager-control/index.d.ts +173 -0
  55. package/dist/pager-control/index.js +267 -0
  56. package/dist/pager-control/index.js.map +1 -0
  57. package/dist/popover/index.d.ts +200 -0
  58. package/dist/popover/index.js +290 -0
  59. package/dist/popover/index.js.map +1 -0
  60. package/dist/prose/index.d.ts +39 -0
  61. package/dist/prose/index.js +56 -0
  62. package/dist/prose/index.js.map +1 -0
  63. package/dist/quote-block/index.d.ts +156 -0
  64. package/dist/quote-block/index.js +321 -0
  65. package/dist/quote-block/index.js.map +1 -0
  66. package/dist/river/index.d.ts +100 -0
  67. package/dist/river/index.js +107 -0
  68. package/dist/river/index.js.map +1 -0
  69. package/dist/select/index.d.ts +188 -0
  70. package/dist/select/index.js +295 -0
  71. package/dist/select/index.js.map +1 -0
  72. package/dist/theme/index.d.ts +149 -0
  73. package/dist/theme/index.js +211 -0
  74. package/dist/theme/index.js.map +1 -0
  75. package/dist/theme-CzBPUlh_.d.ts +332 -0
  76. package/dist/tooltip/index.d.ts +166 -0
  77. package/dist/tooltip/index.js +200 -0
  78. package/dist/tooltip/index.js.map +1 -0
  79. package/dist/tout/index.d.ts +157 -0
  80. package/dist/tout/index.js +315 -0
  81. package/dist/tout/index.js.map +1 -0
  82. package/dist/two-column-section/index.d.ts +122 -0
  83. package/dist/two-column-section/index.js +121 -0
  84. package/dist/two-column-section/index.js.map +1 -0
  85. package/dist/us-gov-banner/index.d.ts +141 -0
  86. package/dist/us-gov-banner/index.js +74 -0
  87. package/dist/us-gov-banner/index.js.map +1 -0
  88. package/dist/use-captions-AkKlJhov.d.ts +71 -0
  89. package/dist/utils/index.d.ts +7 -0
  90. package/dist/utils/index.js +12 -0
  91. package/dist/utils/index.js.map +1 -0
  92. package/dist/video-dialog/index.d.ts +106 -0
  93. package/dist/video-dialog/index.js +1305 -0
  94. package/dist/video-dialog/index.js.map +1 -0
  95. package/dist/video-player/index.d.ts +115 -0
  96. package/dist/video-player/index.js +879 -0
  97. package/dist/video-player/index.js.map +1 -0
  98. package/dist/video-player-qxf-BURH.d.ts +236 -0
  99. package/dist/video-with-backdrop/index.d.ts +267 -0
  100. package/dist/video-with-backdrop/index.js +1284 -0
  101. package/dist/video-with-backdrop/index.js.map +1 -0
  102. package/package.json +13 -2
  103. package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +5 -27
  104. package/src/theme/hooks.ts +2 -0
  105. package/src/theme/index.ts +2 -0
  106. package/src/theme/theme-provider.tsx +2 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/components/atoms/video-player/caption-overlay.tsx","../../src/hooks/use-captions.ts","../../src/hooks/use-video-keyboard.ts","../../src/components/atoms/video-player/video-player.tsx"],"names":["twMerge","React","React2","React3","tv","jsx"],"mappings":";;;;;;;AAKO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAOA,MAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACGA,IAAM,yBAAyB,EAAA,CAAG;AAAA,EACjC,IAAA,EAAM;AAAA;AAAA,IAEL,qBAAA;AAAA,IACA,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,QAAA,EAAU;AAAA,MACT,MAAA,EAAQ,WAAA;AAAA,MACR,WAAA,EAAa;AAAA;AACd,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,QAAA,EAAU;AAAA;AAEZ,CAAC;AAKD,IAAM,sBAAsB,EAAA,CAAG;AAAA,EAC9B,IAAA,EAAM;AAAA,IACL,kCAAA;AAAA,IACA,mBAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,2BAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,EAAA,EAAI,kCAAA;AAAA,MACJ,EAAA,EAAI;AAAA;AACL,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,IAAA,EAAM;AAAA;AAER,CAAC,CAAA;AA0BD,IAAM,cAAA,GAAuBC,MAAA,CAAA,UAAA;AAAA,EAC5B,CAAC,EAAE,SAAA,EAAW,GAAA,EAAK,IAAA,EAAM,UAAU,IAAA,EAAM,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAE5D,IAAA,MAAM,WAAA,GAAc,KAAK,IAAA,IAAQ,IAAA;AAGjC,IAAA,IAAI,CAAC,WAAA,EAAa;AACjB,MAAA,OAAO,IAAA;AAAA,IACR;AAEA,IAAA,uBACC,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAW,EAAA,CAAG,sBAAA,CAAuB,EAAE,QAAA,EAAU,GAAG,SAAS,CAAA;AAAA,QAC7D,WAAA,EAAU,QAAA;AAAA,QACV,YAAA,EAAW,eAAA;AAAA,QACV,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAA,GAAA,CAAC,UAAK,SAAA,EAAW,mBAAA,CAAoB,EAAE,IAAA,EAAM,GAAI,QAAA,EAAA,WAAA,EAAY;AAAA;AAAA,KAC9D;AAAA,EAEF;AACD;AAEA,cAAA,CAAe,WAAA,GAAc,gBAAA;AClF7B,SAAS,kBAAkB,SAAA,EAA2B;AACrD,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,IAAA,EAAK,CAAE,MAAM,GAAG,CAAA;AACxC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACvB,IAAA,KAAA,GAAQ,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACpC,IAAA,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACtC,IAAA,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACrC,CAAA,MAAA,IAAW,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC9B,IAAA,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACtC,IAAA,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,KAAA,GAAQ,IAAA,GAAO,OAAA,GAAU,EAAA,GAAK,OAAA;AACtC;AAKA,SAAS,SAAS,UAAA,EAAkC;AACnD,EAAA,MAAM,OAAqB,EAAC;AAC5B,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,EAAK,CAAE,MAAM,IAAI,CAAA;AAE1C,EAAA,IAAI,CAAA,GAAI,CAAA;AAGR,EAAA,OAAO,CAAA,GAAI,MAAM,MAAA,IAAU,CAAC,MAAM,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA,EAAG;AACrD,IAAA,CAAA,EAAA;AAAA,EACD;AAEA,EAAA,OAAO,CAAA,GAAI,MAAM,MAAA,EAAQ;AACxB,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAG3B,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,KAAK,CAAA,EAAG;AACzB,MAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAA;AAGhE,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AACjC,MAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,QAAA,CAAS,CAAC,CAAC,CAAA;AAC7C,MAAA,MAAM,SAAA,GAAY,kBAAkB,QAAQ,CAAA;AAG5C,MAAA,MAAM,YAAsB,EAAC;AAC7B,MAAA,CAAA,EAAA;AACA,MAAA,OACC,CAAA,GAAI,KAAA,CAAM,MAAA,IACV,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,IACpB,CAAC,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA,EACvB;AAED,QAAA,IAAI,CAAC,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,EAAG;AACnC,UAAA,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CAAA;AAAA,QAC/B;AACA,QAAA,CAAA,EAAA;AAAA,MACD;AAEA,MAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACzB,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACT,EAAA,EAAI,CAAA,IAAA,EAAO,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,UACtB,SAAA;AAAA,UACA,OAAA;AAAA,UACA,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAI;AAAA,SACzB,CAAA;AAAA,MACF;AAAA,IACD,CAAA,MAAO;AACN,MAAA,CAAA,EAAA;AAAA,IACD;AAAA,EACD;AAEA,EAAA,OAAO,IAAA;AACR;AAMA,SAAS,aAAa,IAAA,EAAsB;AAC3C,EAAA,OAAO,IAAA,CACL,QAAQ,iBAAA,EAAmB,EAAE,EAC7B,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA,CACtB,OAAA,CAAQ,UAAU,GAAG,CAAA,CACrB,QAAQ,OAAA,EAAS,GAAG,EACpB,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA,CACpB,IAAA,EAAK;AACR;AA2DO,SAAS,WAAA,CACf,OAAA,GAA8B,EAAC,EACX;AACpB,EAAA,MAAM,EAAE,GAAA,EAAK,OAAA,EAAS,YAAY,IAAA,EAAM,WAAA,EAAa,cAAa,GAAI,OAAA;AAEtE,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUC,MAAA,CAAA,QAAA,CAAuB,EAAE,CAAA;AACvD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAUA,gBAAS,CAAC,CAAA;AACxD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAUA,gBAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,gBAAuB,IAAI,CAAA;AAG3D,EAAA,MAAM,cAAc,YAAA,IAAgB,YAAA;AAGpC,EAAMA,iBAAU,MAAM;AACrB,IAAA,IAAI,OAAA,EAAS;AAEZ,MAAA,MAAM,MAAA,GAAS,SAAS,OAAO,CAAA;AAC/B,MAAA,OAAA;AAAA,QACC,SAAA,GACG,MAAA,CAAO,GAAA,CAAI,CAAC,SAAS,EAAE,GAAG,GAAA,EAAK,IAAA,EAAM,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,GAAI,CAAA,GAC9D;AAAA,OACJ;AACA,MAAA;AAAA,IACD;AAEA,IAAA,IAAI,CAAC,GAAA,EAAK;AACT,MAAA,OAAA,CAAQ,EAAE,CAAA;AACV,MAAA;AAAA,IACD;AAEA,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAA,KAAA,CAAM,GAAG,CAAA,CACP,IAAA,CAAK,CAAC,QAAA,KAAa;AACnB,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AACjB,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,MAC/D;AACA,MAAA,OAAO,SAAS,IAAA,EAAK;AAAA,IACtB,CAAC,CAAA,CACA,IAAA,CAAK,CAAC,UAAA,KAAe;AACrB,MAAA,MAAM,MAAA,GAAS,SAAS,UAAU,CAAA;AAClC,MAAA,OAAA;AAAA,QACC,SAAA,GACG,MAAA,CAAO,GAAA,CAAI,CAAC,SAAS,EAAE,GAAG,GAAA,EAAK,IAAA,EAAM,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,GAAI,CAAA,GAC9D;AAAA,OACJ;AAAA,IACD,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AACf,MAAA,QAAA,CAAS,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IAC7D,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACd,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACnB,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,GAAA,EAAK,OAAA,EAAS,SAAS,CAAC,CAAA;AAG5B,EAAA,MAAM,SAAA,GAAkBA,eAAQ,MAAM;AACrC,IAAA,OACC,IAAA,CAAK,IAAA;AAAA,MACJ,CAAC,GAAA,KAAQ,WAAA,IAAe,GAAA,CAAI,SAAA,IAAa,eAAe,GAAA,CAAI;AAAA,KAC7D,IAAK,IAAA;AAAA,EAEP,CAAA,EAAG,CAAC,IAAA,EAAM,WAAW,CAAC,CAAA;AAGtB,EAAA,MAAM,oBAAA,GAA6BA,MAAA,CAAA,WAAA,CAAY,CAAC,IAAA,KAAiB;AAChE,IAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,EACrB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACN,IAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAA,EAAgB,oBAAA;AAAA,IAChB,SAAA;AAAA,IACA;AAAA,GACD;AACD;ACpLO,SAAS,gBAAA,CAAiB;AAAA,EAChC,QAAA;AAAA,EACA,OAAA,GAAU,IAAA;AAAA,EACV,UAAA,GAAa,CAAA;AAAA,EACb,UAAA,GAAa,GAAA;AAAA,EACb,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACD,CAAA,EAAoD;AACnD,EAAA,MAAM,aAAA,GAAsBC,MAAA,CAAA,WAAA;AAAA,IAC3B,CAAC,CAAA,KAA2B;AAC3B,MAAA,IAAI,CAAC,OAAA,EAAS;AAEd,MAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,MAAA,IAAI,CAAC,KAAA,EAAO;AAGZ,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IACC,MAAA,CAAO,YAAY,QAAA,IACnB,MAAA,CAAO,YAAY,OAAA,IACnB,MAAA,CAAO,YAAY,UAAA,IACnB,MAAA,CAAO,QAAQ,QAAQ,CAAA,IACvB,OAAO,OAAA,CAAQ,OAAO,KACtB,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,EAC/B;AACD,QAAA;AAAA,MACD;AAEA,MAAA,IAAI,OAAA,GAAU,KAAA;AAEd,MAAA,QAAQ,EAAE,GAAA;AAAK;AAAA,QAEd,KAAK,GAAA;AAAA,QACL,KAAK,UAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,IAAI,YAAA,EAAc;AACjB,YAAA,YAAA,EAAa;AAAA,UACd,CAAA,MAAO;AACN,YAAA,IAAI,MAAM,MAAA,EAAQ;AACjB,cAAA,KAAA,CAAM,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,cAAC,CAAC,CAAA;AAAA,YAC5B,CAAA,MAAO;AACN,cAAA,KAAA,CAAM,KAAA,EAAM;AAAA,YACb;AAAA,UACD;AACA,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,WAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,KAAA,CAAM,cAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,cAAc,UAAU,CAAA;AAC9D,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,YAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,KAAA,CAAM,cAAc,IAAA,CAAK,GAAA;AAAA,YACxB,MAAM,QAAA,IAAY,CAAA;AAAA,YAClB,MAAM,WAAA,GAAc;AAAA,WACrB;AACA,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,SAAA;AACJ,UAAA,KAAA,CAAM,SAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,SAAS,UAAU,CAAA;AACpD,UAAA,KAAA,CAAM,KAAA,GAAQ,KAAA;AACd,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,WAAA;AACJ,UAAA,KAAA,CAAM,SAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,SAAS,UAAU,CAAA;AACpD,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,KAAA,CAAM,KAAA,GAAQ,CAAC,KAAA,CAAM,KAAA;AACrB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,kBAAA,IAAqB;AACrB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,gBAAA,IAAmB;AACnB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,MAAA;AACJ,UAAA,KAAA,CAAM,WAAA,GAAc,CAAA;AACpB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,KAAA;AACJ,UAAA,KAAA,CAAM,WAAA,GAAc,MAAM,QAAA,IAAY,CAAA;AACtC,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA;AAAA,QAGD,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AAAA,QACL,KAAK,GAAA;AACJ,UAAA,IAAI,MAAM,QAAA,EAAU;AACnB,YAAA,MAAM,OAAA,GAAU,QAAA,CAAS,CAAA,CAAE,GAAA,EAAK,EAAE,CAAA,GAAI,EAAA;AACtC,YAAA,KAAA,CAAM,WAAA,GAAc,MAAM,QAAA,GAAW,OAAA;AACrC,YAAA,OAAA,GAAU,IAAA;AAAA,UACX;AACA,UAAA;AAAA;AAGF,MAAA,IAAI,OAAA,EAAS;AACZ,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,QAAA,cAAA,IAAiB;AAAA,MAClB;AAAA,IACD,CAAA;AAAA,IACA;AAAA,MACC,OAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAA;AAAA,MACA,kBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA;AACD,GACD;AAEA,EAAA,MAAM,cAAA,GAAuBA,MAAA,CAAA,OAAA;AAAA,IAC5B,OAAO;AAAA,MACN,SAAA,EAAW,aAAA;AAAA,MACX,QAAA,EAAU,CAAA;AAAA,MACV,IAAA,EAAM,aAAA;AAAA,MACN,YAAA,EAAc;AAAA,KACf,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GACf;AAEA,EAAA,OAAO;AAAA,IACN,aAAA;AAAA,IACA;AAAA,GACD;AACD;AC/LA,IAAM,sBAAsBC,EAAAA,CAAG;AAAA,EAC9B,IAAA,EAAM;AAAA,IACL,UAAA;AAAA,IACA,UAAA;AAAA,IACA,iBAAA;AAAA;AAAA,IAEA,oBAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,WAAA,EAAa;AAAA,MACZ,MAAA,EAAQ,cAAA;AAAA,MACR,KAAA,EAAO,cAAA;AAAA,MACP,KAAA,EAAO,eAAA;AAAA,MACP,MAAA,EAAQ,eAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACP;AAAA,IACA,OAAA,EAAS;AAAA,MACR,IAAA,EAAM,EAAA;AAAA,MACN,EAAA,EAAI,WAAA;AAAA,MACJ,EAAA,EAAI,WAAA;AAAA,MACJ,EAAA,EAAI;AAAA;AACL,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,WAAA,EAAa,MAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEX,CAAC;AAOD,IAAM,0BAA0BA,EAAAA,CAAG;AAAA,EAClC,IAAA,EAAM;AAAA,IACL,kBAAA;AAAA,IACA,eAAA;AAAA;AAAA,IAEA,0CAAA;AAAA,IACA,8EAAA;AAAA,IACA,+BAAA;AAAA,IACA,+BAAA;AAAA,IACA,kCAAA;AAAA,IACA,mCAAA;AAAA;AAAA,IAEA,wEAAA;AAAA,IACA,mEAAA;AAAA,IACA,kCAAA;AAAA,IACA,yCAAA;AAAA,IACA,0EAAA;AAAA,IACA,mCAAA;AAAA,IACA,kCAAA;AAAA,IACA,yCAAA;AAAA;AAAA,IAEA,8DAAA;AAAA,IACA,iEAAA;AAAA,IACA,uCAAA;AAAA,IACA,8DAAA;AAAA,IACA,0BAAA;AAAA;AAAA,IAEA;AAAA;AAEF,CAAC;AAOD,IAAM,iBAAA,GAAyC;AAAA,EAC9C,OAAA,EAAS,KAAA;AAAA,EACT,YAAA,EAAc,KAAA;AAAA;AAAA,EAEd,4BAAA,EAA8B,sCAAA;AAAA,EAC9B,+BAAA,EAAiC,MAAA;AAAA,EACjC,0BAAA,EAA4B;AAC7B,CAAA;AAKA,IAAM,eAAA,GAAuC;AAAA,EAC5C,IAAA,EAAM,CAAA;AAAA,EACN,UAAA,EAAY,aAAA;AAAA;AAAA,EAEZ,2BAAA,EAA6B,MAAA;AAAA,EAC7B,4BAAA,EAA8B,WAAA;AAAA,EAC9B,6BAAA,EAA+B,WAAA;AAAA,EAC/B,iCAAA,EAAmC;AACpC,CAAA;AAKA,IAAM,iBAAA,GAAyC;AAAA,EAC9C,KAAA,EAAO,MAAA;AAAA,EACP,UAAA,EAAY,aAAA;AAAA;AAAA,EAEZ,4BAAA,EAA8B,sCAAA;AAAA,EAC9B,+BAAA,EAAiC,MAAA;AAAA,EACjC,0BAAA,EAA4B;AAC7B,CAAA;AAKA,IAAM,iBAAA,GAAyC;AAAA,EAC9C,UAAA,EAAY,aAAA;AAAA,EACZ,UAAA,EAAY,WAAA;AAAA,EACZ,QAAA,EAAU,MAAA;AAAA,EACV,KAAA,EAAO,OAAA;AAAA,EACP,UAAA,EAAY;AACb,CAAA;AAOA,IAAM,qBAAqBA,EAAAA,CAAG;AAAA,EAC7B,IAAA,EAAM;AAAA;AAAA,IAEL,mBAAA;AAAA;AAAA,IAEA,6BAAA;AAAA;AAAA,IAEA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,OAAA,EAAS;AAAA,MACR,IAAA,EAAM,2BAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACR,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,OAAA,EAAS;AAAA;AAEX,CAAC;AAMD,IAAM,wBAAwBA,EAAAA,CAAG;AAAA,EAChC,IAAA,EAAM;AAAA,IACL,kCAAA;AAAA,IACA,kBAAA;AAAA;AAAA,IAEA,gBAAA;AAAA,IACA,iCAAA;AAAA,IACA,uCAAA;AAAA,IACA,6FAAA;AAAA,IACA,gCAAA;AAAA,IACA;AAAA;AAEF,CAAC;AAKD,IAAM,yBAAyBA,EAAAA,CAAG;AAAA,EACjC,IAAA,EAAM;AAAA,IACL,kBAAA;AAAA,IACA,kCAAA;AAAA,IACA,aAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA;AAEF,CAAC;AAUD,SAAS,cAAA,CACR,QAAA,EACA,GAAA,EACA,OAAA,EACC;AACD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAU,gBAAS,IAAI,CAAA;AACrD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,gBAAuB,IAAI,CAAA;AAC3D,EAAA,MAAM,MAAA,GAAe,cAAgB,IAAI,CAAA;AAEzC,EAAM,iBAAU,MAAM;AACrB,IAAA,IAAgB,CAAC,GAAA,IAAO,CAAC,SAAS,OAAA,EAAS;AAC1C,MAAA;AAAA,IACD;AAEA,IAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,QAAA,CAAS,OAAO,CAAA;AAGxC,IAAA,IAAI,CAAC,WAAA,EAAa;AACjB,MAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AACZ,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA;AAAA,IACD;AAGA,IAAA,IAAI,KAAA,CAAM,WAAA,CAAY,+BAA+B,CAAA,EAAG;AACvD,MAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AACZ,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA;AAAA,IACD;AAGA,IAAA,MAAM,UAAU,YAAY;AAC3B,MAAA,IAAI;AAEH,QAAA,MAAM,SAAA,GAAY,MAAM,OAAO,QAAQ,CAAA;AACvC,QAAA,MAAM,MAAM,SAAA,CAAU,OAAA;AAEtB,QAAA,IAAI,CAAC,GAAA,CAAI,WAAA,EAAY,EAAG;AAEvB,UAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AACZ,UAAA,YAAA,CAAa,KAAK,CAAA;AAClB,UAAA;AAAA,QACD;AAEA,QAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI;AAAA,UACnB,YAAA,EAAc,IAAA;AAAA,UACd,cAAA,EAAgB;AAAA,SAChB,CAAA;AAED,QAAA,GAAA,CAAI,WAAW,GAAG,CAAA;AAClB,QAAA,GAAA,CAAI,YAAY,KAAK,CAAA;AAErB,QAAA,GAAA,CAAI,EAAA,CAAG,GAAA,CAAI,MAAA,CAAO,eAAA,EAAiB,MAAM;AACxC,UAAA,YAAA,CAAa,KAAK,CAAA;AAAA,QACnB,CAAC,CAAA;AAED,QAAA,GAAA,CAAI,EAAA;AAAA,UACH,IAAI,MAAA,CAAO,KAAA;AAAA,UACX,CAAC,QAAiB,IAAA,KAAgD;AACjE,YAAA,IAAI,KAAK,KAAA,EAAO;AACf,cAAA,QAAA,CAAS,IAAI,KAAA,CAAM,CAAA,WAAA,EAAc,IAAA,CAAK,OAAO,EAAE,CAAC,CAAA;AAChD,cAAA,YAAA,CAAa,KAAK,CAAA;AAAA,YACnB;AAAA,UACD;AAAA,SACD;AAEA,QAAA,MAAA,CAAO,OAAA,GAAU,GAAA;AAAA,MAClB,CAAA,CAAA,MAAQ;AAEP,QAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AACZ,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACnB;AAAA,IACD,CAAA;AAEA,IAAA,OAAA,EAAQ;AAER,IAAA,OAAO,MAAM;AACZ,MAAA,IAAI,OAAO,OAAA,EAAS;AACnB,QAAC,MAAA,CAAO,QAAoC,OAAA,EAAQ;AACpD,QAAA,MAAA,CAAO,OAAA,GAAU,IAAA;AAAA,MAClB;AAAA,IACD,CAAA;AAAA,EACD,CAAA,EAAG,CAAC,OAAA,EAAS,GAAA,EAAK,QAAQ,CAAC,CAAA;AAE3B,EAAA,OAAO,EAAE,WAAW,KAAA,EAAM;AAC3B;AA2EA,IAAM,WAAA,GAAoB,MAAA,CAAA,UAAA;AAAA,EACzB,CACC;AAAA,IACC,SAAA;AAAA,IACA,GAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA,GAAW,KAAA;AAAA,IACX,IAAA,GAAO,KAAA;AAAA,IACP,KAAA,GAAQ,KAAA;AAAA,IACR,QAAA,GAAW,IAAA;AAAA,IACX,gBAAA,GAAmB,IAAA;AAAA,IACnB,aAAA,GAAgB,GAAA;AAAA,IAChB,iBAAiB,sBAAA,GAAyB,KAAA;AAAA,IAC1C,WAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU,gBAAA;AAAA,IACV,GAAG;AAAA,KAEJ,GAAA,KACI;AAEJ,IAAA,MAAM,YAAA,GAAqB,cAAuB,IAAI,CAAA;AACtD,IAAA,MAAM,gBAAA,GAAyB,cAAgC,IAAI,CAAA;AACnE,IAAA,MAAM,kBAAA,GAA2B,cAEvB,IAAI,CAAA;AAGd,IAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAU,gBAAS,KAAK,CAAA;AACtD,IAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAU,gBAAS,CAAC,CAAA;AACtD,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,gBAAS,IAAI,CAAA;AACjE,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,MAAA,CAAA,QAAA;AAAA,MACnD;AAAA,KACD;AACA,IAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAU,gBAAS,KAAK,CAAA;AAG5D,IAAA,MAAM,QAAA,GAAiB,eAAQ,MAAM;AACpC,MAAA,IAAI,UAAA,EAAY;AACf,QAAA,OAAO,CAAA,iBAAA,EAAoB,UAAA,CAAW,YAAY,CAAA,sBAAA,EAAyB,WAAW,OAAO,CAAA,oBAAA,CAAA;AAAA,MAC9F;AACA,MAAA,OAAO,GAAA;AAAA,IACR,CAAA,EAAG,CAAC,UAAA,EAAY,GAAG,CAAC,CAAA;AAGpB,IAAA,MAAM,EAAE,SAAA,EAAW,KAAA,EAAO,QAAA,EAAS,GAAI,cAAA;AAAA,MACtC,gBAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACD;AAGA,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,WAAA,CAAY;AAAA,MACjC,GAAA,EAAK,WAAA;AAAA,MACL;AAAA,KACA,CAAA;AAGD,IAAM,iBAAU,MAAM;AACrB,MAAA,IAAI,gBAAA,EAAkB;AACrB,QACC,gBAAA,CACC,UAAU,gBAAA,CAAiB,OAAA;AAAA,MAC9B;AAAA,IACD,CAAA,EAAG,CAAC,gBAAgB,CAAC,CAAA;AAGrB,IAAM,MAAA,CAAA,mBAAA;AAAA,MACL,GAAA;AAAA,MACA,MAAM,YAAA,CAAa;AAAA,KACpB;AAGA,IAAM,iBAAU,MAAM;AACrB,MAAA,IAAI,YAAY,OAAA,EAAS;AACxB,QAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,MACjB;AAAA,IACD,CAAA,EAAG,CAAC,QAAA,EAAU,OAAO,CAAC,CAAA;AAGtB,IAAM,iBAAU,MAAM;AACrB,MAAA,MAAM,QAAQ,gBAAA,CAAiB,OAAA;AAC/B,MAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,MAAA,MAAM,aAAa,MAAM;AACxB,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,MAAA,IAAS;AAAA,MACV,CAAA;AAEA,MAAA,MAAM,cAAc,MAAM;AACzB,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,OAAA,IAAU;AAAA,MACX,CAAA;AAEA,MAAA,MAAM,cAAc,MAAM;AACzB,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,OAAA,IAAU;AAAA,MACX,CAAA;AAEA,MAAA,MAAM,mBAAmB,MAAM;AAC9B,QAAA,cAAA,CAAe,MAAM,WAAW,CAAA;AAChC,QAAA,YAAA,GAAe,MAAM,WAAW,CAAA;AAAA,MACjC,CAAA;AAEA,MAAA,MAAM,gBAAgB,MAAM;AAC3B,QAAA,IAAI,QAAA,EAAU;AACb,UAAA,KAAA,CAAM,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,UAEzB,CAAC,CAAA;AAAA,QACF;AAAA,MACD,CAAA;AAEA,MAAA,KAAA,CAAM,gBAAA,CAAiB,QAAQ,UAAU,CAAA;AACzC,MAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC3C,MAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC3C,MAAA,KAAA,CAAM,gBAAA,CAAiB,cAAc,gBAAgB,CAAA;AACrD,MAAA,KAAA,CAAM,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAE/C,MAAA,OAAO,MAAM;AACZ,QAAA,KAAA,CAAM,mBAAA,CAAoB,QAAQ,UAAU,CAAA;AAC5C,QAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC9C,QAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC9C,QAAA,KAAA,CAAM,mBAAA,CAAoB,cAAc,gBAAgB,CAAA;AACxD,QAAA,KAAA,CAAM,mBAAA,CAAoB,WAAW,aAAa,CAAA;AAAA,MACnD,CAAA;AAAA,IACD,GAAG,CAAC,QAAA,EAAU,QAAQ,OAAA,EAAS,OAAA,EAAS,YAAY,CAAC,CAAA;AAGrD,IAAM,iBAAU,MAAM;AACrB,MAAA,IAAI,CAAC,gBAAA,IAAoB,CAAC,SAAA,IAAa,CAAC,eAAA,EAAiB;AAEzD,MAAA,kBAAA,CAAmB,OAAA,GAAU,WAAW,MAAM;AAC7C,QAAA,kBAAA,CAAmB,KAAK,CAAA;AAAA,MACzB,GAAG,aAAa,CAAA;AAEhB,MAAA,OAAO,MAAM;AACZ,QAAA,IAAI,mBAAmB,OAAA,EAAS;AAC/B,UAAA,YAAA,CAAa,mBAAmB,OAAO,CAAA;AAAA,QACxC;AAAA,MACD,CAAA;AAAA,IACD,GAAG,CAAC,gBAAA,EAAkB,SAAA,EAAW,eAAA,EAAiB,aAAa,CAAC,CAAA;AAGhE,IAAM,iBAAU,MAAM;AACrB,MAAA,MAAM,yBAAyB,MAAM;AACpC,QAAA,eAAA,CAAgB,CAAC,CAAC,QAAA,CAAS,iBAAiB,CAAA;AAAA,MAC7C,CAAA;AAEA,MAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,sBAAsB,CAAA;AACpE,MAAA,QAAA,CAAS,gBAAA;AAAA,QACR,wBAAA;AAAA,QACA;AAAA,OACD;AACA,MAAA,OAAO,MAAM;AACZ,QAAA,QAAA,CAAS,mBAAA;AAAA,UACR,kBAAA;AAAA,UACA;AAAA,SACD;AACA,QAAA,QAAA,CAAS,mBAAA;AAAA,UACR,wBAAA;AAAA,UACA;AAAA,SACD;AAAA,MACD,CAAA;AAAA,IACD,CAAA,EAAG,EAAE,CAAA;AAGL,IAAA,MAAM,UAAA,GAAmB,mBAAY,MAAM;AAC1C,MAAA,MAAM,QAAQ,gBAAA,CAAiB,OAAA;AAC/B,MAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,MAAA,IAAI,MAAM,MAAA,EAAQ;AACjB,QAAA,KAAA,CAAM,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MAC5B,CAAA,MAAO;AACN,QAAA,KAAA,CAAM,KAAA,EAAM;AAAA,MACb;AAAA,IACD,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,cAAA,GAAuB,mBAAY,MAAM;AAC9C,MAAA,kBAAA,CAAmB,CAAC,IAAA,KAAS,CAAC,IAAI,CAAA;AAAA,IACnC,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,gBAAA,GAAyB,mBAAY,MAAM;AAChD,MAAA,IAAI,CAAC,SAAS,iBAAA,EAAmB;AAChC,QAAA,YAAA,CAAa,SAAS,iBAAA,EAAkB;AAAA,MACzC,CAAA,MAAO;AACN,QAAA,QAAA,CAAS,cAAA,EAAe;AAAA,MACzB;AAAA,IACD,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,YAAA,GAAqB,mBAAY,MAAM;AAC5C,MAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,MAAA,IAAI,mBAAmB,OAAA,EAAS;AAC/B,QAAA,YAAA,CAAa,mBAAmB,OAAO,CAAA;AAAA,MACxC;AAAA,IACD,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,gBAAA,GAAyB,mBAAY,MAAM;AAChD,MAAA,IAAI,oBAAoB,SAAA,EAAW;AAClC,QAAA,kBAAA,CAAmB,KAAK,CAAA;AAAA,MACzB;AAAA,IACD,CAAA,EAAG,CAAC,gBAAA,EAAkB,SAAS,CAAC,CAAA;AAGhC,IAAA,MAAM,EAAE,cAAA,EAAgB,aAAA,EAAc,GAAI,gBAAA,CAAiB;AAAA,MAC1D,QAAA,EAAU,gBAAA;AAAA,MACV,YAAA,EAAc,UAAA;AAAA,MACd,kBAAA,EAAoB,gBAAA;AAAA,MACpB,gBAAA,EAAkB,cAAc,cAAA,GAAiB,MAAA;AAAA,MACjD,cAAA,EAAgB;AAAA,KAChB,CAAA;AAED,IAAA;AAAA;AAAA,sBAEC,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACA,GAAA,EAAK,YAAA;AAAA,UACL,SAAA,EAAW,GAAG,mBAAA,CAAoB,EAAE,aAAa,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,UACtE,WAAA,EAAa,YAAA;AAAA,UACb,YAAA,EAAc,gBAAA;AAAA,UACb,GAAG,aAAA;AAAA,UACH,GAAG,KAAA;AAAA,UAEH,QAAA,EAAA;AAAA,YAAA,QAAA,mBACA,IAAA;AAAA,cAAC,eAAA;AAAA,cAAA;AAAA,gBACA,UAAA,EAAY,IAAA;AAAA,gBACZ,WAAW,uBAAA,EAAwB;AAAA,gBAGnC,QAAA,EAAA;AAAA,kCAAAC,GAAAA;AAAA,oBAAC,OAAA;AAAA,oBAAA;AAAA,sBACA,GAAA,EAAK,gBAAA;AAAA,sBACL,IAAA,EAAK,OAAA;AAAA,sBACL,MAAA;AAAA,sBACA,IAAA;AAAA,sBACA,KAAA;AAAA,sBACA,WAAA,EAAW,IAAA;AAAA,sBACX,WAAA,EAAY,WAAA;AAAA,sBACZ,SAAA,EAAU;AAAA;AAAA,mBACX;AAAA,kCAGAA,GAAAA,CAAC,qBAAA,EAAA,EAAsB,IAAA,EAAK,iBAAA,EAAkB,YAAU,IAAA,EAAC,CAAA;AAAA,kCAGzDA,GAAAA;AAAA,oBAAC,KAAA;AAAA,oBAAA;AAAA,sBACA,OAAA,EAAS,UAAA;AAAA,sBACT,SAAA,EAAU,uCAAA;AAAA,sBACV,aAAA,EAAY;AAAA;AAAA,mBACb;AAAA,kCAGA,IAAA;AAAA,oBAAC,eAAA;AAAA,oBAAA;AAAA,sBACA,SAAA,EAAW,kBAAA,CAAmB,EAAE,OAAA,EAAS,iBAAiB,CAAA;AAAA,sBAC1D,OAAA,EAAS,CAAC,CAAA,KAAwB,CAAA,CAAE,eAAA,EAAgB;AAAA,sBACpD,KAAA,EAAO;AAAA,wBACN,QAAA,EAAU,UAAA;AAAA,wBACV,IAAA,EAAM,MAAA;AAAA,wBACN,KAAA,EAAO,MAAA;AAAA,wBACP,MAAA,EAAQ,MAAA;AAAA,wBACR,GAAA,EAAK,MAAA;AAAA,wBACL,OAAA,EAAS,UAAA;AAAA,wBACT,YAAA,EAAc,QAAA;AAAA,wBACd,cAAA,EAAgB,YAAA;AAAA,wBAChB,oBAAA,EAAsB,YAAA;AAAA,wBACtB,MAAA,EAAQ;AAAA,uBACT;AAAA,sBAEA,QAAA,EAAA;AAAA,wCAAAA,GAAAA,CAAC,eAAA,EAAA,EAAgB,KAAA,EAAO,iBAAA,EAAmB,CAAA;AAAA,wCAC3CA,GAAAA,CAAC,eAAA,EAAA,EAAgB,KAAA,EAAO,iBAAA,EAAmB,CAAA;AAAA,wCAC3CA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,KAAA,EAAO,iBAAA,EAAmB,CAAA;AAAA,wCAC5CA,GAAAA;AAAA,0BAAC,gBAAA;AAAA,0BAAA;AAAA,4BACA,KAAA,EAAO,iBAAA;AAAA,4BACP,YAAA,EAAY,IAAA;AAAA,4BACZ,QAAA,EAAQ;AAAA;AAAA,yBACT;AAAA,wCACAA,GAAAA,CAAC,cAAA,EAAA,EAAe,KAAA,EAAO,eAAA,EAAiB,CAAA;AAAA,wBAGvC,+BACAA,GAAAA;AAAA,0BAAC,QAAA;AAAA,0BAAA;AAAA,4BACA,IAAA,EAAK,QAAA;AAAA,4BACL,WAAW,qBAAA,EAAsB;AAAA,4BACjC,OAAA,EAAS,CAAC,CAAA,KAAM;AACf,8BAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,8BAAA,cAAA,EAAe;AAAA,4BAChB,CAAA;AAAA,4BACA,YAAA,EACC,kBAAkB,kBAAA,GAAqB,iBAAA;AAAA,4BAExC,cAAA,EAAc,eAAA;AAAA,4BAEd,QAAA,kBAAAA,GAAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,eAAA,EAAiB;AAAA;AAAA,yBACzC;AAAA,wCAIDA,GAAAA;AAAA,0BAAC,QAAA;AAAA,0BAAA;AAAA,4BACA,IAAA,EAAK,QAAA;AAAA,4BACL,WAAW,qBAAA,EAAsB;AAAA,4BACjC,OAAA,EAAS,CAAC,CAAA,KAAM;AACf,8BAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,8BAAA,gBAAA,EAAiB;AAAA,4BAClB,CAAA;AAAA,4BACA,YAAA,EACC,eAAe,iBAAA,GAAoB,kBAAA;AAAA,4BAGpC,QAAA,kBAAAA,GAAAA,CAAC,cAAA,EAAA,EAAe,YAAA,EAA4B;AAAA;AAAA;AAC7C;AAAA;AAAA;AACD;AAAA;AAAA,aACD;AAAA;AAAA,8BAGAA,GAAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBACA,GAAA,EAAK,gBAAA;AAAA,kBACL,MAAA;AAAA,kBACA,IAAA;AAAA,kBACA,KAAA;AAAA,kBACA,WAAA,EAAW,IAAA;AAAA,kBACX,WAAA,EAAY,WAAA;AAAA,kBACZ,SAAA,EAAU,8BAAA;AAAA,kBACV,OAAA,EAAS;AAAA;AAAA;AACV,aAAA;AAAA,YAIA,SAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,sBAAA,EAAuB,EACtC,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6EAAA,EAA8E,CAAA,EAC9F,CAAA;AAAA,YAIA,QAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,wBAAuB,EACtC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACd,QAAA,EAAA;AAAA,8BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,sBAAA,EAAoB,CAAA;AAAA,8BACzDA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uCAAA,EACX,mBAAS,OAAA,EACX;AAAA,aAAA,EACD,CAAA,EACD,CAAA;AAAA,YAIA,mBAAmB,SAAA,oBAAaA,GAAAA,CAAC,cAAA,EAAA,EAAe,KAAK,SAAA,EAAW;AAAA;AAAA;AAAA;AAClE;AAAA,EAEF;AACD;AACA,WAAA,CAAY,WAAA,GAAc,aAAA;AAM1B,IAAM,YAAA,GAAe,CAAC,EAAE,OAAA,uBACvBA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACA,SAAA,EAAU,WAAA;AAAA,IACV,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,cAAA;AAAA,IACL,aAAA,EAAY,MAAA;AAAA,IAEX,QAAA,EAAA,OAAA;AAAA;AAAA,sBAEAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6RAAA,EAA8R;AAAA;AAAA;AAAA,sBAGtS,IAAA,CAAA,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6RAAA,EAA8R,CAAA;AAAA,wBACtSA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACA,EAAA,EAAG,GAAA;AAAA,YACH,EAAA,EAAG,IAAA;AAAA,YACH,EAAA,EAAG,IAAA;AAAA,YACH,EAAA,EAAG,GAAA;AAAA,YACH,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY;AAAA;AAAA;AACb,OAAA,EACD;AAAA;AAAA;AAEF,CAAA;AAGD,IAAM,cAAA,GAAiB,CAAC,EAAE,YAAA,uBACzBA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACA,SAAA,EAAU,WAAA;AAAA,IACV,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAY,MAAA;AAAA,IAEX,QAAA,EAAA,YAAA;AAAA;AAAA,sBAEA,IAAA,CAAA,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,kBAAA,EAAmB,CAAA;AAAA,wBACpCA,GAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,kBAAA,EAAmB,CAAA;AAAA,wBACpCA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,wBACrCA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,OAAA,EACtC;AAAA;AAAA;AAAA,sBAGA,IAAA,CAAA,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,gBAAA,EAAiB,CAAA;AAAA,wBAClCA,GAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,gBAAA,EAAiB,CAAA;AAAA,wBAClCA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA;AAAA,wBACrCA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,OAAA,EACtC;AAAA;AAAA;AAEF,CAAA","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { cnBase as twMerge } from \"tailwind-variants\";\n\nexport { twMerge };\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport type { CaptionCue } from \"@/hooks/use-captions\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Caption overlay variants using semantic tokens.\n */\nconst captionOverlayVariants = tv({\n\tbase: [\n\t\t// Positioning - absolute at bottom of video container\n\t\t\"pointer-events-none\",\n\t\t\"absolute right-0 left-0\",\n\t\t\"z-10\",\n\t\t\"flex justify-center\",\n\t\t\"px-4\",\n\t],\n\tvariants: {\n\t\tposition: {\n\t\t\tbottom: \"bottom-64\",\n\t\t\t\"bottom-sm\": \"bottom-24\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tposition: \"bottom-sm\",\n\t},\n});\n\n/**\n * Caption text box variants.\n */\nconst captionTextVariants = tv({\n\tbase: [\n\t\t\"flex items-center justify-center\",\n\t\t\"w-fit max-w-[80%]\",\n\t\t\"gap-10\",\n\t\t\"px-12 py-6\",\n\t\t\"text-center\",\n\t\t\"font-normal leading-[1.4]\",\n\t\t\"rounded-6\",\n\t\t\"bg-video-player-caption-bg text-video-player-caption-text\",\n\t],\n\tvariants: {\n\t\tsize: {\n\t\t\tsm: \"text-14\",\n\t\t\tmd: \"[font-size:clamp(16px,2vw,24px)]\",\n\t\t\tlg: \"text-24\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tsize: \"md\",\n\t},\n});\n\nexport interface CaptionOverlayProps\n\textends React.HTMLAttributes<HTMLOutputElement>,\n\t\tVariantProps<typeof captionOverlayVariants>,\n\t\tVariantProps<typeof captionTextVariants> {\n\t/** Caption cue to display */\n\tcue?: CaptionCue | null;\n\t/** Caption text to display (alternative to cue) */\n\ttext?: string;\n}\n\n/**\n * CaptionOverlay component.\n *\n * Displays caption text overlaid on video content.\n * Styled to match the DGA video player implementation.\n *\n * @example\n * ```tsx\n * <CaptionOverlay cue={activeCue} />\n *\n * // Or with plain text\n * <CaptionOverlay text=\"Hello, world!\" />\n * ```\n */\nconst CaptionOverlay = React.forwardRef<HTMLOutputElement, CaptionOverlayProps>(\n\t({ className, cue, text, position, size, ...props }, ref) => {\n\t\t// Use cue text or fallback to text prop\n\t\tconst displayText = cue?.text ?? text;\n\n\t\t// Don't render anything if no caption text\n\t\tif (!displayText) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<output\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(captionOverlayVariants({ position }), className)}\n\t\t\t\taria-live=\"polite\"\n\t\t\t\taria-label=\"Video caption\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<span className={captionTextVariants({ size })}>{displayText}</span>\n\t\t\t</output>\n\t\t);\n\t},\n);\n\nCaptionOverlay.displayName = \"CaptionOverlay\";\n\nexport { CaptionOverlay, captionOverlayVariants, captionTextVariants };\n","\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * Represents a single caption cue parsed from VTT.\n */\nexport interface CaptionCue {\n\t/** Unique identifier for the cue */\n\tid: string;\n\t/** Start time in seconds */\n\tstartTime: number;\n\t/** End time in seconds */\n\tendTime: number;\n\t/** Caption text content */\n\ttext: string;\n}\n\n/**\n * Parse VTT timestamp to seconds.\n * Handles formats: HH:MM:SS.mmm or MM:SS.mmm\n */\nfunction parseVttTimestamp(timestamp: string): number {\n\tconst parts = timestamp.trim().split(\":\");\n\tlet hours = 0;\n\tlet minutes = 0;\n\tlet seconds = 0;\n\n\tif (parts.length === 3) {\n\t\thours = Number.parseInt(parts[0], 10);\n\t\tminutes = Number.parseInt(parts[1], 10);\n\t\tseconds = Number.parseFloat(parts[2]);\n\t} else if (parts.length === 2) {\n\t\tminutes = Number.parseInt(parts[0], 10);\n\t\tseconds = Number.parseFloat(parts[1]);\n\t}\n\n\treturn hours * 3600 + minutes * 60 + seconds;\n}\n\n/**\n * Parse VTT content string into an array of caption cues.\n */\nfunction parseVtt(vttContent: string): CaptionCue[] {\n\tconst cues: CaptionCue[] = [];\n\tconst lines = vttContent.trim().split(\"\\n\");\n\n\tlet i = 0;\n\n\t// Skip WEBVTT header and any metadata\n\twhile (i < lines.length && !lines[i].includes(\"-->\")) {\n\t\ti++;\n\t}\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i].trim();\n\n\t\t// Look for timestamp line (contains -->)\n\t\tif (line.includes(\"-->\")) {\n\t\t\tconst [startStr, endStr] = line.split(\"-->\").map((s) => s.trim());\n\n\t\t\t// Handle optional cue settings after timestamp\n\t\t\tconst endParts = endStr.split(\" \");\n\t\t\tconst endTime = parseVttTimestamp(endParts[0]);\n\t\t\tconst startTime = parseVttTimestamp(startStr);\n\n\t\t\t// Collect text lines until empty line or next timestamp\n\t\t\tconst textLines: string[] = [];\n\t\t\ti++;\n\t\t\twhile (\n\t\t\t\ti < lines.length &&\n\t\t\t\tlines[i].trim() !== \"\" &&\n\t\t\t\t!lines[i].includes(\"-->\")\n\t\t\t) {\n\t\t\t\t// Skip cue identifier lines (numbers only)\n\t\t\t\tif (!/^\\d+$/.test(lines[i].trim())) {\n\t\t\t\t\ttextLines.push(lines[i].trim());\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\tif (textLines.length > 0) {\n\t\t\t\tcues.push({\n\t\t\t\t\tid: `cue-${cues.length}`,\n\t\t\t\t\tstartTime,\n\t\t\t\t\tendTime,\n\t\t\t\t\ttext: textLines.join(\"\\n\"),\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\n\treturn cues;\n}\n\n/**\n * Strip VTT formatting tags from text.\n * Removes <v>, <c>, <i>, <b>, <u>, etc.\n */\nfunction stripVttTags(text: string): string {\n\treturn text\n\t\t.replace(/<\\/?[^>]+(>|$)/g, \"\") // Remove HTML-like tags\n\t\t.replace(/&nbsp;/g, \" \")\n\t\t.replace(/&amp;/g, \"&\")\n\t\t.replace(/&lt;/g, \"<\")\n\t\t.replace(/&gt;/g, \">\")\n\t\t.trim();\n}\n\ninterface UseCaptionsOptions {\n\t/** VTT file URL to fetch */\n\tsrc?: string;\n\t/** Pre-loaded VTT content string */\n\tcontent?: string;\n\t/** Strip VTT formatting tags from caption text */\n\tstripTags?: boolean;\n\t/** Current playback time in seconds (alternative to setCurrentTime) */\n\tcurrentTime?: number;\n}\n\ninterface UseCaptionsReturn {\n\t/** All parsed caption cues */\n\tcues: CaptionCue[];\n\t/** Currently active cue based on current time */\n\tactiveCue: CaptionCue | null;\n\t/** Update the current playback time to get active cue */\n\tsetCurrentTime: (time: number) => void;\n\t/** Loading state */\n\tisLoading: boolean;\n\t/** Error state */\n\terror: Error | null;\n}\n\n/**\n * Hook for parsing VTT captions and tracking the active cue.\n *\n * @param options - Caption source options\n * @returns Parsed cues, active cue, and state\n *\n * @example\n * ```tsx\n * function VideoPlayer() {\n * const videoRef = React.useRef<HTMLVideoElement>(null);\n * const { activeCue, setCurrentTime } = useCaptions({\n * src: '/captions.vtt',\n * });\n *\n * // Sync with video time\n * React.useEffect(() => {\n * const video = videoRef.current;\n * if (!video) return;\n *\n * const handleTimeUpdate = () => setCurrentTime(video.currentTime);\n * video.addEventListener('timeupdate', handleTimeUpdate);\n * return () => video.removeEventListener('timeupdate', handleTimeUpdate);\n * }, [setCurrentTime]);\n *\n * return (\n * <div>\n * <video ref={videoRef} src=\"/video.mp4\" />\n * {activeCue && <div className=\"caption\">{activeCue.text}</div>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCaptions(\n\toptions: UseCaptionsOptions = {},\n): UseCaptionsReturn {\n\tconst { src, content, stripTags = true, currentTime: externalTime } = options;\n\n\tconst [cues, setCues] = React.useState<CaptionCue[]>([]);\n\tconst [internalTime, setInternalTime] = React.useState(0);\n\tconst [isLoading, setIsLoading] = React.useState(false);\n\tconst [error, setError] = React.useState<Error | null>(null);\n\n\t// Use external time if provided, otherwise use internal state\n\tconst currentTime = externalTime ?? internalTime;\n\n\t// Parse content or fetch from URL\n\tReact.useEffect(() => {\n\t\tif (content) {\n\t\t\t// Use provided content directly\n\t\t\tconst parsed = parseVtt(content);\n\t\t\tsetCues(\n\t\t\t\tstripTags\n\t\t\t\t\t? parsed.map((cue) => ({ ...cue, text: stripVttTags(cue.text) }))\n\t\t\t\t\t: parsed,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!src) {\n\t\t\tsetCues([]);\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\n\t\tfetch(src)\n\t\t\t.then((response) => {\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to fetch captions: ${response.status}`);\n\t\t\t\t}\n\t\t\t\treturn response.text();\n\t\t\t})\n\t\t\t.then((vttContent) => {\n\t\t\t\tconst parsed = parseVtt(vttContent);\n\t\t\t\tsetCues(\n\t\t\t\t\tstripTags\n\t\t\t\t\t\t? parsed.map((cue) => ({ ...cue, text: stripVttTags(cue.text) }))\n\t\t\t\t\t\t: parsed,\n\t\t\t\t);\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tsetError(err instanceof Error ? err : new Error(String(err)));\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tsetIsLoading(false);\n\t\t\t});\n\t}, [src, content, stripTags]);\n\n\t// Find active cue for current time\n\tconst activeCue = React.useMemo(() => {\n\t\treturn (\n\t\t\tcues.find(\n\t\t\t\t(cue) => currentTime >= cue.startTime && currentTime <= cue.endTime,\n\t\t\t) ?? null\n\t\t);\n\t}, [cues, currentTime]);\n\n\t// Memoize setCurrentTime to avoid unnecessary re-renders\n\tconst handleSetCurrentTime = React.useCallback((time: number) => {\n\t\tsetInternalTime(time);\n\t}, []);\n\n\treturn {\n\t\tcues,\n\t\tactiveCue,\n\t\tsetCurrentTime: handleSetCurrentTime,\n\t\tisLoading,\n\t\terror,\n\t};\n}\n","import * as React from \"react\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface UseVideoKeyboardOptions {\n\t/** Ref to the video element */\n\tvideoRef: React.RefObject<HTMLVideoElement | null>;\n\t/** Whether keyboard handling is enabled (default: true) */\n\tenabled?: boolean;\n\t/** Seek amount in seconds for arrow keys (default: 5) */\n\tseekAmount?: number;\n\t/** Volume change amount for arrow keys (default: 0.1) */\n\tvolumeStep?: number;\n\t/** Callback when play/pause is toggled */\n\tonTogglePlay?: () => void;\n\t/** Callback when fullscreen is toggled */\n\tonToggleFullscreen?: () => void;\n\t/** Callback when captions are toggled */\n\tonToggleCaptions?: () => void;\n\t/** Callback when controls should be shown */\n\tonShowControls?: () => void;\n}\n\nexport interface UseVideoKeyboardReturn {\n\t/** Key down handler to attach to container element */\n\thandleKeyDown: (e: React.KeyboardEvent) => void;\n\t/** Props to spread on the container element */\n\tcontainerProps: {\n\t\tonKeyDown: (e: React.KeyboardEvent) => void;\n\t\ttabIndex: number;\n\t\trole: string;\n\t\t\"aria-label\": string;\n\t};\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook for handling keyboard shortcuts in a video player.\n *\n * Supported shortcuts:\n * - Space: Play/pause\n * - Left Arrow: Seek backward\n * - Right Arrow: Seek forward\n * - Up Arrow: Volume up\n * - Down Arrow: Volume down\n * - M: Toggle mute\n * - F: Toggle fullscreen\n * - C: Toggle captions\n *\n * @example\n * ```tsx\n * const { containerProps } = useVideoKeyboard({\n * videoRef,\n * onTogglePlay: () => video.paused ? video.play() : video.pause(),\n * onToggleFullscreen: () => toggleFullscreen(),\n * onShowControls: () => setControlsVisible(true),\n * });\n *\n * return <div {...containerProps}>...</div>;\n * ```\n */\nexport function useVideoKeyboard({\n\tvideoRef,\n\tenabled = true,\n\tseekAmount = 5,\n\tvolumeStep = 0.1,\n\tonTogglePlay,\n\tonToggleFullscreen,\n\tonToggleCaptions,\n\tonShowControls,\n}: UseVideoKeyboardOptions): UseVideoKeyboardReturn {\n\tconst handleKeyDown = React.useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (!enabled) return;\n\n\t\t\tconst video = videoRef.current;\n\t\t\tif (!video) return;\n\n\t\t\t// Don't handle if focus is on interactive elements\n\t\t\tconst target = e.target as HTMLElement;\n\t\t\tif (\n\t\t\t\ttarget.tagName === \"BUTTON\" ||\n\t\t\t\ttarget.tagName === \"INPUT\" ||\n\t\t\t\ttarget.tagName === \"TEXTAREA\" ||\n\t\t\t\ttarget.closest(\"button\") ||\n\t\t\t\ttarget.closest(\"input\") ||\n\t\t\t\ttarget.closest(\"[role='slider']\")\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet handled = false;\n\n\t\t\tswitch (e.key) {\n\t\t\t\t// Play/Pause\n\t\t\t\tcase \" \":\n\t\t\t\tcase \"Spacebar\":\n\t\t\t\tcase \"k\": // YouTube-style shortcut\n\t\t\t\t\tif (onTogglePlay) {\n\t\t\t\t\t\tonTogglePlay();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (video.paused) {\n\t\t\t\t\t\t\tvideo.play().catch(() => {});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvideo.pause();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Seek backward\n\t\t\t\tcase \"ArrowLeft\":\n\t\t\t\tcase \"j\": // YouTube-style shortcut\n\t\t\t\t\tvideo.currentTime = Math.max(0, video.currentTime - seekAmount);\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Seek forward\n\t\t\t\tcase \"ArrowRight\":\n\t\t\t\tcase \"l\": // YouTube-style shortcut\n\t\t\t\t\tvideo.currentTime = Math.min(\n\t\t\t\t\t\tvideo.duration || 0,\n\t\t\t\t\t\tvideo.currentTime + seekAmount,\n\t\t\t\t\t);\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Volume up\n\t\t\t\tcase \"ArrowUp\":\n\t\t\t\t\tvideo.volume = Math.min(1, video.volume + volumeStep);\n\t\t\t\t\tvideo.muted = false;\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Volume down\n\t\t\t\tcase \"ArrowDown\":\n\t\t\t\t\tvideo.volume = Math.max(0, video.volume - volumeStep);\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Toggle mute\n\t\t\t\tcase \"m\":\n\t\t\t\tcase \"M\":\n\t\t\t\t\tvideo.muted = !video.muted;\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Toggle fullscreen\n\t\t\t\tcase \"f\":\n\t\t\t\tcase \"F\":\n\t\t\t\t\tonToggleFullscreen?.();\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Toggle captions\n\t\t\t\tcase \"c\":\n\t\t\t\tcase \"C\":\n\t\t\t\t\tonToggleCaptions?.();\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Jump to start\n\t\t\t\tcase \"Home\":\n\t\t\t\t\tvideo.currentTime = 0;\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Jump to end\n\t\t\t\tcase \"End\":\n\t\t\t\t\tvideo.currentTime = video.duration || 0;\n\t\t\t\t\thandled = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Number keys for percentage seeking (0-9)\n\t\t\t\tcase \"0\":\n\t\t\t\tcase \"1\":\n\t\t\t\tcase \"2\":\n\t\t\t\tcase \"3\":\n\t\t\t\tcase \"4\":\n\t\t\t\tcase \"5\":\n\t\t\t\tcase \"6\":\n\t\t\t\tcase \"7\":\n\t\t\t\tcase \"8\":\n\t\t\t\tcase \"9\":\n\t\t\t\t\tif (video.duration) {\n\t\t\t\t\t\tconst percent = parseInt(e.key, 10) / 10;\n\t\t\t\t\t\tvideo.currentTime = video.duration * percent;\n\t\t\t\t\t\thandled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (handled) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tonShowControls?.();\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tenabled,\n\t\t\tvideoRef,\n\t\t\tseekAmount,\n\t\t\tvolumeStep,\n\t\t\tonTogglePlay,\n\t\t\tonToggleFullscreen,\n\t\t\tonToggleCaptions,\n\t\t\tonShowControls,\n\t\t],\n\t);\n\n\tconst containerProps = React.useMemo(\n\t\t() => ({\n\t\t\tonKeyDown: handleKeyDown,\n\t\t\ttabIndex: 0,\n\t\t\trole: \"application\" as const,\n\t\t\t\"aria-label\": \"Video player, press space to play or pause\",\n\t\t}),\n\t\t[handleKeyDown],\n\t);\n\n\treturn {\n\t\thandleKeyDown,\n\t\tcontainerProps,\n\t};\n}\n","\"use client\";\n\nimport {\n\tMediaControlBar,\n\tMediaController,\n\tMediaLoadingIndicator,\n\tMediaMuteButton,\n\tMediaPlayButton,\n\tMediaTimeDisplay,\n\tMediaTimeRange,\n\tMediaVolumeRange,\n} from \"media-chrome/react\";\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { useCaptions } from \"@/hooks/use-captions\";\nimport { useVideoKeyboard } from \"@/hooks/use-video-keyboard\";\nimport { cn } from \"@/lib/utils\";\nimport { CaptionOverlay } from \"./caption-overlay\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Cloudflare Stream configuration */\ninterface CloudflareConfig {\n\t/** Cloudflare Stream video ID */\n\tvideoId: string;\n\t/** Cloudflare customer code/subdomain */\n\tcustomerCode: string;\n}\n\n// ============================================================================\n// Variant Definitions\n// ============================================================================\n\n/**\n * Video player container variants.\n */\nconst videoPlayerVariants = tv({\n\tbase: [\n\t\t\"relative\",\n\t\t\"bg-black\",\n\t\t\"overflow-hidden\",\n\t\t// Focus styling for keyboard navigation\n\t\t\"focus:outline-none\",\n\t\t\"focus-visible:ring-2\",\n\t\t\"focus-visible:ring-white/50\",\n\t],\n\tvariants: {\n\t\taspectRatio: {\n\t\t\t\"16/9\": \"aspect-video\",\n\t\t\t\"4/3\": \"aspect-[4/3]\",\n\t\t\t\"1/1\": \"aspect-square\",\n\t\t\t\"9/16\": \"aspect-[9/16]\",\n\t\t\tauto: \"\",\n\t\t},\n\t\trounded: {\n\t\t\tnone: \"\",\n\t\t\tsm: \"rounded-4\",\n\t\t\tmd: \"rounded-8\",\n\t\t\tlg: \"rounded-12\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\taspectRatio: \"16/9\",\n\t\trounded: \"none\",\n\t},\n});\n\n/**\n * Media controller container styles.\n * Uses CSS custom properties to configure media-chrome components.\n * Styled to match DGA video player design with ghost-style buttons.\n */\nconst mediaControllerVariants = tv({\n\tbase: [\n\t\t\"absolute inset-0\",\n\t\t\"w-full h-full\",\n\t\t// Button styling - transparent base, hover shows background\n\t\t\"[--media-control-background:transparent]\",\n\t\t\"[--media-control-hover-background:var(--color-video-player-button-bg-hover)]\",\n\t\t\"[--media-control-padding:8px]\",\n\t\t\"[--media-control-height:36px]\",\n\t\t\"[--media-button-icon-width:20px]\",\n\t\t\"[--media-button-icon-height:20px]\",\n\t\t// Progress bar / range styling\n\t\t\"[--media-range-track-background:var(--color-video-player-progress-bg)]\",\n\t\t\"[--media-range-bar-color:var(--color-video-player-progress-fill)]\",\n\t\t\"[--media-range-track-height:4px]\",\n\t\t\"[--media-range-track-border-radius:2px]\",\n\t\t\"[--media-range-thumb-background:var(--color-video-player-progress-fill)]\",\n\t\t\"[--media-range-thumb-height:12px]\",\n\t\t\"[--media-range-thumb-width:12px]\",\n\t\t\"[--media-range-thumb-border-radius:50%]\",\n\t\t// Text/icon colors\n\t\t\"[--media-icon-color:var(--color-video-player-controls-text)]\",\n\t\t\"[--media-primary-color:var(--color-video-player-controls-text)]\",\n\t\t\"[--media-secondary-color:transparent]\",\n\t\t\"[--media-text-color:var(--color-video-player-controls-text)]\",\n\t\t\"[--media-font-size:14px]\",\n\t\t// Time display styling\n\t\t\"[--media-time-display-background:transparent]\",\n\t],\n});\n\n/**\n * Media-chrome control button styles.\n * Applied to media-play-button, media-mute-button, etc.\n * Transparent by default, shows background on hover (ghost style).\n */\nconst mediaButtonStyles: React.CSSProperties = {\n\tpadding: \"8px\",\n\tborderRadius: \"50%\",\n\t// Tooltip styling - consistent across all buttons\n\t\"--media-tooltip-background\": \"var(--color-video-player-tooltip-bg)\",\n\t\"--media-tooltip-arrow-display\": \"none\",\n\t\"--media-tooltip-distance\": \"8px\",\n} as React.CSSProperties;\n\n/**\n * Time range styles matching DGA.\n */\nconst timeRangeStyles: React.CSSProperties = {\n\tflex: 1,\n\tbackground: \"transparent\",\n\t// Preview tooltip styling - consistent with button tooltips\n\t\"--media-box-arrow-display\": \"none\",\n\t\"--media-preview-box-margin\": \"0 0 8px 0\",\n\t\"--media-preview-time-margin\": \"0 0 8px 0\",\n\t\"--media-preview-time-background\": \"var(--color-video-player-tooltip-bg)\",\n} as React.CSSProperties;\n\n/**\n * Volume range styles.\n */\nconst volumeRangeStyles: React.CSSProperties = {\n\twidth: \"80px\",\n\tbackground: \"transparent\",\n\t// Tooltip styling - consistent with button tooltips\n\t\"--media-tooltip-background\": \"var(--color-video-player-tooltip-bg)\",\n\t\"--media-tooltip-arrow-display\": \"none\",\n\t\"--media-tooltip-distance\": \"8px\",\n} as React.CSSProperties;\n\n/**\n * Time display styles.\n */\nconst timeDisplayStyles: React.CSSProperties = {\n\tbackground: \"transparent\",\n\tfontFamily: \"monospace\",\n\tfontSize: \"14px\",\n\tcolor: \"white\",\n\twhiteSpace: \"nowrap\",\n};\n\n/**\n * Control bar variants.\n * Note: Positioning is handled via inline styles to override web component defaults.\n * Tailwind classes handle background color and visibility transitions.\n */\nconst controlBarVariants = tv({\n\tbase: [\n\t\t// Layout handled in inline styles, but we need flex\n\t\t\"flex items-center\",\n\t\t// Background using semantic token\n\t\t\"bg-video-player-controls-bg\",\n\t\t// Animation\n\t\t\"transition-all duration-300\",\n\t],\n\tvariants: {\n\t\tvisible: {\n\t\t\ttrue: \"opacity-100 translate-y-0\",\n\t\t\tfalse: \"opacity-0 translate-y-16 pointer-events-none\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tvisible: true,\n\t},\n});\n\n/**\n * Control button styles for custom buttons.\n * Transparent by default, shows background on hover (ghost style).\n */\nconst controlButtonVariants = tv({\n\tbase: [\n\t\t\"flex items-center justify-center\",\n\t\t\"p-8 rounded-full\",\n\t\t// Transparent by default, background on hover\n\t\t\"bg-transparent\",\n\t\t\"text-video-player-controls-text\",\n\t\t\"hover:bg-video-player-button-bg-hover\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-video-player-progress-bg\",\n\t\t\"transition-colors duration-150\",\n\t\t\"cursor-pointer\",\n\t],\n});\n\n/**\n * Loading overlay variants.\n */\nconst loadingOverlayVariants = tv({\n\tbase: [\n\t\t\"absolute inset-0\",\n\t\t\"flex items-center justify-center\",\n\t\t\"bg-black/50\",\n\t\t\"pointer-events-none\",\n\t\t\"z-10\",\n\t],\n});\n\n// ============================================================================\n// HLS Hook (internal)\n// ============================================================================\n\n/**\n * Internal hook for HLS.js initialization.\n * Handles both native HLS (Safari) and HLS.js (Chrome/Firefox).\n */\nfunction useHlsInternal(\n\tvideoRef: React.RefObject<HTMLVideoElement | null>,\n\tsrc: string | undefined,\n\tenabled: boolean,\n) {\n\tconst [isLoading, setIsLoading] = React.useState(true);\n\tconst [error, setError] = React.useState<Error | null>(null);\n\tconst hlsRef = React.useRef<unknown>(null);\n\n\tReact.useEffect(() => {\n\t\tif (!enabled || !src || !videoRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst video = videoRef.current;\n\t\tconst isHlsSource = src.includes(\".m3u8\");\n\n\t\t// For non-HLS sources, just set the src directly\n\t\tif (!isHlsSource) {\n\t\t\tvideo.src = src;\n\t\t\tsetIsLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if native HLS is supported (Safari)\n\t\tif (video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n\t\t\tvideo.src = src;\n\t\t\tsetIsLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Try to use HLS.js for other browsers\n\t\tconst loadHls = async () => {\n\t\t\ttry {\n\t\t\t\t// Dynamic import of HLS.js (peer dependency)\n\t\t\t\tconst HlsModule = await import(\"hls.js\");\n\t\t\t\tconst Hls = HlsModule.default;\n\n\t\t\t\tif (!Hls.isSupported()) {\n\t\t\t\t\t// Fallback: try setting src directly\n\t\t\t\t\tvideo.src = src;\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst hls = new Hls({\n\t\t\t\t\tenableWorker: true,\n\t\t\t\t\tlowLatencyMode: false,\n\t\t\t\t});\n\n\t\t\t\thls.loadSource(src);\n\t\t\t\thls.attachMedia(video);\n\n\t\t\t\thls.on(Hls.Events.MANIFEST_PARSED, () => {\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t});\n\n\t\t\t\thls.on(\n\t\t\t\t\tHls.Events.ERROR,\n\t\t\t\t\t(_event: unknown, data: { fatal?: boolean; details?: string }) => {\n\t\t\t\t\t\tif (data.fatal) {\n\t\t\t\t\t\t\tsetError(new Error(`HLS error: ${data.details}`));\n\t\t\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\thlsRef.current = hls;\n\t\t\t} catch {\n\t\t\t\t// HLS.js not available, try direct source\n\t\t\t\tvideo.src = src;\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t};\n\n\t\tloadHls();\n\n\t\treturn () => {\n\t\t\tif (hlsRef.current) {\n\t\t\t\t(hlsRef.current as { destroy: () => void }).destroy();\n\t\t\t\thlsRef.current = null;\n\t\t\t}\n\t\t};\n\t}, [enabled, src, videoRef]);\n\n\treturn { isLoading, error };\n}\n\n// ============================================================================\n// VideoPlayer Component\n// ============================================================================\n\nexport interface VideoPlayerProps\n\textends Omit<\n\t\t\tReact.HTMLAttributes<HTMLDivElement>,\n\t\t\t\"children\" | \"onError\" | \"onPlay\" | \"onPause\" | \"onEnded\" | \"onTimeUpdate\"\n\t\t>,\n\t\tVariantProps<typeof videoPlayerVariants> {\n\t/** Video source URL (HLS .m3u8 or regular video file) */\n\tsrc?: string;\n\t/** Cloudflare Stream configuration (takes precedence over src) */\n\tcloudflare?: CloudflareConfig;\n\t/** Poster image URL */\n\tposter?: string;\n\t/** VTT captions URL */\n\tcaptionsSrc?: string;\n\t/** Whether to autoplay (default: false) */\n\tautoPlay?: boolean;\n\t/** Whether to loop the video (default: false) */\n\tloop?: boolean;\n\t/** Whether to mute initially (default: false) */\n\tmuted?: boolean;\n\t/** Whether to show controls (default: true) */\n\tcontrols?: boolean;\n\t/** Whether to auto-hide controls when not interacting (default: true) */\n\tautoHideControls?: boolean;\n\t/** Control auto-hide delay in ms (default: 3000) */\n\tautoHideDelay?: number;\n\t/** Whether captions are enabled by default (default: false) */\n\tcaptionsEnabled?: boolean;\n\t/** Callback when video starts playing */\n\tonPlay?: () => void;\n\t/** Callback when video pauses */\n\tonPause?: () => void;\n\t/** Callback when video ends */\n\tonEnded?: () => void;\n\t/** Callback on time update */\n\tonTimeUpdate?: (time: number) => void;\n\t/** Callback on error */\n\tonError?: (error: Error) => void;\n\t/** Ref to the video element */\n\tvideoRef?: React.RefObject<HTMLVideoElement | null>;\n}\n\n/**\n * VideoPlayer - Standalone video player component with media-chrome controls.\n *\n * Supports Cloudflare Stream (recommended) or direct video URLs with HLS support.\n * Works standalone or can be composed with Modal for fullscreen playback.\n *\n * @example\n * ```tsx\n * // With Cloudflare Stream (recommended)\n * <VideoPlayer\n * cloudflare={{ videoId: \"abc123\", customerCode: \"xyz789\" }}\n * poster=\"/thumbnail.jpg\"\n * captionsSrc=\"/captions.vtt\"\n * />\n *\n * // With direct URL\n * <VideoPlayer\n * src=\"https://example.com/video.mp4\"\n * poster=\"/thumbnail.jpg\"\n * />\n *\n * // With Modal for fullscreen\n * <Modal trigger={<Button>Watch Video</Button>}>\n * <VideoPlayer cloudflare={{ videoId: \"...\", customerCode: \"...\" }} />\n * </Modal>\n * ```\n */\nconst VideoPlayer = React.forwardRef<HTMLDivElement, VideoPlayerProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tsrc,\n\t\t\tcloudflare,\n\t\t\tposter,\n\t\t\tcaptionsSrc,\n\t\t\tautoPlay = false,\n\t\t\tloop = false,\n\t\t\tmuted = false,\n\t\t\tcontrols = true,\n\t\t\tautoHideControls = true,\n\t\t\tautoHideDelay = 3000,\n\t\t\tcaptionsEnabled: initialCaptionsEnabled = false,\n\t\t\taspectRatio,\n\t\t\trounded,\n\t\t\tonPlay,\n\t\t\tonPause,\n\t\t\tonEnded,\n\t\t\tonTimeUpdate,\n\t\t\tonError,\n\t\t\tvideoRef: externalVideoRef,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\t// Internal refs\n\t\tconst containerRef = React.useRef<HTMLDivElement>(null);\n\t\tconst internalVideoRef = React.useRef<HTMLVideoElement | null>(null);\n\t\tconst controlsTimeoutRef = React.useRef<ReturnType<\n\t\t\ttypeof setTimeout\n\t\t> | null>(null);\n\n\t\t// State\n\t\tconst [isPlaying, setIsPlaying] = React.useState(false);\n\t\tconst [currentTime, setCurrentTime] = React.useState(0);\n\t\tconst [controlsVisible, setControlsVisible] = React.useState(true);\n\t\tconst [captionsEnabled, setCaptionsEnabled] = React.useState(\n\t\t\tinitialCaptionsEnabled,\n\t\t);\n\t\tconst [isFullscreen, setIsFullscreen] = React.useState(false);\n\n\t\t// Compute video source URL\n\t\tconst videoSrc = React.useMemo(() => {\n\t\t\tif (cloudflare) {\n\t\t\t\treturn `https://customer-${cloudflare.customerCode}.cloudflarestream.com/${cloudflare.videoId}/manifest/video.m3u8`;\n\t\t\t}\n\t\t\treturn src;\n\t\t}, [cloudflare, src]);\n\n\t\t// HLS support\n\t\tconst { isLoading, error: hlsError } = useHlsInternal(\n\t\t\tinternalVideoRef,\n\t\t\tvideoSrc,\n\t\t\ttrue,\n\t\t);\n\n\t\t// Caption parsing\n\t\tconst { activeCue } = useCaptions({\n\t\t\tsrc: captionsSrc,\n\t\t\tcurrentTime,\n\t\t});\n\n\t\t// Merge refs\n\t\tReact.useEffect(() => {\n\t\t\tif (externalVideoRef) {\n\t\t\t\t(\n\t\t\t\t\texternalVideoRef as React.MutableRefObject<HTMLVideoElement | null>\n\t\t\t\t).current = internalVideoRef.current;\n\t\t\t}\n\t\t}, [externalVideoRef]);\n\n\t\t// Merge container ref\n\t\tReact.useImperativeHandle(\n\t\t\tref,\n\t\t\t() => containerRef.current as HTMLDivElement,\n\t\t);\n\n\t\t// Report errors\n\t\tReact.useEffect(() => {\n\t\t\tif (hlsError && onError) {\n\t\t\t\tonError(hlsError);\n\t\t\t}\n\t\t}, [hlsError, onError]);\n\n\t\t// Video event handlers\n\t\tReact.useEffect(() => {\n\t\t\tconst video = internalVideoRef.current;\n\t\t\tif (!video) return;\n\n\t\t\tconst handlePlay = () => {\n\t\t\t\tsetIsPlaying(true);\n\t\t\t\tonPlay?.();\n\t\t\t};\n\n\t\t\tconst handlePause = () => {\n\t\t\t\tsetIsPlaying(false);\n\t\t\t\tonPause?.();\n\t\t\t};\n\n\t\t\tconst handleEnded = () => {\n\t\t\t\tsetIsPlaying(false);\n\t\t\t\tonEnded?.();\n\t\t\t};\n\n\t\t\tconst handleTimeUpdate = () => {\n\t\t\t\tsetCurrentTime(video.currentTime);\n\t\t\t\tonTimeUpdate?.(video.currentTime);\n\t\t\t};\n\n\t\t\tconst handleCanPlay = () => {\n\t\t\t\tif (autoPlay) {\n\t\t\t\t\tvideo.play().catch(() => {\n\t\t\t\t\t\t// Autoplay may be blocked\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvideo.addEventListener(\"play\", handlePlay);\n\t\t\tvideo.addEventListener(\"pause\", handlePause);\n\t\t\tvideo.addEventListener(\"ended\", handleEnded);\n\t\t\tvideo.addEventListener(\"timeupdate\", handleTimeUpdate);\n\t\t\tvideo.addEventListener(\"canplay\", handleCanPlay);\n\n\t\t\treturn () => {\n\t\t\t\tvideo.removeEventListener(\"play\", handlePlay);\n\t\t\t\tvideo.removeEventListener(\"pause\", handlePause);\n\t\t\t\tvideo.removeEventListener(\"ended\", handleEnded);\n\t\t\t\tvideo.removeEventListener(\"timeupdate\", handleTimeUpdate);\n\t\t\t\tvideo.removeEventListener(\"canplay\", handleCanPlay);\n\t\t\t};\n\t\t}, [autoPlay, onPlay, onPause, onEnded, onTimeUpdate]);\n\n\t\t// Auto-hide controls\n\t\tReact.useEffect(() => {\n\t\t\tif (!autoHideControls || !isPlaying || !controlsVisible) return;\n\n\t\t\tcontrolsTimeoutRef.current = setTimeout(() => {\n\t\t\t\tsetControlsVisible(false);\n\t\t\t}, autoHideDelay);\n\n\t\t\treturn () => {\n\t\t\t\tif (controlsTimeoutRef.current) {\n\t\t\t\t\tclearTimeout(controlsTimeoutRef.current);\n\t\t\t\t}\n\t\t\t};\n\t\t}, [autoHideControls, isPlaying, controlsVisible, autoHideDelay]);\n\n\t\t// Track fullscreen state\n\t\tReact.useEffect(() => {\n\t\t\tconst handleFullscreenChange = () => {\n\t\t\t\tsetIsFullscreen(!!document.fullscreenElement);\n\t\t\t};\n\n\t\t\tdocument.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n\t\t\tdocument.addEventListener(\n\t\t\t\t\"webkitfullscreenchange\",\n\t\t\t\thandleFullscreenChange,\n\t\t\t);\n\t\t\treturn () => {\n\t\t\t\tdocument.removeEventListener(\n\t\t\t\t\t\"fullscreenchange\",\n\t\t\t\t\thandleFullscreenChange,\n\t\t\t\t);\n\t\t\t\tdocument.removeEventListener(\n\t\t\t\t\t\"webkitfullscreenchange\",\n\t\t\t\t\thandleFullscreenChange,\n\t\t\t\t);\n\t\t\t};\n\t\t}, []);\n\n\t\t// Actions\n\t\tconst togglePlay = React.useCallback(() => {\n\t\t\tconst video = internalVideoRef.current;\n\t\t\tif (!video) return;\n\n\t\t\tif (video.paused) {\n\t\t\t\tvideo.play().catch(() => {});\n\t\t\t} else {\n\t\t\t\tvideo.pause();\n\t\t\t}\n\t\t}, []);\n\n\t\tconst toggleCaptions = React.useCallback(() => {\n\t\t\tsetCaptionsEnabled((prev) => !prev);\n\t\t}, []);\n\n\t\tconst toggleFullscreen = React.useCallback(() => {\n\t\t\tif (!document.fullscreenElement) {\n\t\t\t\tcontainerRef.current?.requestFullscreen();\n\t\t\t} else {\n\t\t\t\tdocument.exitFullscreen();\n\t\t\t}\n\t\t}, []);\n\n\t\tconst showControls = React.useCallback(() => {\n\t\t\tsetControlsVisible(true);\n\t\t\tif (controlsTimeoutRef.current) {\n\t\t\t\tclearTimeout(controlsTimeoutRef.current);\n\t\t\t}\n\t\t}, []);\n\n\t\tconst handleMouseLeave = React.useCallback(() => {\n\t\t\tif (autoHideControls && isPlaying) {\n\t\t\t\tsetControlsVisible(false);\n\t\t\t}\n\t\t}, [autoHideControls, isPlaying]);\n\n\t\t// Keyboard shortcuts for video player\n\t\tconst { containerProps: keyboardProps } = useVideoKeyboard({\n\t\t\tvideoRef: internalVideoRef,\n\t\t\tonTogglePlay: togglePlay,\n\t\t\tonToggleFullscreen: toggleFullscreen,\n\t\t\tonToggleCaptions: captionsSrc ? toggleCaptions : undefined,\n\t\t\tonShowControls: showControls,\n\t\t});\n\n\t\treturn (\n\t\t\t// biome-ignore lint/a11y/noStaticElementInteractions: role is applied via keyboardProps spread\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={cn(videoPlayerVariants({ aspectRatio, rounded }), className)}\n\t\t\t\tonMouseMove={showControls}\n\t\t\t\tonMouseLeave={handleMouseLeave}\n\t\t\t\t{...keyboardProps}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{controls ? (\n\t\t\t\t\t<MediaController\n\t\t\t\t\t\tnoAutohide={true}\n\t\t\t\t\t\tclassName={mediaControllerVariants()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Video Element */}\n\t\t\t\t\t\t<video\n\t\t\t\t\t\t\tref={internalVideoRef}\n\t\t\t\t\t\t\tslot=\"media\"\n\t\t\t\t\t\t\tposter={poster}\n\t\t\t\t\t\t\tloop={loop}\n\t\t\t\t\t\t\tmuted={muted}\n\t\t\t\t\t\t\tplaysInline\n\t\t\t\t\t\t\tcrossOrigin=\"anonymous\"\n\t\t\t\t\t\t\tclassName=\"w-full h-full object-contain\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{/* Loading Indicator */}\n\t\t\t\t\t\t<MediaLoadingIndicator slot=\"centered-chrome\" noAutohide />\n\n\t\t\t\t\t\t{/* Click to play/pause overlay */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tonClick={togglePlay}\n\t\t\t\t\t\t\tclassName=\"absolute inset-0 cursor-pointer z-[1]\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{/* Control Bar */}\n\t\t\t\t\t\t<MediaControlBar\n\t\t\t\t\t\t\tclassName={controlBarVariants({ visible: controlsVisible })}\n\t\t\t\t\t\t\tonClick={(e: React.MouseEvent) => e.stopPropagation()}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\tleft: \"24px\",\n\t\t\t\t\t\t\t\tright: \"24px\",\n\t\t\t\t\t\t\t\tbottom: \"24px\",\n\t\t\t\t\t\t\t\tgap: \"12px\",\n\t\t\t\t\t\t\t\tpadding: \"8px 16px\",\n\t\t\t\t\t\t\t\tborderRadius: \"9999px\",\n\t\t\t\t\t\t\t\tbackdropFilter: \"blur(10px)\",\n\t\t\t\t\t\t\t\tWebkitBackdropFilter: \"blur(10px)\",\n\t\t\t\t\t\t\t\tzIndex: 2,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<MediaPlayButton style={mediaButtonStyles} />\n\t\t\t\t\t\t\t<MediaMuteButton style={mediaButtonStyles} />\n\t\t\t\t\t\t\t<MediaVolumeRange style={volumeRangeStyles} />\n\t\t\t\t\t\t\t<MediaTimeDisplay\n\t\t\t\t\t\t\t\tstyle={timeDisplayStyles}\n\t\t\t\t\t\t\t\tshowDuration\n\t\t\t\t\t\t\t\tnoToggle\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<MediaTimeRange style={timeRangeStyles} />\n\n\t\t\t\t\t\t\t{/* Captions Button */}\n\t\t\t\t\t\t\t{captionsSrc && (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName={controlButtonVariants()}\n\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\ttoggleCaptions();\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\t\tcaptionsEnabled ? \"Disable captions\" : \"Enable captions\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\taria-pressed={captionsEnabled}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<CaptionsIcon enabled={captionsEnabled} />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* Fullscreen Button */}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName={controlButtonVariants()}\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\ttoggleFullscreen();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\t\t\tisFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<FullscreenIcon isFullscreen={isFullscreen} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</MediaControlBar>\n\t\t\t\t\t</MediaController>\n\t\t\t\t) : (\n\t\t\t\t\t/* Video without controls */\n\t\t\t\t\t<video\n\t\t\t\t\t\tref={internalVideoRef}\n\t\t\t\t\t\tposter={poster}\n\t\t\t\t\t\tloop={loop}\n\t\t\t\t\t\tmuted={muted}\n\t\t\t\t\t\tplaysInline\n\t\t\t\t\t\tcrossOrigin=\"anonymous\"\n\t\t\t\t\t\tclassName=\"w-full h-full object-contain\"\n\t\t\t\t\t\tonClick={togglePlay}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t\t{/* Loading Overlay (when HLS is loading) */}\n\t\t\t\t{isLoading && (\n\t\t\t\t\t<div className={loadingOverlayVariants()}>\n\t\t\t\t\t\t<div className=\"w-40 h-40 border-3 border-white/30 border-t-white rounded-full animate-spin\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Error Display */}\n\t\t\t\t{hlsError && (\n\t\t\t\t\t<div className={loadingOverlayVariants()}>\n\t\t\t\t\t\t<div className=\"text-white text-center px-16\">\n\t\t\t\t\t\t\t<p className=\"typography-body-sm-sm\">Failed to load video</p>\n\t\t\t\t\t\t\t<p className=\"typography-caption text-white/60 mt-4\">\n\t\t\t\t\t\t\t\t{hlsError.message}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Caption Overlay */}\n\t\t\t\t{captionsEnabled && activeCue && <CaptionOverlay cue={activeCue} />}\n\t\t\t</div>\n\t\t);\n\t},\n);\nVideoPlayer.displayName = \"VideoPlayer\";\n\n// ============================================================================\n// Icons\n// ============================================================================\n\nconst CaptionsIcon = ({ enabled }: { enabled: boolean }) => (\n\t<svg\n\t\tclassName=\"w-20 h-20\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"currentColor\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t{enabled ? (\n\t\t\t// Captions On\n\t\t\t<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\" />\n\t\t) : (\n\t\t\t// Captions Off (with strike-through)\n\t\t\t<>\n\t\t\t\t<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\" />\n\t\t\t\t<line\n\t\t\t\t\tx1=\"4\"\n\t\t\t\t\ty1=\"20\"\n\t\t\t\t\tx2=\"20\"\n\t\t\t\t\ty2=\"4\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t/>\n\t\t\t</>\n\t\t)}\n\t</svg>\n);\n\nconst FullscreenIcon = ({ isFullscreen }: { isFullscreen: boolean }) => (\n\t<svg\n\t\tclassName=\"w-20 h-20\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\tstroke=\"currentColor\"\n\t\tstrokeWidth=\"2\"\n\t\tstrokeLinecap=\"round\"\n\t\tstrokeLinejoin=\"round\"\n\t\taria-hidden=\"true\"\n\t>\n\t\t{isFullscreen ? (\n\t\t\t// Minimize (exit fullscreen)\n\t\t\t<>\n\t\t\t\t<polyline points=\"4 14 10 14 10 20\" />\n\t\t\t\t<polyline points=\"20 10 14 10 14 4\" />\n\t\t\t\t<line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n\t\t\t\t<line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n\t\t\t</>\n\t\t) : (\n\t\t\t// Maximize (enter fullscreen)\n\t\t\t<>\n\t\t\t\t<polyline points=\"15 3 21 3 21 9\" />\n\t\t\t\t<polyline points=\"9 21 3 21 3 15\" />\n\t\t\t\t<line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n\t\t\t\t<line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n\t\t\t</>\n\t\t)}\n\t</svg>\n);\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n\tVideoPlayer,\n\tvideoPlayerVariants,\n\tmediaControllerVariants,\n\tcontrolBarVariants,\n\tcontrolButtonVariants,\n\tloadingOverlayVariants,\n};\n"]}
@@ -0,0 +1,236 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
4
+ import * as React from 'react';
5
+
6
+ /** Cloudflare Stream configuration */
7
+ interface CloudflareConfig {
8
+ /** Cloudflare Stream video ID */
9
+ videoId: string;
10
+ /** Cloudflare customer code/subdomain */
11
+ customerCode: string;
12
+ }
13
+ /**
14
+ * Video player container variants.
15
+ */
16
+ declare const videoPlayerVariants: tailwind_variants.TVReturnType<{
17
+ aspectRatio: {
18
+ "16/9": string;
19
+ "4/3": string;
20
+ "1/1": string;
21
+ "9/16": string;
22
+ auto: string;
23
+ };
24
+ rounded: {
25
+ none: string;
26
+ sm: string;
27
+ md: string;
28
+ lg: string;
29
+ };
30
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
31
+ aspectRatio: {
32
+ "16/9": string;
33
+ "4/3": string;
34
+ "1/1": string;
35
+ "9/16": string;
36
+ auto: string;
37
+ };
38
+ rounded: {
39
+ none: string;
40
+ sm: string;
41
+ md: string;
42
+ lg: string;
43
+ };
44
+ }, {
45
+ aspectRatio: {
46
+ "16/9": string;
47
+ "4/3": string;
48
+ "1/1": string;
49
+ "9/16": string;
50
+ auto: string;
51
+ };
52
+ rounded: {
53
+ none: string;
54
+ sm: string;
55
+ md: string;
56
+ lg: string;
57
+ };
58
+ }>, {
59
+ aspectRatio: {
60
+ "16/9": string;
61
+ "4/3": string;
62
+ "1/1": string;
63
+ "9/16": string;
64
+ auto: string;
65
+ };
66
+ rounded: {
67
+ none: string;
68
+ sm: string;
69
+ md: string;
70
+ lg: string;
71
+ };
72
+ }, undefined, tailwind_variants.TVReturnType<{
73
+ aspectRatio: {
74
+ "16/9": string;
75
+ "4/3": string;
76
+ "1/1": string;
77
+ "9/16": string;
78
+ auto: string;
79
+ };
80
+ rounded: {
81
+ none: string;
82
+ sm: string;
83
+ md: string;
84
+ lg: string;
85
+ };
86
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
87
+ aspectRatio: {
88
+ "16/9": string;
89
+ "4/3": string;
90
+ "1/1": string;
91
+ "9/16": string;
92
+ auto: string;
93
+ };
94
+ rounded: {
95
+ none: string;
96
+ sm: string;
97
+ md: string;
98
+ lg: string;
99
+ };
100
+ }, {
101
+ aspectRatio: {
102
+ "16/9": string;
103
+ "4/3": string;
104
+ "1/1": string;
105
+ "9/16": string;
106
+ auto: string;
107
+ };
108
+ rounded: {
109
+ none: string;
110
+ sm: string;
111
+ md: string;
112
+ lg: string;
113
+ };
114
+ }>, unknown, unknown, undefined>>;
115
+ /**
116
+ * Media controller container styles.
117
+ * Uses CSS custom properties to configure media-chrome components.
118
+ * Styled to match DGA video player design with ghost-style buttons.
119
+ */
120
+ declare const mediaControllerVariants: tailwind_variants.TVReturnType<{} | {} | {}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, {} | {}, undefined, tailwind_variants.TVReturnType<unknown, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
121
+ /**
122
+ * Control bar variants.
123
+ * Note: Positioning is handled via inline styles to override web component defaults.
124
+ * Tailwind classes handle background color and visibility transitions.
125
+ */
126
+ declare const controlBarVariants: tailwind_variants.TVReturnType<{
127
+ visible: {
128
+ true: string;
129
+ false: string;
130
+ };
131
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
132
+ visible: {
133
+ true: string;
134
+ false: string;
135
+ };
136
+ }, {
137
+ visible: {
138
+ true: string;
139
+ false: string;
140
+ };
141
+ }>, {
142
+ visible: {
143
+ true: string;
144
+ false: string;
145
+ };
146
+ }, undefined, tailwind_variants.TVReturnType<{
147
+ visible: {
148
+ true: string;
149
+ false: string;
150
+ };
151
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
152
+ visible: {
153
+ true: string;
154
+ false: string;
155
+ };
156
+ }, {
157
+ visible: {
158
+ true: string;
159
+ false: string;
160
+ };
161
+ }>, unknown, unknown, undefined>>;
162
+ /**
163
+ * Control button styles for custom buttons.
164
+ * Transparent by default, shows background on hover (ghost style).
165
+ */
166
+ declare const controlButtonVariants: tailwind_variants.TVReturnType<{} | {} | {}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, {} | {}, undefined, tailwind_variants.TVReturnType<unknown, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
167
+ /**
168
+ * Loading overlay variants.
169
+ */
170
+ declare const loadingOverlayVariants: tailwind_variants.TVReturnType<{} | {} | {}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, {} | {}, undefined, tailwind_variants.TVReturnType<unknown, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
171
+ interface VideoPlayerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onError" | "onPlay" | "onPause" | "onEnded" | "onTimeUpdate">, VariantProps<typeof videoPlayerVariants> {
172
+ /** Video source URL (HLS .m3u8 or regular video file) */
173
+ src?: string;
174
+ /** Cloudflare Stream configuration (takes precedence over src) */
175
+ cloudflare?: CloudflareConfig;
176
+ /** Poster image URL */
177
+ poster?: string;
178
+ /** VTT captions URL */
179
+ captionsSrc?: string;
180
+ /** Whether to autoplay (default: false) */
181
+ autoPlay?: boolean;
182
+ /** Whether to loop the video (default: false) */
183
+ loop?: boolean;
184
+ /** Whether to mute initially (default: false) */
185
+ muted?: boolean;
186
+ /** Whether to show controls (default: true) */
187
+ controls?: boolean;
188
+ /** Whether to auto-hide controls when not interacting (default: true) */
189
+ autoHideControls?: boolean;
190
+ /** Control auto-hide delay in ms (default: 3000) */
191
+ autoHideDelay?: number;
192
+ /** Whether captions are enabled by default (default: false) */
193
+ captionsEnabled?: boolean;
194
+ /** Callback when video starts playing */
195
+ onPlay?: () => void;
196
+ /** Callback when video pauses */
197
+ onPause?: () => void;
198
+ /** Callback when video ends */
199
+ onEnded?: () => void;
200
+ /** Callback on time update */
201
+ onTimeUpdate?: (time: number) => void;
202
+ /** Callback on error */
203
+ onError?: (error: Error) => void;
204
+ /** Ref to the video element */
205
+ videoRef?: React.RefObject<HTMLVideoElement | null>;
206
+ }
207
+ /**
208
+ * VideoPlayer - Standalone video player component with media-chrome controls.
209
+ *
210
+ * Supports Cloudflare Stream (recommended) or direct video URLs with HLS support.
211
+ * Works standalone or can be composed with Modal for fullscreen playback.
212
+ *
213
+ * @example
214
+ * ```tsx
215
+ * // With Cloudflare Stream (recommended)
216
+ * <VideoPlayer
217
+ * cloudflare={{ videoId: "abc123", customerCode: "xyz789" }}
218
+ * poster="/thumbnail.jpg"
219
+ * captionsSrc="/captions.vtt"
220
+ * />
221
+ *
222
+ * // With direct URL
223
+ * <VideoPlayer
224
+ * src="https://example.com/video.mp4"
225
+ * poster="/thumbnail.jpg"
226
+ * />
227
+ *
228
+ * // With Modal for fullscreen
229
+ * <Modal trigger={<Button>Watch Video</Button>}>
230
+ * <VideoPlayer cloudflare={{ videoId: "...", customerCode: "..." }} />
231
+ * </Modal>
232
+ * ```
233
+ */
234
+ declare const VideoPlayer: React.ForwardRefExoticComponent<VideoPlayerProps & React.RefAttributes<HTMLDivElement>>;
235
+
236
+ export { type VideoPlayerProps as V, controlButtonVariants as a, VideoPlayer as b, controlBarVariants as c, loadingOverlayVariants as l, mediaControllerVariants as m, videoPlayerVariants as v };
@@ -0,0 +1,267 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
4
+ import * as React from 'react';
5
+ import { BlurredVideoBackdropProps } from '../blurred-video-backdrop/index.js';
6
+ import { V as VideoPlayerProps } from '../video-player-qxf-BURH.js';
7
+
8
+ /** Cloudflare Stream configuration */
9
+ interface CloudflareConfig {
10
+ /** Cloudflare Stream video ID */
11
+ videoId: string;
12
+ /** Cloudflare customer code/subdomain */
13
+ customerCode: string;
14
+ }
15
+ /**
16
+ * Root container variants.
17
+ */
18
+ declare const videoWithBackdropVariants: tailwind_variants.TVReturnType<{
19
+ /**
20
+ * Full-height mode for dialogs.
21
+ */
22
+ fullHeight: {
23
+ true: string;
24
+ false: string;
25
+ };
26
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
27
+ /**
28
+ * Full-height mode for dialogs.
29
+ */
30
+ fullHeight: {
31
+ true: string;
32
+ false: string;
33
+ };
34
+ }, {
35
+ /**
36
+ * Full-height mode for dialogs.
37
+ */
38
+ fullHeight: {
39
+ true: string;
40
+ false: string;
41
+ };
42
+ }>, {
43
+ /**
44
+ * Full-height mode for dialogs.
45
+ */
46
+ fullHeight: {
47
+ true: string;
48
+ false: string;
49
+ };
50
+ }, undefined, tailwind_variants.TVReturnType<{
51
+ /**
52
+ * Full-height mode for dialogs.
53
+ */
54
+ fullHeight: {
55
+ true: string;
56
+ false: string;
57
+ };
58
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
59
+ /**
60
+ * Full-height mode for dialogs.
61
+ */
62
+ fullHeight: {
63
+ true: string;
64
+ false: string;
65
+ };
66
+ }, {
67
+ /**
68
+ * Full-height mode for dialogs.
69
+ */
70
+ fullHeight: {
71
+ true: string;
72
+ false: string;
73
+ };
74
+ }>, unknown, unknown, undefined>>;
75
+ /**
76
+ * Content container variants.
77
+ */
78
+ declare const contentVariants: tailwind_variants.TVReturnType<{
79
+ fullHeight: {
80
+ true: string;
81
+ false: string;
82
+ };
83
+ padding: {
84
+ none: string;
85
+ sm: string;
86
+ md: string;
87
+ lg: string;
88
+ };
89
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
90
+ fullHeight: {
91
+ true: string;
92
+ false: string;
93
+ };
94
+ padding: {
95
+ none: string;
96
+ sm: string;
97
+ md: string;
98
+ lg: string;
99
+ };
100
+ }, {
101
+ fullHeight: {
102
+ true: string;
103
+ false: string;
104
+ };
105
+ padding: {
106
+ none: string;
107
+ sm: string;
108
+ md: string;
109
+ lg: string;
110
+ };
111
+ }>, {
112
+ fullHeight: {
113
+ true: string;
114
+ false: string;
115
+ };
116
+ padding: {
117
+ none: string;
118
+ sm: string;
119
+ md: string;
120
+ lg: string;
121
+ };
122
+ }, undefined, tailwind_variants.TVReturnType<{
123
+ fullHeight: {
124
+ true: string;
125
+ false: string;
126
+ };
127
+ padding: {
128
+ none: string;
129
+ sm: string;
130
+ md: string;
131
+ lg: string;
132
+ };
133
+ }, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
134
+ fullHeight: {
135
+ true: string;
136
+ false: string;
137
+ };
138
+ padding: {
139
+ none: string;
140
+ sm: string;
141
+ md: string;
142
+ lg: string;
143
+ };
144
+ }, {
145
+ fullHeight: {
146
+ true: string;
147
+ false: string;
148
+ };
149
+ padding: {
150
+ none: string;
151
+ sm: string;
152
+ md: string;
153
+ lg: string;
154
+ };
155
+ }>, unknown, unknown, undefined>>;
156
+ interface VideoWithBackdropRootProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof videoWithBackdropVariants> {
157
+ /** Video source URL (HLS .m3u8 or regular video file) */
158
+ src?: string;
159
+ /** Cloudflare Stream configuration (takes precedence over src) */
160
+ cloudflare?: CloudflareConfig;
161
+ /** Children to render */
162
+ children: React.ReactNode;
163
+ }
164
+ /**
165
+ * VideoWithBackdrop Root
166
+ *
167
+ * Container that provides video context to child components.
168
+ * Use with VideoWithBackdrop.Backdrop and VideoWithBackdrop.Content.
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * <VideoWithBackdrop.Root cloudflare={config}>
173
+ * <VideoWithBackdrop.Backdrop blur="high" overlay="vignette" />
174
+ * <VideoWithBackdrop.Content>
175
+ * <VideoWithBackdrop.Video />
176
+ * </VideoWithBackdrop.Content>
177
+ * </VideoWithBackdrop.Root>
178
+ * ```
179
+ */
180
+ declare const VideoWithBackdropRoot: React.ForwardRefExoticComponent<VideoWithBackdropRootProps & React.RefAttributes<HTMLDivElement>>;
181
+ interface VideoWithBackdropBackdropProps extends Omit<BlurredVideoBackdropProps, "videoRef"> {
182
+ }
183
+ /**
184
+ * VideoWithBackdrop Backdrop
185
+ *
186
+ * Renders the blurred video backdrop layer using canvas.
187
+ * Automatically draws from the video element in context.
188
+ */
189
+ declare const VideoWithBackdropBackdrop: React.ForwardRefExoticComponent<VideoWithBackdropBackdropProps & React.RefAttributes<HTMLDivElement>>;
190
+ interface VideoWithBackdropContentProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof contentVariants> {
191
+ }
192
+ /**
193
+ * VideoWithBackdrop Content
194
+ *
195
+ * Container for the main video player and any additional content.
196
+ * Positioned above the backdrop with z-index.
197
+ */
198
+ declare const VideoWithBackdropContent: React.ForwardRefExoticComponent<VideoWithBackdropContentProps & React.RefAttributes<HTMLDivElement>>;
199
+ interface VideoWithBackdropVideoProps extends Omit<VideoPlayerProps, "videoRef"> {
200
+ /** Max width of the video player container */
201
+ maxWidth?: string;
202
+ }
203
+ /**
204
+ * VideoWithBackdrop Video
205
+ *
206
+ * Convenience wrapper for VideoPlayer that automatically connects
207
+ * to the backdrop via context.
208
+ */
209
+ declare const VideoWithBackdropVideo: React.ForwardRefExoticComponent<VideoWithBackdropVideoProps & React.RefAttributes<HTMLDivElement>>;
210
+ interface VideoWithBackdropProps extends Omit<VideoPlayerProps, "videoRef" | "className" | "aspectRatio"> {
211
+ /** Blur intensity (default: high) */
212
+ blur?: BlurredVideoBackdropProps["blur"];
213
+ /** Gradient overlay (default: vignette) */
214
+ overlay?: BlurredVideoBackdropProps["overlay"];
215
+ /** Backdrop opacity (default: 0.6) */
216
+ backdropOpacity?: number;
217
+ /** Max width of video player (default: 960px) */
218
+ maxWidth?: string;
219
+ /** Content padding (default: md) */
220
+ padding?: "none" | "sm" | "md" | "lg";
221
+ /** Video player rounded corners */
222
+ rounded?: VideoPlayerProps["rounded"];
223
+ /** Additional className for root container */
224
+ className?: string;
225
+ /** Target FPS for backdrop canvas (default: 30) */
226
+ targetFps?: number;
227
+ /** Canvas scale factor for backdrop (default: 0.5) */
228
+ scale?: number;
229
+ }
230
+ /**
231
+ * VideoWithBackdrop - Pre-composed video player with blurred backdrop.
232
+ *
233
+ * A simple, ready-to-use component that combines VideoPlayer with
234
+ * BlurredVideoBackdrop for modal video experiences. Uses canvas rendering
235
+ * for optimal performance.
236
+ *
237
+ * For custom layouts, use the compound components:
238
+ * - VideoWithBackdrop.Root
239
+ * - VideoWithBackdrop.Backdrop
240
+ * - VideoWithBackdrop.Content
241
+ * - VideoWithBackdrop.Video
242
+ *
243
+ * @example
244
+ * ```tsx
245
+ * // Simple usage (in a full-height container like Dialog)
246
+ * <VideoWithBackdrop
247
+ * cloudflare={{ videoId: "...", customerCode: "..." }}
248
+ * autoPlay
249
+ * blur="high"
250
+ * overlay="vignette"
251
+ * />
252
+ *
253
+ * // With Dialog
254
+ * <Dialog size="full" variant="minimal">
255
+ * <VideoWithBackdrop cloudflare={config} autoPlay />
256
+ * </Dialog>
257
+ * ```
258
+ */
259
+ declare const VideoWithBackdrop: React.ForwardRefExoticComponent<VideoWithBackdropProps & React.RefAttributes<HTMLDivElement>>;
260
+ declare const VideoWithBackdropParts: React.ForwardRefExoticComponent<VideoWithBackdropRootProps & React.RefAttributes<HTMLDivElement>> & {
261
+ Root: React.ForwardRefExoticComponent<VideoWithBackdropRootProps & React.RefAttributes<HTMLDivElement>>;
262
+ Backdrop: React.ForwardRefExoticComponent<VideoWithBackdropBackdropProps & React.RefAttributes<HTMLDivElement>>;
263
+ Content: React.ForwardRefExoticComponent<VideoWithBackdropContentProps & React.RefAttributes<HTMLDivElement>>;
264
+ Video: React.ForwardRefExoticComponent<VideoWithBackdropVideoProps & React.RefAttributes<HTMLDivElement>>;
265
+ };
266
+
267
+ export { VideoWithBackdrop, VideoWithBackdropBackdrop, type VideoWithBackdropBackdropProps, VideoWithBackdropContent, type VideoWithBackdropContentProps, VideoWithBackdropParts, type VideoWithBackdropProps, VideoWithBackdropRoot, type VideoWithBackdropRootProps, VideoWithBackdropVideo, type VideoWithBackdropVideoProps, contentVariants, videoWithBackdropVariants };