@geekapps/silo-elements-nextjs 0.2.56 → 0.2.58

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.
@@ -33,6 +33,14 @@ function StoryboardFrame(_props) {
33
33
  return null;
34
34
  }
35
35
  StoryboardFrame.displayName = "SiloStoryboardFrame";
36
+ function AgeRating(_props) {
37
+ return null;
38
+ }
39
+ AgeRating.displayName = "SiloAgeRating";
40
+ function Rating(_props) {
41
+ return null;
42
+ }
43
+ Rating.displayName = "SiloRating";
36
44
  function Video({
37
45
  title,
38
46
  description,
@@ -154,6 +162,8 @@ function Video({
154
162
  const dragPointerIdRef = useRef(null);
155
163
  const [isPlaying, setIsPlaying] = useState(false);
156
164
  const [hasPlayed, setHasPlayed] = useState(false);
165
+ const [ageRatingOverlay, setAgeRatingOverlay] = useState(false);
166
+ const ageRatingTimerRef = useRef(null);
157
167
  const [clickIcon, setClickIcon] = useState(null);
158
168
  const clickIconTimerRef = useRef(null);
159
169
  const [isLoading, setIsLoading] = useState(true);
@@ -261,7 +271,14 @@ function Video({
261
271
  };
262
272
  const onPlay = () => {
263
273
  setIsPlaying(true);
264
- setHasPlayed(true);
274
+ setHasPlayed((prev) => {
275
+ if (!prev && parsed.ageRating?.data) {
276
+ setAgeRatingOverlay(true);
277
+ if (ageRatingTimerRef.current) window.clearTimeout(ageRatingTimerRef.current);
278
+ ageRatingTimerRef.current = window.setTimeout(() => setAgeRatingOverlay(false), 4e3);
279
+ }
280
+ return true;
281
+ });
265
282
  showControlsTemporarily();
266
283
  };
267
284
  const onPause = () => {
@@ -840,600 +857,760 @@ function Video({
840
857
  "."
841
858
  ] });
842
859
  }
843
- return /* @__PURE__ */ jsx(
860
+ return /* @__PURE__ */ jsxs(
844
861
  "div",
845
862
  {
846
863
  ref: containerRef,
847
864
  className: `@container mx-auto w-full max-w-6xl${className ?? ""}`,
848
- children: /* @__PURE__ */ jsxs(
849
- "div",
850
- {
851
- ref: playerRef,
852
- tabIndex: 0,
853
- onKeyDown: handleKeyDown,
854
- onMouseMove: showControlsTemporarily,
855
- onMouseLeave: () => {
856
- closeSettings();
857
- if (isPlaying && autoHideControls) {
858
- setControlsVisible(false);
859
- }
860
- },
861
- onBlur: (e) => {
862
- if (!e.currentTarget.contains(e.relatedTarget)) {
865
+ children: [
866
+ /* @__PURE__ */ jsx("style", { children: `@keyframes silo-fade-out{0%{opacity:1}70%{opacity:1}100%{opacity:0}}` }),
867
+ /* @__PURE__ */ jsxs(
868
+ "div",
869
+ {
870
+ ref: playerRef,
871
+ tabIndex: 0,
872
+ onKeyDown: handleKeyDown,
873
+ onMouseMove: showControlsTemporarily,
874
+ onMouseLeave: () => {
863
875
  closeSettings();
864
- }
865
- },
866
- onTouchStart: showControlsTemporarily,
867
- onTouchMove: showControlsTemporarily,
868
- className: "relative w-full overflow-hidden rounded-[14px] bg-black shadow-[0_30px_90px_rgba(15,15,15,0.22)] outline-none ring-1 ring-black/5",
869
- style: fixedHeight ? {
870
- height: typeof fixedHeight === "number" ? `${fixedHeight}px` : fixedHeight
871
- } : maxHeight ? {
872
- maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
873
- aspectRatio: "16/9"
874
- } : { aspectRatio: "16/9" },
875
- children: [
876
- /* @__PURE__ */ jsxs(
877
- "video",
878
- {
879
- ref: videoRef,
880
- className: `h-full w-full ${isFullscreen ? "object-contain" : "object-cover"}`,
881
- playsInline: true,
882
- preload: "metadata",
883
- crossOrigin: "anonymous",
884
- children: [
885
- captions.map((subtitle) => /* @__PURE__ */ jsx(
886
- "track",
887
- {
888
- kind: "subtitles",
889
- src: subtitle.src,
890
- srcLang: subtitle.srclang,
891
- label: subtitle.label,
892
- default: subtitle.default
893
- },
894
- `${activeSource.src}-${subtitle.srclang}-${subtitle.src}`
895
- )),
896
- parsed.storyboard?.src && /* @__PURE__ */ jsx(
897
- "track",
898
- {
899
- kind: "metadata",
900
- label: "thumbnails",
901
- src: parsed.storyboard.src
902
- }
903
- )
904
- ]
876
+ if (isPlaying && autoHideControls) {
877
+ setControlsVisible(false);
905
878
  }
906
- ),
907
- poster && !hasPlayed && /* @__PURE__ */ jsx(
908
- "img",
909
- {
910
- src: poster,
911
- "aria-hidden": true,
912
- className: "pointer-events-none absolute inset-0 h-full w-full object-contain bg-black"
879
+ },
880
+ onBlur: (e) => {
881
+ if (!e.currentTarget.contains(e.relatedTarget)) {
882
+ closeSettings();
913
883
  }
914
- ),
915
- /* @__PURE__ */ jsx(
916
- "div",
917
- {
918
- className: "pointer-events-none absolute inset-0 z-10 grid place-items-center",
919
- style: {
920
- opacity: clickIcon ? 1 : 0,
921
- transition: clickIcon ? "opacity 0.08s ease-in" : "opacity 0.45s ease-out"
922
- },
923
- children: /* @__PURE__ */ jsx("span", { className: "grid size-10 place-items-center text-white drop-shadow-[0_2px_12px_rgba(0,0,0,0.8)] @sm:size-14 @lg:size-16", children: clickIcon === "pause" ? /* @__PURE__ */ jsx(Pause, { className: "size-7 @sm:size-9 @lg:size-11", fill: "white" }) : /* @__PURE__ */ jsx(
924
- Play,
884
+ },
885
+ onTouchStart: showControlsTemporarily,
886
+ onTouchMove: showControlsTemporarily,
887
+ className: "relative w-full overflow-hidden rounded-[14px] bg-black shadow-[0_30px_90px_rgba(15,15,15,0.22)] outline-none ring-1 ring-black/5",
888
+ style: fixedHeight ? {
889
+ height: typeof fixedHeight === "number" ? `${fixedHeight}px` : fixedHeight
890
+ } : maxHeight ? {
891
+ maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
892
+ aspectRatio: "16/9"
893
+ } : { aspectRatio: "16/9" },
894
+ children: [
895
+ /* @__PURE__ */ jsxs(
896
+ "video",
897
+ {
898
+ ref: videoRef,
899
+ className: `h-full w-full ${isFullscreen ? "object-contain" : "object-cover"}`,
900
+ playsInline: true,
901
+ preload: "metadata",
902
+ crossOrigin: "anonymous",
903
+ children: [
904
+ captions.map((subtitle) => /* @__PURE__ */ jsx(
905
+ "track",
906
+ {
907
+ kind: "subtitles",
908
+ src: subtitle.src,
909
+ srcLang: subtitle.srclang,
910
+ label: subtitle.label,
911
+ default: subtitle.default
912
+ },
913
+ `${activeSource.src}-${subtitle.srclang}-${subtitle.src}`
914
+ )),
915
+ parsed.storyboard?.src && /* @__PURE__ */ jsx(
916
+ "track",
917
+ {
918
+ kind: "metadata",
919
+ label: "thumbnails",
920
+ src: parsed.storyboard.src
921
+ }
922
+ )
923
+ ]
924
+ }
925
+ ),
926
+ poster && !hasPlayed && /* @__PURE__ */ jsx(
927
+ "img",
928
+ {
929
+ src: poster,
930
+ "aria-hidden": true,
931
+ className: "pointer-events-none absolute inset-0 h-full w-full object-contain bg-black"
932
+ }
933
+ ),
934
+ ageRatingOverlay && parsed.ageRating?.data && (() => {
935
+ const ar = parsed.ageRating;
936
+ const regionKey = resolveAgeRatingRegion(ar.locale, ar.data);
937
+ if (!regionKey) return null;
938
+ const code = ar.data[regionKey];
939
+ const lookupKey = `${regionKey}:${code}`;
940
+ const info = ar.lookup?.[lookupKey];
941
+ return /* @__PURE__ */ jsx(
942
+ "div",
925
943
  {
926
- className: "ml-0.5 size-7 @sm:size-9 @lg:size-11",
927
- fill: "white"
944
+ className: "pointer-events-none absolute inset-0 z-40 flex items-start justify-start p-4",
945
+ style: { animation: "silo-fade-out 4s forwards" },
946
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 rounded-lg px-3 py-2", style: { background: "rgba(0,0,0,0.72)", backdropFilter: "blur(8px)" }, children: [
947
+ info?.imageUrl ? /* @__PURE__ */ jsx("img", { src: info.imageUrl, alt: code, className: "h-10 w-auto object-contain" }) : /* @__PURE__ */ jsx("span", { className: "flex h-10 min-w-10 items-center justify-center rounded border border-white/30 px-1.5 text-sm font-bold text-white", children: code }),
948
+ (info?.title || info?.description) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
949
+ info.title && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-white", children: info.title }),
950
+ info.description && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-white/60 leading-tight max-w-48", children: info.description })
951
+ ] })
952
+ ] })
928
953
  }
929
- ) })
930
- }
931
- ),
932
- isLoading && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-20 grid place-items-center bg-black/10", children: /* @__PURE__ */ jsx("div", { className: "size-9 animate-spin rounded-full border-2 border-white/25 border-t-white" }) }),
933
- /* @__PURE__ */ jsxs(
934
- "div",
935
- {
936
- ref: chromeRef,
937
- onClick: togglePlay,
938
- className: `absolute inset-0 z-30 flex flex-col transition-opacity duration-200 ${isFullscreen ? "justify-between" : "justify-end"} ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"}`,
939
- children: [
940
- isFullscreen && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-black/70 to-transparent" }),
941
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-black/80 to-transparent" }),
942
- isFullscreen && /* @__PURE__ */ jsx(
943
- "header",
954
+ );
955
+ })(),
956
+ /* @__PURE__ */ jsx(
957
+ "div",
958
+ {
959
+ className: "pointer-events-none absolute inset-0 z-10 grid place-items-center",
960
+ style: {
961
+ opacity: clickIcon ? 1 : 0,
962
+ transition: clickIcon ? "opacity 0.08s ease-in" : "opacity 0.45s ease-out"
963
+ },
964
+ children: /* @__PURE__ */ jsx("span", { className: "grid size-10 place-items-center text-white drop-shadow-[0_2px_12px_rgba(0,0,0,0.8)] @sm:size-14 @lg:size-16", children: clickIcon === "pause" ? /* @__PURE__ */ jsx(Pause, { className: "size-7 @sm:size-9 @lg:size-11", fill: "white" }) : /* @__PURE__ */ jsx(
965
+ Play,
944
966
  {
945
- onClick: (e) => e.stopPropagation(),
946
- className: "relative z-10 flex items-start px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8",
947
- children: /* @__PURE__ */ jsxs("div", { children: [
948
- title && /* @__PURE__ */ jsx(
949
- "h1",
950
- {
951
- className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl",
952
- style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" },
953
- children: title
954
- }
955
- ),
956
- description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
957
- ] })
967
+ className: "ml-0.5 size-7 @sm:size-9 @lg:size-11",
968
+ fill: "white"
958
969
  }
959
- ),
960
- /* @__PURE__ */ jsxs(
961
- "footer",
962
- {
963
- onClick: (e) => e.stopPropagation(),
964
- className: "relative z-10 px-4 pb-4 text-white",
965
- children: [
966
- settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
967
- /* @__PURE__ */ jsx(
968
- "div",
970
+ ) })
971
+ }
972
+ ),
973
+ isLoading && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-20 grid place-items-center bg-black/10", children: /* @__PURE__ */ jsx("div", { className: "size-9 animate-spin rounded-full border-2 border-white/25 border-t-white" }) }),
974
+ /* @__PURE__ */ jsxs(
975
+ "div",
976
+ {
977
+ ref: chromeRef,
978
+ onClick: togglePlay,
979
+ className: `absolute inset-0 z-30 flex flex-col transition-opacity duration-200 ${isFullscreen ? "justify-between" : "justify-end"} ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"}`,
980
+ children: [
981
+ isFullscreen && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 h-32 bg-linear-to-b from-black/70 to-transparent" }),
982
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-black/80 to-transparent" }),
983
+ isFullscreen && /* @__PURE__ */ jsx(
984
+ "header",
985
+ {
986
+ onClick: (e) => e.stopPropagation(),
987
+ className: "relative z-10 flex items-start px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8",
988
+ children: /* @__PURE__ */ jsxs("div", { children: [
989
+ title && /* @__PURE__ */ jsx(
990
+ "h1",
969
991
  {
970
- className: "fixed inset-0 z-70",
971
- onClick: closeSettings
992
+ className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl",
993
+ style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" },
994
+ children: title
972
995
  }
973
996
  ),
974
- /* @__PURE__ */ jsxs(
975
- "div",
976
- {
977
- className: "absolute bottom-full right-2 z-70 mb-2 overflow-hidden rounded-2xl bg-[#1c1c1e]/95 shadow-2xl backdrop-blur-xl ring-1 ring-white/10",
978
- style: {
979
- width: Math.min(
980
- 224,
981
- Math.max(180, (playerWidth || 640) * 0.22)
982
- ) + "px",
983
- opacity: settingsVisible ? 1 : 0,
984
- transform: settingsVisible ? "translateY(0) scale(1)" : "translateY(8px) scale(0.97)",
985
- transition: "opacity 0.18s ease, transform 0.18s ease"
986
- },
987
- children: [
988
- settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
989
- {
990
- id: "quality",
991
- label: "Qualidade",
992
- value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto"
993
- },
994
- ...captions.length > 0 ? [
995
- {
996
- id: "subtitles",
997
- label: "Legendas",
998
- value: subtitleStyle.track === "off" ? "Desligado" : captions.find(
999
- (s) => s.srclang === subtitleStyle.track
1000
- )?.label ?? subtitleStyle.track
1001
- }
1002
- ] : [],
1003
- ...audioTracks.length > 1 ? [
1004
- {
1005
- id: "audio",
1006
- label: "\xC1udio",
1007
- value: audioTracks.find(
1008
- (t) => t.id === selectedAudio
1009
- )?.label ?? ""
1010
- }
1011
- ] : [],
1012
- {
1013
- id: "playback",
1014
- label: "Velocidade",
1015
- value: playbackRate === 1 ? "Normal" : `${playbackRate}\xD7`
1016
- }
1017
- ].map((item) => /* @__PURE__ */ jsxs(
1018
- "button",
1019
- {
1020
- type: "button",
1021
- onClick: () => setSettingsTab(item.id),
1022
- className: "flex w-full items-center justify-between gap-3 px-4 py-3 text-sm transition hover:bg-white/8 first:pt-3.5 last:pb-3.5",
1023
- children: [
1024
- /* @__PURE__ */ jsx("span", { className: "text-white/80", children: item.label }),
1025
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-xs text-white/40", children: [
1026
- item.value,
1027
- /* @__PURE__ */ jsx(
1028
- "svg",
1029
- {
1030
- className: "size-3 opacity-50",
1031
- viewBox: "0 0 12 12",
1032
- fill: "none",
1033
- children: /* @__PURE__ */ jsx(
1034
- "path",
1035
- {
1036
- d: "M4.5 3l3 3-3 3",
1037
- stroke: "currentColor",
1038
- strokeWidth: "1.5",
1039
- strokeLinecap: "round",
1040
- strokeLinejoin: "round"
1041
- }
1042
- )
1043
- }
1044
- )
1045
- ] })
1046
- ]
1047
- },
1048
- item.id
1049
- )) }),
1050
- settingsTab === "quality" && /* @__PURE__ */ jsxs("div", { children: [
1051
- /* @__PURE__ */ jsxs(
1052
- "button",
1053
- {
1054
- type: "button",
1055
- onClick: () => setSettingsTab("root"),
1056
- className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1057
- children: [
1058
- /* @__PURE__ */ jsx(
1059
- "svg",
1060
- {
1061
- className: "size-3.5",
1062
- viewBox: "0 0 12 12",
1063
- fill: "none",
1064
- children: /* @__PURE__ */ jsx(
1065
- "path",
1066
- {
1067
- d: "M7.5 3L4.5 6l3 3",
1068
- stroke: "currentColor",
1069
- strokeWidth: "1.5",
1070
- strokeLinecap: "round",
1071
- strokeLinejoin: "round"
1072
- }
1073
- )
1074
- }
1075
- ),
1076
- "Qualidade"
1077
- ]
1078
- }
1079
- ),
1080
- /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(
1081
- "button",
997
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
998
+ ] })
999
+ }
1000
+ ),
1001
+ /* @__PURE__ */ jsxs(
1002
+ "footer",
1003
+ {
1004
+ onClick: (e) => e.stopPropagation(),
1005
+ className: "relative z-10 px-4 pb-4 text-white",
1006
+ children: [
1007
+ settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
1008
+ /* @__PURE__ */ jsx(
1009
+ "div",
1010
+ {
1011
+ className: "fixed inset-0 z-70",
1012
+ onClick: closeSettings
1013
+ }
1014
+ ),
1015
+ /* @__PURE__ */ jsxs(
1016
+ "div",
1017
+ {
1018
+ className: "absolute bottom-full right-2 z-70 mb-2 overflow-hidden rounded-2xl bg-[#1c1c1e]/95 shadow-2xl backdrop-blur-xl ring-1 ring-white/10",
1019
+ style: {
1020
+ width: Math.min(
1021
+ 224,
1022
+ Math.max(180, (playerWidth || 640) * 0.22)
1023
+ ) + "px",
1024
+ opacity: settingsVisible ? 1 : 0,
1025
+ transform: settingsVisible ? "translateY(0) scale(1)" : "translateY(8px) scale(0.97)",
1026
+ transition: "opacity 0.18s ease, transform 0.18s ease"
1027
+ },
1028
+ children: [
1029
+ settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
1082
1030
  {
1083
- type: "button",
1084
- onClick: () => {
1085
- changeQuality(quality.id);
1086
- setSettingsTab("root");
1087
- },
1088
- className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1089
- children: [
1090
- /* @__PURE__ */ jsx(
1091
- "svg",
1092
- {
1093
- className: `size-4 shrink-0 ${selectedQuality === quality.id ? "text-white" : "text-transparent"}`,
1094
- viewBox: "0 0 16 16",
1095
- fill: "none",
1096
- children: /* @__PURE__ */ jsx(
1097
- "path",
1098
- {
1099
- d: "M3 8l3.5 3.5L13 4.5",
1100
- stroke: "currentColor",
1101
- strokeWidth: "1.8",
1102
- strokeLinecap: "round",
1103
- strokeLinejoin: "round"
1104
- }
1105
- )
1106
- }
1107
- ),
1108
- /* @__PURE__ */ jsxs(
1109
- "span",
1110
- {
1111
- className: selectedQuality === quality.id ? "font-semibold text-white" : "text-white/55",
1112
- children: [
1113
- quality.label,
1114
- quality.id === "auto" ? " (ABR)" : ""
1115
- ]
1116
- }
1117
- )
1118
- ]
1031
+ id: "quality",
1032
+ label: "Qualidade",
1033
+ value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto"
1119
1034
  },
1120
- quality.id
1121
- )) })
1122
- ] }),
1123
- settingsTab === "subtitles" && /* @__PURE__ */ jsxs("div", { children: [
1124
- /* @__PURE__ */ jsxs(
1125
- "button",
1035
+ ...captions.length > 0 ? [
1036
+ {
1037
+ id: "subtitles",
1038
+ label: "Legendas",
1039
+ value: subtitleStyle.track === "off" ? "Desligado" : captions.find(
1040
+ (s) => s.srclang === subtitleStyle.track
1041
+ )?.label ?? subtitleStyle.track
1042
+ }
1043
+ ] : [],
1044
+ ...audioTracks.length > 1 ? [
1045
+ {
1046
+ id: "audio",
1047
+ label: "\xC1udio",
1048
+ value: audioTracks.find(
1049
+ (t) => t.id === selectedAudio
1050
+ )?.label ?? ""
1051
+ }
1052
+ ] : [],
1126
1053
  {
1127
- type: "button",
1128
- onClick: () => setSettingsTab("root"),
1129
- className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1130
- children: [
1131
- /* @__PURE__ */ jsx(
1132
- "svg",
1133
- {
1134
- className: "size-3.5",
1135
- viewBox: "0 0 12 12",
1136
- fill: "none",
1137
- children: /* @__PURE__ */ jsx(
1138
- "path",
1139
- {
1140
- d: "M7.5 3L4.5 6l3 3",
1141
- stroke: "currentColor",
1142
- strokeWidth: "1.5",
1143
- strokeLinecap: "round",
1144
- strokeLinejoin: "round"
1145
- }
1146
- )
1147
- }
1148
- ),
1149
- "Legendas"
1150
- ]
1054
+ id: "playback",
1055
+ label: "Velocidade",
1056
+ value: playbackRate === 1 ? "Normal" : `${playbackRate}\xD7`
1151
1057
  }
1152
- ),
1153
- /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [
1154
- { srclang: "off", label: "Desligado" },
1155
- ...captions
1156
- ].map((s) => /* @__PURE__ */ jsxs(
1058
+ ].map((item) => /* @__PURE__ */ jsxs(
1157
1059
  "button",
1158
1060
  {
1159
1061
  type: "button",
1160
- onClick: () => {
1161
- const next = s.srclang === "off" ? "off" : s.srclang;
1162
- setSubtitleMode(next);
1163
- setSubtitleStyle((st) => ({
1164
- ...st,
1165
- track: next
1166
- }));
1167
- },
1168
- className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1062
+ onClick: () => setSettingsTab(item.id),
1063
+ className: "flex w-full items-center justify-between gap-3 px-4 py-3 text-sm transition hover:bg-white/8 first:pt-3.5 last:pb-3.5",
1169
1064
  children: [
1170
- /* @__PURE__ */ jsx(
1171
- "svg",
1172
- {
1173
- className: `size-4 shrink-0 ${subtitleStyle.track === s.srclang ? "text-white" : "text-transparent"}`,
1174
- viewBox: "0 0 16 16",
1175
- fill: "none",
1176
- children: /* @__PURE__ */ jsx(
1177
- "path",
1178
- {
1179
- d: "M3 8l3.5 3.5L13 4.5",
1180
- stroke: "currentColor",
1181
- strokeWidth: "1.8",
1182
- strokeLinecap: "round",
1183
- strokeLinejoin: "round"
1184
- }
1185
- )
1186
- }
1187
- ),
1188
- /* @__PURE__ */ jsx(
1189
- "span",
1190
- {
1191
- className: subtitleStyle.track === s.srclang ? "font-semibold text-white" : "text-white/55",
1192
- children: s.label
1193
- }
1194
- )
1065
+ /* @__PURE__ */ jsx("span", { className: "text-white/80", children: item.label }),
1066
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-xs text-white/40", children: [
1067
+ item.value,
1068
+ /* @__PURE__ */ jsx(
1069
+ "svg",
1070
+ {
1071
+ className: "size-3 opacity-50",
1072
+ viewBox: "0 0 12 12",
1073
+ fill: "none",
1074
+ children: /* @__PURE__ */ jsx(
1075
+ "path",
1076
+ {
1077
+ d: "M4.5 3l3 3-3 3",
1078
+ stroke: "currentColor",
1079
+ strokeWidth: "1.5",
1080
+ strokeLinecap: "round",
1081
+ strokeLinejoin: "round"
1082
+ }
1083
+ )
1084
+ }
1085
+ )
1086
+ ] })
1195
1087
  ]
1196
1088
  },
1197
- s.srclang
1089
+ item.id
1198
1090
  )) }),
1199
- subtitleStyle.track !== "off" && /* @__PURE__ */ jsxs(
1200
- "button",
1201
- {
1202
- type: "button",
1203
- onClick: () => setSettingsTab("subtitles-style"),
1204
- className: "flex w-full items-center justify-between gap-3 border-t border-white/8 px-4 py-3 text-sm transition hover:bg-white/8",
1205
- children: [
1206
- /* @__PURE__ */ jsx("span", { className: "text-white/60", children: "Apar\xEAncia" }),
1207
- /* @__PURE__ */ jsx(
1208
- "svg",
1209
- {
1210
- className: "size-3 opacity-50",
1211
- viewBox: "0 0 12 12",
1212
- fill: "none",
1213
- children: /* @__PURE__ */ jsx(
1214
- "path",
1215
- {
1216
- d: "M4.5 3l3 3-3 3",
1217
- stroke: "currentColor",
1218
- strokeWidth: "1.5",
1219
- strokeLinecap: "round",
1220
- strokeLinejoin: "round"
1221
- }
1222
- )
1223
- }
1224
- )
1225
- ]
1226
- }
1227
- )
1228
- ] }),
1229
- settingsTab === "subtitles-style" && /* @__PURE__ */ jsxs("div", { children: [
1230
- /* @__PURE__ */ jsxs(
1231
- "button",
1232
- {
1233
- type: "button",
1234
- onClick: () => setSettingsTab("subtitles"),
1235
- className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1236
- children: [
1237
- /* @__PURE__ */ jsx(
1238
- "svg",
1239
- {
1240
- className: "size-3.5",
1241
- viewBox: "0 0 12 12",
1242
- fill: "none",
1243
- children: /* @__PURE__ */ jsx(
1244
- "path",
1245
- {
1246
- d: "M7.5 3L4.5 6l3 3",
1247
- stroke: "currentColor",
1248
- strokeWidth: "1.5",
1249
- strokeLinecap: "round",
1250
- strokeLinejoin: "round"
1251
- }
1252
- )
1253
- }
1254
- ),
1255
- "Apar\xEAncia"
1256
- ]
1257
- }
1258
- ),
1259
- /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 flex flex-col gap-3", children: [
1260
- /* @__PURE__ */ jsxs("div", { children: [
1261
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Tamanho" }),
1262
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
1263
- "button",
1264
- {
1265
- type: "button",
1266
- onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
1267
- className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition${subtitleStyle.size === s ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
1268
- children: s === "small" ? "P" : s === "medium" ? "M" : s === "large" ? "G" : "GG"
1091
+ settingsTab === "quality" && /* @__PURE__ */ jsxs("div", { children: [
1092
+ /* @__PURE__ */ jsxs(
1093
+ "button",
1094
+ {
1095
+ type: "button",
1096
+ onClick: () => setSettingsTab("root"),
1097
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1098
+ children: [
1099
+ /* @__PURE__ */ jsx(
1100
+ "svg",
1101
+ {
1102
+ className: "size-3.5",
1103
+ viewBox: "0 0 12 12",
1104
+ fill: "none",
1105
+ children: /* @__PURE__ */ jsx(
1106
+ "path",
1107
+ {
1108
+ d: "M7.5 3L4.5 6l3 3",
1109
+ stroke: "currentColor",
1110
+ strokeWidth: "1.5",
1111
+ strokeLinecap: "round",
1112
+ strokeLinejoin: "round"
1113
+ }
1114
+ )
1115
+ }
1116
+ ),
1117
+ "Qualidade"
1118
+ ]
1119
+ }
1120
+ ),
1121
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(
1122
+ "button",
1123
+ {
1124
+ type: "button",
1125
+ onClick: () => {
1126
+ changeQuality(quality.id);
1127
+ setSettingsTab("root");
1269
1128
  },
1270
- s
1271
- )) })
1272
- ] }),
1273
- /* @__PURE__ */ jsxs("div", { children: [
1274
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Cor" }),
1275
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [
1276
- ["white", "Branco", "#fff"],
1277
- ["yellow", "Amarelo", "#facc15"],
1278
- ["cyan", "Ciano", "#22d3ee"]
1279
- ].map(([val, label, color]) => /* @__PURE__ */ jsx(
1280
- "button",
1281
- {
1282
- type: "button",
1283
- onClick: () => setSubtitleStyle((st) => ({
1129
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1130
+ children: [
1131
+ /* @__PURE__ */ jsx(
1132
+ "svg",
1133
+ {
1134
+ className: `size-4 shrink-0 ${selectedQuality === quality.id ? "text-white" : "text-transparent"}`,
1135
+ viewBox: "0 0 16 16",
1136
+ fill: "none",
1137
+ children: /* @__PURE__ */ jsx(
1138
+ "path",
1139
+ {
1140
+ d: "M3 8l3.5 3.5L13 4.5",
1141
+ stroke: "currentColor",
1142
+ strokeWidth: "1.8",
1143
+ strokeLinecap: "round",
1144
+ strokeLinejoin: "round"
1145
+ }
1146
+ )
1147
+ }
1148
+ ),
1149
+ /* @__PURE__ */ jsxs(
1150
+ "span",
1151
+ {
1152
+ className: selectedQuality === quality.id ? "font-semibold text-white" : "text-white/55",
1153
+ children: [
1154
+ quality.label,
1155
+ quality.id === "auto" ? " (ABR)" : ""
1156
+ ]
1157
+ }
1158
+ )
1159
+ ]
1160
+ },
1161
+ quality.id
1162
+ )) })
1163
+ ] }),
1164
+ settingsTab === "subtitles" && /* @__PURE__ */ jsxs("div", { children: [
1165
+ /* @__PURE__ */ jsxs(
1166
+ "button",
1167
+ {
1168
+ type: "button",
1169
+ onClick: () => setSettingsTab("root"),
1170
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1171
+ children: [
1172
+ /* @__PURE__ */ jsx(
1173
+ "svg",
1174
+ {
1175
+ className: "size-3.5",
1176
+ viewBox: "0 0 12 12",
1177
+ fill: "none",
1178
+ children: /* @__PURE__ */ jsx(
1179
+ "path",
1180
+ {
1181
+ d: "M7.5 3L4.5 6l3 3",
1182
+ stroke: "currentColor",
1183
+ strokeWidth: "1.5",
1184
+ strokeLinecap: "round",
1185
+ strokeLinejoin: "round"
1186
+ }
1187
+ )
1188
+ }
1189
+ ),
1190
+ "Legendas"
1191
+ ]
1192
+ }
1193
+ ),
1194
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [
1195
+ { srclang: "off", label: "Desligado" },
1196
+ ...captions
1197
+ ].map((s) => /* @__PURE__ */ jsxs(
1198
+ "button",
1199
+ {
1200
+ type: "button",
1201
+ onClick: () => {
1202
+ const next = s.srclang === "off" ? "off" : s.srclang;
1203
+ setSubtitleMode(next);
1204
+ setSubtitleStyle((st) => ({
1284
1205
  ...st,
1285
- color: val
1286
- })),
1287
- className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition ring-1${subtitleStyle.color === val ? "ring-white/40" : "ring-transparent hover:ring-white/15"}`,
1288
- style: { color },
1289
- children: label
1206
+ track: next
1207
+ }));
1290
1208
  },
1291
- val
1292
- )) })
1293
- ] }),
1294
- /* @__PURE__ */ jsxs("div", { children: [
1295
- /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Fundo" }),
1296
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [
1297
- ["none", "Nenhum"],
1298
- ["semi", "Semi"],
1299
- ["solid", "S\xF3lido"]
1300
- ].map(([val, label]) => /* @__PURE__ */ jsx(
1301
- "button",
1302
- {
1303
- type: "button",
1304
- onClick: () => setSubtitleStyle((st) => ({ ...st, bg: val })),
1305
- className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition${subtitleStyle.bg === val ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
1306
- children: label
1307
- },
1308
- val
1309
- )) })
1310
- ] })
1311
- ] })
1312
- ] }),
1313
- settingsTab === "audio" && /* @__PURE__ */ jsxs("div", { children: [
1314
- /* @__PURE__ */ jsxs(
1315
- "button",
1316
- {
1317
- type: "button",
1318
- onClick: () => setSettingsTab("root"),
1319
- className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1320
- children: [
1321
- /* @__PURE__ */ jsx(
1322
- "svg",
1323
- {
1324
- className: "size-3.5",
1325
- viewBox: "0 0 12 12",
1326
- fill: "none",
1327
- children: /* @__PURE__ */ jsx(
1328
- "path",
1329
- {
1330
- d: "M7.5 3L4.5 6l3 3",
1331
- stroke: "currentColor",
1332
- strokeWidth: "1.5",
1333
- strokeLinecap: "round",
1334
- strokeLinejoin: "round"
1335
- }
1336
- )
1337
- }
1338
- ),
1339
- "\xC1udio"
1340
- ]
1341
- }
1342
- ),
1343
- /* @__PURE__ */ jsx("div", { className: "py-1.5", children: audioTracks.map((track) => /* @__PURE__ */ jsxs(
1344
- "button",
1345
- {
1346
- type: "button",
1347
- onClick: () => {
1348
- changeAudio(track.id);
1349
- setSettingsTab("root");
1209
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1210
+ children: [
1211
+ /* @__PURE__ */ jsx(
1212
+ "svg",
1213
+ {
1214
+ className: `size-4 shrink-0 ${subtitleStyle.track === s.srclang ? "text-white" : "text-transparent"}`,
1215
+ viewBox: "0 0 16 16",
1216
+ fill: "none",
1217
+ children: /* @__PURE__ */ jsx(
1218
+ "path",
1219
+ {
1220
+ d: "M3 8l3.5 3.5L13 4.5",
1221
+ stroke: "currentColor",
1222
+ strokeWidth: "1.8",
1223
+ strokeLinecap: "round",
1224
+ strokeLinejoin: "round"
1225
+ }
1226
+ )
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ jsx(
1230
+ "span",
1231
+ {
1232
+ className: subtitleStyle.track === s.srclang ? "font-semibold text-white" : "text-white/55",
1233
+ children: s.label
1234
+ }
1235
+ )
1236
+ ]
1350
1237
  },
1351
- className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1352
- children: [
1353
- /* @__PURE__ */ jsx(
1354
- "svg",
1238
+ s.srclang
1239
+ )) }),
1240
+ subtitleStyle.track !== "off" && /* @__PURE__ */ jsxs(
1241
+ "button",
1242
+ {
1243
+ type: "button",
1244
+ onClick: () => setSettingsTab("subtitles-style"),
1245
+ className: "flex w-full items-center justify-between gap-3 border-t border-white/8 px-4 py-3 text-sm transition hover:bg-white/8",
1246
+ children: [
1247
+ /* @__PURE__ */ jsx("span", { className: "text-white/60", children: "Apar\xEAncia" }),
1248
+ /* @__PURE__ */ jsx(
1249
+ "svg",
1250
+ {
1251
+ className: "size-3 opacity-50",
1252
+ viewBox: "0 0 12 12",
1253
+ fill: "none",
1254
+ children: /* @__PURE__ */ jsx(
1255
+ "path",
1256
+ {
1257
+ d: "M4.5 3l3 3-3 3",
1258
+ stroke: "currentColor",
1259
+ strokeWidth: "1.5",
1260
+ strokeLinecap: "round",
1261
+ strokeLinejoin: "round"
1262
+ }
1263
+ )
1264
+ }
1265
+ )
1266
+ ]
1267
+ }
1268
+ )
1269
+ ] }),
1270
+ settingsTab === "subtitles-style" && /* @__PURE__ */ jsxs("div", { children: [
1271
+ /* @__PURE__ */ jsxs(
1272
+ "button",
1273
+ {
1274
+ type: "button",
1275
+ onClick: () => setSettingsTab("subtitles"),
1276
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1277
+ children: [
1278
+ /* @__PURE__ */ jsx(
1279
+ "svg",
1280
+ {
1281
+ className: "size-3.5",
1282
+ viewBox: "0 0 12 12",
1283
+ fill: "none",
1284
+ children: /* @__PURE__ */ jsx(
1285
+ "path",
1286
+ {
1287
+ d: "M7.5 3L4.5 6l3 3",
1288
+ stroke: "currentColor",
1289
+ strokeWidth: "1.5",
1290
+ strokeLinecap: "round",
1291
+ strokeLinejoin: "round"
1292
+ }
1293
+ )
1294
+ }
1295
+ ),
1296
+ "Apar\xEAncia"
1297
+ ]
1298
+ }
1299
+ ),
1300
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 flex flex-col gap-3", children: [
1301
+ /* @__PURE__ */ jsxs("div", { children: [
1302
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Tamanho" }),
1303
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
1304
+ "button",
1355
1305
  {
1356
- className: `size-4 shrink-0 ${selectedAudio === track.id ? "text-white" : "text-transparent"}`,
1357
- viewBox: "0 0 16 16",
1358
- fill: "none",
1359
- children: /* @__PURE__ */ jsx(
1360
- "path",
1361
- {
1362
- d: "M3 8l3.5 3.5L13 4.5",
1363
- stroke: "currentColor",
1364
- strokeWidth: "1.8",
1365
- strokeLinecap: "round",
1366
- strokeLinejoin: "round"
1367
- }
1368
- )
1369
- }
1370
- ),
1371
- /* @__PURE__ */ jsx(
1372
- "span",
1306
+ type: "button",
1307
+ onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
1308
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition${subtitleStyle.size === s ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
1309
+ children: s === "small" ? "P" : s === "medium" ? "M" : s === "large" ? "G" : "GG"
1310
+ },
1311
+ s
1312
+ )) })
1313
+ ] }),
1314
+ /* @__PURE__ */ jsxs("div", { children: [
1315
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Cor" }),
1316
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [
1317
+ ["white", "Branco", "#fff"],
1318
+ ["yellow", "Amarelo", "#facc15"],
1319
+ ["cyan", "Ciano", "#22d3ee"]
1320
+ ].map(([val, label, color]) => /* @__PURE__ */ jsx(
1321
+ "button",
1373
1322
  {
1374
- className: selectedAudio === track.id ? "font-semibold text-white" : "text-white/55",
1375
- children: track.label
1376
- }
1377
- )
1378
- ]
1379
- },
1380
- track.id
1381
- )) })
1382
- ] }),
1383
- settingsTab === "playback" && /* @__PURE__ */ jsxs("div", { children: [
1384
- /* @__PURE__ */ jsxs(
1385
- "button",
1386
- {
1387
- type: "button",
1388
- onClick: () => setSettingsTab("root"),
1389
- className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1390
- children: [
1391
- /* @__PURE__ */ jsx(
1392
- "svg",
1323
+ type: "button",
1324
+ onClick: () => setSubtitleStyle((st) => ({
1325
+ ...st,
1326
+ color: val
1327
+ })),
1328
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition ring-1${subtitleStyle.color === val ? "ring-white/40" : "ring-transparent hover:ring-white/15"}`,
1329
+ style: { color },
1330
+ children: label
1331
+ },
1332
+ val
1333
+ )) })
1334
+ ] }),
1335
+ /* @__PURE__ */ jsxs("div", { children: [
1336
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Fundo" }),
1337
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [
1338
+ ["none", "Nenhum"],
1339
+ ["semi", "Semi"],
1340
+ ["solid", "S\xF3lido"]
1341
+ ].map(([val, label]) => /* @__PURE__ */ jsx(
1342
+ "button",
1393
1343
  {
1394
- className: "size-3.5",
1395
- viewBox: "0 0 12 12",
1396
- fill: "none",
1397
- children: /* @__PURE__ */ jsx(
1398
- "path",
1399
- {
1400
- d: "M7.5 3L4.5 6l3 3",
1401
- stroke: "currentColor",
1402
- strokeWidth: "1.5",
1403
- strokeLinecap: "round",
1404
- strokeLinejoin: "round"
1405
- }
1406
- )
1407
- }
1408
- ),
1409
- "Velocidade"
1410
- ]
1344
+ type: "button",
1345
+ onClick: () => setSubtitleStyle((st) => ({ ...st, bg: val })),
1346
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition${subtitleStyle.bg === val ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
1347
+ children: label
1348
+ },
1349
+ val
1350
+ )) })
1351
+ ] })
1352
+ ] })
1353
+ ] }),
1354
+ settingsTab === "audio" && /* @__PURE__ */ jsxs("div", { children: [
1355
+ /* @__PURE__ */ jsxs(
1356
+ "button",
1357
+ {
1358
+ type: "button",
1359
+ onClick: () => setSettingsTab("root"),
1360
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1361
+ children: [
1362
+ /* @__PURE__ */ jsx(
1363
+ "svg",
1364
+ {
1365
+ className: "size-3.5",
1366
+ viewBox: "0 0 12 12",
1367
+ fill: "none",
1368
+ children: /* @__PURE__ */ jsx(
1369
+ "path",
1370
+ {
1371
+ d: "M7.5 3L4.5 6l3 3",
1372
+ stroke: "currentColor",
1373
+ strokeWidth: "1.5",
1374
+ strokeLinecap: "round",
1375
+ strokeLinejoin: "round"
1376
+ }
1377
+ )
1378
+ }
1379
+ ),
1380
+ "\xC1udio"
1381
+ ]
1382
+ }
1383
+ ),
1384
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: audioTracks.map((track) => /* @__PURE__ */ jsxs(
1385
+ "button",
1386
+ {
1387
+ type: "button",
1388
+ onClick: () => {
1389
+ changeAudio(track.id);
1390
+ setSettingsTab("root");
1391
+ },
1392
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1393
+ children: [
1394
+ /* @__PURE__ */ jsx(
1395
+ "svg",
1396
+ {
1397
+ className: `size-4 shrink-0 ${selectedAudio === track.id ? "text-white" : "text-transparent"}`,
1398
+ viewBox: "0 0 16 16",
1399
+ fill: "none",
1400
+ children: /* @__PURE__ */ jsx(
1401
+ "path",
1402
+ {
1403
+ d: "M3 8l3.5 3.5L13 4.5",
1404
+ stroke: "currentColor",
1405
+ strokeWidth: "1.8",
1406
+ strokeLinecap: "round",
1407
+ strokeLinejoin: "round"
1408
+ }
1409
+ )
1410
+ }
1411
+ ),
1412
+ /* @__PURE__ */ jsx(
1413
+ "span",
1414
+ {
1415
+ className: selectedAudio === track.id ? "font-semibold text-white" : "text-white/55",
1416
+ children: track.label
1417
+ }
1418
+ )
1419
+ ]
1420
+ },
1421
+ track.id
1422
+ )) })
1423
+ ] }),
1424
+ settingsTab === "playback" && /* @__PURE__ */ jsxs("div", { children: [
1425
+ /* @__PURE__ */ jsxs(
1426
+ "button",
1427
+ {
1428
+ type: "button",
1429
+ onClick: () => setSettingsTab("root"),
1430
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
1431
+ children: [
1432
+ /* @__PURE__ */ jsx(
1433
+ "svg",
1434
+ {
1435
+ className: "size-3.5",
1436
+ viewBox: "0 0 12 12",
1437
+ fill: "none",
1438
+ children: /* @__PURE__ */ jsx(
1439
+ "path",
1440
+ {
1441
+ d: "M7.5 3L4.5 6l3 3",
1442
+ stroke: "currentColor",
1443
+ strokeWidth: "1.5",
1444
+ strokeLinecap: "round",
1445
+ strokeLinejoin: "round"
1446
+ }
1447
+ )
1448
+ }
1449
+ ),
1450
+ "Velocidade"
1451
+ ]
1452
+ }
1453
+ ),
1454
+ /* @__PURE__ */ jsx("div", { className: "py-1.5", children: PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsxs(
1455
+ "button",
1456
+ {
1457
+ type: "button",
1458
+ onClick: () => {
1459
+ setPlaybackRate(speed);
1460
+ closeSettings();
1461
+ },
1462
+ className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1463
+ children: [
1464
+ /* @__PURE__ */ jsx(
1465
+ "svg",
1466
+ {
1467
+ className: `size-4 shrink-0 ${playbackRate === speed ? "text-white" : "text-transparent"}`,
1468
+ viewBox: "0 0 16 16",
1469
+ fill: "none",
1470
+ children: /* @__PURE__ */ jsx(
1471
+ "path",
1472
+ {
1473
+ d: "M3 8l3.5 3.5L13 4.5",
1474
+ stroke: "currentColor",
1475
+ strokeWidth: "1.8",
1476
+ strokeLinecap: "round",
1477
+ strokeLinejoin: "round"
1478
+ }
1479
+ )
1480
+ }
1481
+ ),
1482
+ /* @__PURE__ */ jsx(
1483
+ "span",
1484
+ {
1485
+ className: playbackRate === speed ? "font-semibold text-white" : "text-white/55",
1486
+ children: speed === 1 ? "Normal" : `${speed}\xD7`
1487
+ }
1488
+ )
1489
+ ]
1490
+ },
1491
+ speed
1492
+ )) })
1493
+ ] })
1494
+ ]
1495
+ }
1496
+ )
1497
+ ] }),
1498
+ /* @__PURE__ */ jsxs(
1499
+ "div",
1500
+ {
1501
+ ref: progressRef,
1502
+ onPointerMove: handleProgressPointerMove,
1503
+ onPointerEnter: handleProgressPointerEnter,
1504
+ onPointerLeave: handleProgressPointerLeave,
1505
+ onPointerDown: handleProgressPointerDown,
1506
+ onPointerUp: handleProgressPointerUp,
1507
+ className: "relative mb-2 h-8 cursor-pointer overflow-visible",
1508
+ children: [
1509
+ /* @__PURE__ */ jsxs(
1510
+ "div",
1511
+ {
1512
+ className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/18",
1513
+ style: {
1514
+ height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px",
1515
+ transition: "height 0.15s ease"
1516
+ },
1517
+ children: [
1518
+ /* @__PURE__ */ jsx(
1519
+ "div",
1520
+ {
1521
+ className: "absolute inset-y-0 left-0 rounded-full bg-white/28",
1522
+ style: { width: `${bufferedPercent}%` }
1523
+ }
1524
+ ),
1525
+ /* @__PURE__ */ jsx(
1526
+ "div",
1527
+ {
1528
+ className: "absolute inset-y-0 left-0 rounded-full bg-white",
1529
+ style: { width: `${progressPercent}%`, transition: "width 0.05s linear" }
1530
+ }
1531
+ )
1532
+ ]
1533
+ }
1534
+ ),
1535
+ /* @__PURE__ */ jsx(
1536
+ "div",
1537
+ {
1538
+ className: "pointer-events-none absolute rounded-full bg-white shadow-[0_1px_6px_rgba(0,0,0,0.5)]",
1539
+ style: {
1540
+ top: "50%",
1541
+ left: `${progressPercent}%`,
1542
+ transform: "translate(-50%, -50%)",
1543
+ width: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1544
+ height: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1545
+ transition: "width 0.2s cubic-bezier(0.34,1.56,0.64,1), height 0.2s cubic-bezier(0.34,1.56,0.64,1)"
1411
1546
  }
1412
- ),
1413
- /* @__PURE__ */ jsx("div", { className: "py-1.5", children: PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsxs(
1414
- "button",
1547
+ }
1548
+ ),
1549
+ chapters.length > 0 && duration > 0 && chapters.map((ch, i) => /* @__PURE__ */ jsx(
1550
+ "div",
1551
+ {
1552
+ className: "pointer-events-none absolute top-1/2 -translate-y-1/2 w-0.5 rounded-full bg-white/50",
1553
+ style: { left: `${ch.startTime / duration * 100}%`, height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px", transition: "height 0.15s ease" }
1554
+ },
1555
+ i
1556
+ )),
1557
+ preview && (() => {
1558
+ const frameW = preview.cue.w ?? 160;
1559
+ const frameH = preview.cue.h ?? 90;
1560
+ const thumbW = 200;
1561
+ const thumbH = Math.round(thumbW * (frameH / frameW));
1562
+ const scale = thumbW / frameW;
1563
+ const isSprite = preview.cue.x != null && preview.cue.y != null;
1564
+ return /* @__PURE__ */ jsxs(
1565
+ "div",
1415
1566
  {
1416
- type: "button",
1417
- onClick: () => {
1418
- setPlaybackRate(speed);
1419
- closeSettings();
1567
+ className: "pointer-events-none absolute flex flex-col items-center gap-1",
1568
+ style: {
1569
+ bottom: "calc(100% + 6px)",
1570
+ left: preview.left,
1571
+ transform: "translateX(-50%)",
1572
+ zIndex: 80
1420
1573
  },
1421
- className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1422
1574
  children: [
1423
1575
  /* @__PURE__ */ jsx(
1424
- "svg",
1576
+ "div",
1425
1577
  {
1426
- className: `size-4 shrink-0 ${playbackRate === speed ? "text-white" : "text-transparent"}`,
1427
- viewBox: "0 0 16 16",
1428
- fill: "none",
1429
- children: /* @__PURE__ */ jsx(
1430
- "path",
1578
+ className: "overflow-hidden rounded-lg shadow-2xl ring-1 ring-white/20",
1579
+ style: { width: thumbW, height: thumbH, flexShrink: 0 },
1580
+ children: isSprite ? (
1581
+ // Sprite: need full sheet dimensions to compute backgroundSize correctly.
1582
+ // Load them once from the image's natural size.
1583
+ (() => {
1584
+ const imgUrl = preview.cue.image;
1585
+ if (storyboardSheetUrlRef.current !== imgUrl) {
1586
+ storyboardSheetUrlRef.current = imgUrl;
1587
+ const img = new window.Image();
1588
+ img.onload = () => setStoryboardSheetSize({ w: img.naturalWidth, h: img.naturalHeight });
1589
+ img.src = imgUrl;
1590
+ }
1591
+ if (!storyboardSheetSize) return null;
1592
+ const bsW = storyboardSheetSize.w * scale;
1593
+ const bsH = storyboardSheetSize.h * scale;
1594
+ return /* @__PURE__ */ jsx(
1595
+ "div",
1596
+ {
1597
+ style: {
1598
+ width: thumbW,
1599
+ height: thumbH,
1600
+ backgroundImage: `url(${imgUrl})`,
1601
+ backgroundRepeat: "no-repeat",
1602
+ backgroundPosition: `-${(preview.cue.x ?? 0) * scale}px -${(preview.cue.y ?? 0) * scale}px`,
1603
+ backgroundSize: `${bsW}px ${bsH}px`
1604
+ }
1605
+ }
1606
+ );
1607
+ })()
1608
+ ) : /* @__PURE__ */ jsx(
1609
+ "img",
1431
1610
  {
1432
- d: "M3 8l3.5 3.5L13 4.5",
1433
- stroke: "currentColor",
1434
- strokeWidth: "1.8",
1435
- strokeLinecap: "round",
1436
- strokeLinejoin: "round"
1611
+ src: preview.cue.image,
1612
+ alt: "",
1613
+ style: { width: thumbW, height: thumbH, objectFit: "cover", objectPosition: "center", display: "block" }
1437
1614
  }
1438
1615
  )
1439
1616
  }
@@ -1441,262 +1618,160 @@ function Video({
1441
1618
  /* @__PURE__ */ jsx(
1442
1619
  "span",
1443
1620
  {
1444
- className: playbackRate === speed ? "font-semibold text-white" : "text-white/55",
1445
- children: speed === 1 ? "Normal" : `${speed}\xD7`
1621
+ className: "rounded-md px-2 py-0.5 text-[11px] font-semibold tabular-nums text-white/90",
1622
+ style: { background: "rgba(0,0,0,0.55)", backdropFilter: "blur(6px)" },
1623
+ children: formatTime(preview.time)
1446
1624
  }
1447
1625
  )
1448
1626
  ]
1449
- },
1450
- speed
1451
- )) })
1452
- ] })
1627
+ }
1628
+ );
1629
+ })()
1453
1630
  ]
1454
1631
  }
1455
- )
1456
- ] }),
1457
- /* @__PURE__ */ jsxs(
1458
- "div",
1459
- {
1460
- ref: progressRef,
1461
- onPointerMove: handleProgressPointerMove,
1462
- onPointerEnter: handleProgressPointerEnter,
1463
- onPointerLeave: handleProgressPointerLeave,
1464
- onPointerDown: handleProgressPointerDown,
1465
- onPointerUp: handleProgressPointerUp,
1466
- className: "relative mb-2 h-8 cursor-pointer overflow-visible",
1467
- children: [
1468
- /* @__PURE__ */ jsxs(
1469
- "div",
1632
+ ),
1633
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1634
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 @sm:gap-2", children: [
1635
+ /* @__PURE__ */ jsx(
1636
+ "button",
1470
1637
  {
1471
- className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/18",
1472
- style: {
1473
- height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px",
1474
- transition: "height 0.15s ease"
1475
- },
1476
- children: [
1477
- /* @__PURE__ */ jsx(
1478
- "div",
1479
- {
1480
- className: "absolute inset-y-0 left-0 rounded-full bg-white/28",
1481
- style: { width: `${bufferedPercent}%` }
1482
- }
1483
- ),
1484
- /* @__PURE__ */ jsx(
1485
- "div",
1486
- {
1487
- className: "absolute inset-y-0 left-0 rounded-full bg-white",
1488
- style: { width: `${progressPercent}%`, transition: "width 0.05s linear" }
1489
- }
1490
- )
1491
- ]
1638
+ type: "button",
1639
+ onClick: togglePlay,
1640
+ className: "grid size-8 place-items-center rounded-full text-white transition hover:bg-white/10 @sm:size-9",
1641
+ "aria-label": isPlaying ? "Pause" : "Play",
1642
+ children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-5", fill: "white" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-5", fill: "white" })
1492
1643
  }
1493
1644
  ),
1645
+ /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium tabular-nums text-white/80", children: [
1646
+ formatTime(currentTime),
1647
+ /* @__PURE__ */ jsx("span", { className: "text-white/30", children: "/" }),
1648
+ /* @__PURE__ */ jsx("span", { className: "text-white/45", children: formatTime(duration) })
1649
+ ] }),
1650
+ (() => {
1651
+ if (chapters.length === 0) return null;
1652
+ const ch = [...chapters].reverse().find((c) => currentTime >= c.startTime);
1653
+ return ch ? /* @__PURE__ */ jsx("span", { className: "hidden max-w-40 truncate text-[11px] text-white/50 @sm:block", children: ch.title }) : null;
1654
+ })()
1655
+ ] }),
1656
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
1657
+ parsed.rating && (() => {
1658
+ const r = parsed.rating;
1659
+ const reactions = [
1660
+ { key: "LOVE", emoji: "\u2764\uFE0F" },
1661
+ { key: "LIKE", emoji: "\u{1F44D}" },
1662
+ { key: "DISLIKE", emoji: "\u{1F44E}" }
1663
+ ];
1664
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1665
+ reactions.map(({ key, emoji }) => {
1666
+ const count = r.counts?.[key] ?? 0;
1667
+ const active = r.userReaction === key;
1668
+ return /* @__PURE__ */ jsxs(
1669
+ "button",
1670
+ {
1671
+ type: "button",
1672
+ onClick: (e) => {
1673
+ e.stopPropagation();
1674
+ r.onReact?.(active ? null : key);
1675
+ },
1676
+ className: `flex items-center gap-0.5 rounded px-1.5 py-1 text-[11px] transition hover:bg-white/10 ${active ? "opacity-100" : "opacity-50 hover:opacity-80"}`,
1677
+ "aria-label": key.toLowerCase(),
1678
+ "aria-pressed": active,
1679
+ children: [
1680
+ /* @__PURE__ */ jsx("span", { children: emoji }),
1681
+ count > 0 && /* @__PURE__ */ jsx("span", { className: "text-white/70 tabular-nums", children: count })
1682
+ ]
1683
+ },
1684
+ key
1685
+ );
1686
+ }),
1687
+ /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" })
1688
+ ] });
1689
+ })(),
1494
1690
  /* @__PURE__ */ jsx(
1495
- "div",
1691
+ VolumeSlider,
1496
1692
  {
1497
- className: "pointer-events-none absolute rounded-full bg-white shadow-[0_1px_6px_rgba(0,0,0,0.5)]",
1498
- style: {
1499
- top: "50%",
1500
- left: `${progressPercent}%`,
1501
- transform: "translate(-50%, -50%)",
1502
- width: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1503
- height: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1504
- transition: "width 0.2s cubic-bezier(0.34,1.56,0.64,1), height 0.2s cubic-bezier(0.34,1.56,0.64,1)"
1505
- }
1693
+ volume: isMuted ? 0 : volume,
1694
+ onMuteToggle: () => setIsMuted((v) => !v),
1695
+ onVolumeChange: (v) => {
1696
+ setVolume(v);
1697
+ setIsMuted(v === 0);
1698
+ },
1699
+ isMuted
1506
1700
  }
1507
1701
  ),
1508
- chapters.length > 0 && duration > 0 && chapters.map((ch, i) => /* @__PURE__ */ jsx(
1509
- "div",
1702
+ /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1703
+ captions.length > 0 && /* @__PURE__ */ jsx(
1704
+ "button",
1510
1705
  {
1511
- className: "pointer-events-none absolute top-1/2 -translate-y-1/2 w-0.5 rounded-full bg-white/50",
1512
- style: { left: `${ch.startTime / duration * 100}%`, height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px", transition: "height 0.15s ease" }
1513
- },
1514
- i
1515
- )),
1516
- preview && (() => {
1517
- const frameW = preview.cue.w ?? 160;
1518
- const frameH = preview.cue.h ?? 90;
1519
- const thumbW = 200;
1520
- const thumbH = Math.round(thumbW * (frameH / frameW));
1521
- const scale = thumbW / frameW;
1522
- const isSprite = preview.cue.x != null && preview.cue.y != null;
1523
- return /* @__PURE__ */ jsxs(
1524
- "div",
1525
- {
1526
- className: "pointer-events-none absolute flex flex-col items-center gap-1",
1527
- style: {
1528
- bottom: "calc(100% + 6px)",
1529
- left: preview.left,
1530
- transform: "translateX(-50%)",
1531
- zIndex: 80
1532
- },
1533
- children: [
1534
- /* @__PURE__ */ jsx(
1535
- "div",
1536
- {
1537
- className: "overflow-hidden rounded-lg shadow-2xl ring-1 ring-white/20",
1538
- style: { width: thumbW, height: thumbH, flexShrink: 0 },
1539
- children: isSprite ? (
1540
- // Sprite: need full sheet dimensions to compute backgroundSize correctly.
1541
- // Load them once from the image's natural size.
1542
- (() => {
1543
- const imgUrl = preview.cue.image;
1544
- if (storyboardSheetUrlRef.current !== imgUrl) {
1545
- storyboardSheetUrlRef.current = imgUrl;
1546
- const img = new window.Image();
1547
- img.onload = () => setStoryboardSheetSize({ w: img.naturalWidth, h: img.naturalHeight });
1548
- img.src = imgUrl;
1549
- }
1550
- if (!storyboardSheetSize) return null;
1551
- const bsW = storyboardSheetSize.w * scale;
1552
- const bsH = storyboardSheetSize.h * scale;
1553
- return /* @__PURE__ */ jsx(
1554
- "div",
1555
- {
1556
- style: {
1557
- width: thumbW,
1558
- height: thumbH,
1559
- backgroundImage: `url(${imgUrl})`,
1560
- backgroundRepeat: "no-repeat",
1561
- backgroundPosition: `-${(preview.cue.x ?? 0) * scale}px -${(preview.cue.y ?? 0) * scale}px`,
1562
- backgroundSize: `${bsW}px ${bsH}px`
1563
- }
1564
- }
1565
- );
1566
- })()
1567
- ) : /* @__PURE__ */ jsx(
1568
- "img",
1569
- {
1570
- src: preview.cue.image,
1571
- alt: "",
1572
- style: { width: thumbW, height: thumbH, objectFit: "cover", objectPosition: "center", display: "block" }
1573
- }
1574
- )
1575
- }
1576
- ),
1577
- /* @__PURE__ */ jsx(
1578
- "span",
1579
- {
1580
- className: "rounded-md px-2 py-0.5 text-[11px] font-semibold tabular-nums text-white/90",
1581
- style: { background: "rgba(0,0,0,0.55)", backdropFilter: "blur(6px)" },
1582
- children: formatTime(preview.time)
1583
- }
1584
- )
1585
- ]
1586
- }
1587
- );
1588
- })()
1589
- ]
1590
- }
1591
- ),
1592
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1593
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 @sm:gap-2", children: [
1594
- /* @__PURE__ */ jsx(
1595
- "button",
1596
- {
1597
- type: "button",
1598
- onClick: togglePlay,
1599
- className: "grid size-8 place-items-center rounded-full text-white transition hover:bg-white/10 @sm:size-9",
1600
- "aria-label": isPlaying ? "Pause" : "Play",
1601
- children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-5", fill: "white" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-5", fill: "white" })
1602
- }
1603
- ),
1604
- /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium tabular-nums text-white/80", children: [
1605
- formatTime(currentTime),
1606
- /* @__PURE__ */ jsx("span", { className: "text-white/30", children: "/" }),
1607
- /* @__PURE__ */ jsx("span", { className: "text-white/45", children: formatTime(duration) })
1608
- ] }),
1609
- (() => {
1610
- if (chapters.length === 0) return null;
1611
- const ch = [...chapters].reverse().find((c) => currentTime >= c.startTime);
1612
- return ch ? /* @__PURE__ */ jsx("span", { className: "hidden max-w-40 truncate text-[11px] text-white/50 @sm:block", children: ch.title }) : null;
1613
- })()
1614
- ] }),
1615
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
1616
- /* @__PURE__ */ jsx(
1617
- VolumeSlider,
1618
- {
1619
- volume: isMuted ? 0 : volume,
1620
- onMuteToggle: () => setIsMuted((v) => !v),
1621
- onVolumeChange: (v) => {
1622
- setVolume(v);
1623
- setIsMuted(v === 0);
1624
- },
1625
- isMuted
1626
- }
1627
- ),
1628
- /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1629
- captions.length > 0 && /* @__PURE__ */ jsx(
1630
- "button",
1631
- {
1632
- type: "button",
1633
- onClick: () => {
1634
- const next = subtitleMode === "off" ? captions[0]?.srclang ?? "off" : "off";
1635
- setSubtitleMode(next);
1636
- setSubtitleStyle((st) => ({ ...st, track: next }));
1637
- },
1638
- className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1639
- "aria-label": "Captions",
1640
- children: /* @__PURE__ */ jsx(Captions$1, { className: "size-4 @sm:size-5" })
1641
- }
1642
- ),
1643
- /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
1644
- "button",
1645
- {
1646
- type: "button",
1647
- onClick: () => settingsOpen ? closeSettings() : openSettings(),
1648
- className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${settingsOpen ? "text-white" : "text-white/60"}`,
1649
- "aria-label": "Settings",
1650
- children: /* @__PURE__ */ jsx(Settings, { className: "size-4 @sm:size-5" })
1651
- }
1652
- ) }),
1653
- /* @__PURE__ */ jsx(
1654
- "button",
1655
- {
1656
- type: "button",
1657
- onClick: toggleFullscreen,
1658
- className: "grid size-8 place-items-center text-white/60 transition hover:scale-110 hover:text-white/80 @sm:size-10",
1659
- "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
1660
- children: isFullscreen ? /* @__PURE__ */ jsx(Minimize, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Maximize, { className: "size-4 @sm:size-5" })
1661
- }
1662
- )
1706
+ type: "button",
1707
+ onClick: () => {
1708
+ const next = subtitleMode === "off" ? captions[0]?.srclang ?? "off" : "off";
1709
+ setSubtitleMode(next);
1710
+ setSubtitleStyle((st) => ({ ...st, track: next }));
1711
+ },
1712
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1713
+ "aria-label": "Captions",
1714
+ children: /* @__PURE__ */ jsx(Captions$1, { className: "size-4 @sm:size-5" })
1715
+ }
1716
+ ),
1717
+ /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
1718
+ "button",
1719
+ {
1720
+ type: "button",
1721
+ onClick: () => settingsOpen ? closeSettings() : openSettings(),
1722
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${settingsOpen ? "text-white" : "text-white/60"}`,
1723
+ "aria-label": "Settings",
1724
+ children: /* @__PURE__ */ jsx(Settings, { className: "size-4 @sm:size-5" })
1725
+ }
1726
+ ) }),
1727
+ /* @__PURE__ */ jsx(
1728
+ "button",
1729
+ {
1730
+ type: "button",
1731
+ onClick: toggleFullscreen,
1732
+ className: "grid size-8 place-items-center text-white/60 transition hover:scale-110 hover:text-white/80 @sm:size-10",
1733
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
1734
+ children: isFullscreen ? /* @__PURE__ */ jsx(Minimize, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Maximize, { className: "size-4 @sm:size-5" })
1735
+ }
1736
+ )
1737
+ ] })
1663
1738
  ] })
1664
- ] })
1665
- ]
1739
+ ]
1740
+ }
1741
+ )
1742
+ ]
1743
+ }
1744
+ ),
1745
+ activeCue && /* @__PURE__ */ jsx(
1746
+ "div",
1747
+ {
1748
+ className: `pointer-events-none absolute inset-x-0 z-40 flex justify-center px-4 transition-all duration-200${controlsVisible ? "bottom-20 @sm:bottom-24 @lg:bottom-28" : "bottom-4 @sm:bottom-6"}`,
1749
+ children: /* @__PURE__ */ jsx(
1750
+ "div",
1751
+ {
1752
+ className: "max-w-[80%] rounded-lg px-4 py-1.5 text-center font-medium leading-snug",
1753
+ style: {
1754
+ fontSize: (() => {
1755
+ const base = Math.max(12, Math.min(playerHeight * 0.028, 32));
1756
+ if (subtitleStyle.size === "small") return `${base * 0.75}px`;
1757
+ if (subtitleStyle.size === "large") return `${base * 1.35}px`;
1758
+ if (subtitleStyle.size === "xlarge") return `${base * 1.8}px`;
1759
+ return `${base}px`;
1760
+ })(),
1761
+ color: subtitleStyle.color === "yellow" ? "#facc15" : subtitleStyle.color === "cyan" ? "#22d3ee" : "#ffffff",
1762
+ backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.55)",
1763
+ backdropFilter: subtitleStyle.bg === "semi" ? "blur(6px)" : void 0,
1764
+ textShadow: subtitleStyle.bg === "none" ? "0 1px 8px rgba(0,0,0,1), 0 0 16px rgba(0,0,0,0.9)" : "0 1px 3px rgba(0,0,0,0.5)"
1765
+ },
1766
+ children: activeCue
1666
1767
  }
1667
1768
  )
1668
- ]
1669
- }
1670
- ),
1671
- activeCue && /* @__PURE__ */ jsx(
1672
- "div",
1673
- {
1674
- className: `pointer-events-none absolute inset-x-0 z-40 flex justify-center px-4 transition-all duration-200${controlsVisible ? "bottom-20 @sm:bottom-24 @lg:bottom-28" : "bottom-4 @sm:bottom-6"}`,
1675
- children: /* @__PURE__ */ jsx(
1676
- "div",
1677
- {
1678
- className: "max-w-[80%] rounded-lg px-4 py-1.5 text-center font-medium leading-snug",
1679
- style: {
1680
- fontSize: (() => {
1681
- const base = Math.max(12, Math.min(playerHeight * 0.028, 32));
1682
- if (subtitleStyle.size === "small") return `${base * 0.75}px`;
1683
- if (subtitleStyle.size === "large") return `${base * 1.35}px`;
1684
- if (subtitleStyle.size === "xlarge") return `${base * 1.8}px`;
1685
- return `${base}px`;
1686
- })(),
1687
- color: subtitleStyle.color === "yellow" ? "#facc15" : subtitleStyle.color === "cyan" ? "#22d3ee" : "#ffffff",
1688
- backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.55)",
1689
- backdropFilter: subtitleStyle.bg === "semi" ? "blur(6px)" : void 0,
1690
- textShadow: subtitleStyle.bg === "none" ? "0 1px 8px rgba(0,0,0,1), 0 0 16px rgba(0,0,0,0.9)" : "0 1px 3px rgba(0,0,0,0.5)"
1691
- },
1692
- children: activeCue
1693
- }
1694
- )
1695
- }
1696
- )
1697
- ]
1698
- }
1699
- )
1769
+ }
1770
+ )
1771
+ ]
1772
+ }
1773
+ )
1774
+ ]
1700
1775
  }
1701
1776
  );
1702
1777
  }
@@ -1804,6 +1879,34 @@ function VolumeSlider({
1804
1879
  }
1805
1880
  );
1806
1881
  }
1882
+ var LOCALE_TO_REGION = {
1883
+ "en-US": "US",
1884
+ "en-CA": "CA",
1885
+ "pt-BR": "BR",
1886
+ "de": "EU",
1887
+ "fr": "EU",
1888
+ "es": "EU",
1889
+ "it": "EU",
1890
+ "nl": "EU",
1891
+ "pl": "EU",
1892
+ "de-DE": "EU",
1893
+ "fr-FR": "EU",
1894
+ "es-ES": "EU",
1895
+ "it-IT": "EU",
1896
+ "ja": "JP",
1897
+ "ja-JP": "JP",
1898
+ "ko": "KR",
1899
+ "ko-KR": "KR",
1900
+ "en-AU": "AU"
1901
+ };
1902
+ function resolveAgeRatingRegion(locale, data) {
1903
+ if (!locale) return Object.keys(data)[0];
1904
+ if (LOCALE_TO_REGION[locale] && data[LOCALE_TO_REGION[locale]]) return LOCALE_TO_REGION[locale];
1905
+ const lang = locale.split("-")[0] ?? "";
1906
+ const fromLang = LOCALE_TO_REGION[lang];
1907
+ if (fromLang && data[fromLang]) return fromLang;
1908
+ return Object.keys(data)[0];
1909
+ }
1807
1910
  function parseVideoChildren(children) {
1808
1911
  const parsed = {
1809
1912
  sources: []
@@ -1838,6 +1941,14 @@ function parseVideoChildren(children) {
1838
1941
  const element = child;
1839
1942
  parsed.thumbnailSrc = element.props.src;
1840
1943
  }
1944
+ if (child.type === AgeRating || name === "SiloAgeRating") {
1945
+ const element = child;
1946
+ parsed.ageRating = element.props;
1947
+ }
1948
+ if (child.type === Rating || name === "SiloRating") {
1949
+ const element = child;
1950
+ parsed.rating = element.props;
1951
+ }
1841
1952
  if (child.type === Storyboard || name === "SiloStoryboard") {
1842
1953
  const element = child;
1843
1954
  const frames = [];
@@ -1942,6 +2053,6 @@ function formatTime(seconds) {
1942
2053
  return `${minutes}:${String(secs).padStart(2, "0")}`;
1943
2054
  }
1944
2055
 
1945
- export { Captions, Chapters, Source, Storyboard, StoryboardFrame, Video, VideoPlayer, VideoThumbnail };
2056
+ export { AgeRating, Captions, Chapters, Rating, Source, Storyboard, StoryboardFrame, Video, VideoPlayer, VideoThumbnail };
1946
2057
  //# sourceMappingURL=VideoPlayer.js.map
1947
2058
  //# sourceMappingURL=VideoPlayer.js.map