@xipkg/calls-compactview 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +73 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -14
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import '@xipkg/calls-ui/grid.css';
|
|
1
2
|
import { createContext, useMemo, useState, useEffect, useRef, useCallback, useContext } from 'react';
|
|
2
3
|
import { useDraggable, useSensors, useSensor, PointerSensor, DndContext, useDndMonitor, DragOverlay, useDroppable } from '@dnd-kit/core';
|
|
3
4
|
import { useRoom, useCallsNavigation, useCalls } from '@xipkg/calls-providers';
|
|
@@ -9,7 +10,7 @@ import { useCallStore } from '@xipkg/calls-store';
|
|
|
9
10
|
import { useScreenShareCleanup, useSortedTracks, useVideoBlur, useModeSync, useParticipantJoinSync, useParticipantSounds } from '@xipkg/calls-hooks';
|
|
10
11
|
import { useMedia } from '@xipkg/calls-utils';
|
|
11
12
|
import { Button } from '@xipkg/button';
|
|
12
|
-
import { ArrowLeft, ArrowRight,
|
|
13
|
+
import { ArrowLeft, ArrowRight, Account, SoundTwo, Users, External, ChevronUp, WhiteBoard, Maximize, MicrophoneOff, RedLine, ChevronBottom, ArrowUp } from '@xipkg/icons';
|
|
13
14
|
import { cn } from '@xipkg/utils';
|
|
14
15
|
import { createPortal } from 'react-dom';
|
|
15
16
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -19,13 +20,16 @@ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLab
|
|
|
19
20
|
import { ChatButton, useChatStore, Chat } from '@xipkg/calls-chat';
|
|
20
21
|
import { RaiseHandButton } from '@xipkg/calls-risehand';
|
|
21
22
|
|
|
22
|
-
//
|
|
23
|
+
// index.ts
|
|
23
24
|
|
|
24
25
|
// src/constants.ts
|
|
25
26
|
var HEADER_HEIGHT_PX = 64;
|
|
27
|
+
var COMPACT_MOBILE_CONTENT_GAP_PX = 12;
|
|
28
|
+
var COMPACT_MOBILE_OVERLAY_FALLBACK_PX = 120;
|
|
26
29
|
var BOARD_BOTTOM_TOOLBAR_PX = 64;
|
|
27
30
|
var BOTTOM_OFFSET_DEFAULT_PX = 16;
|
|
28
31
|
var COMPACT_BOTTOM_BAR_PX = 40;
|
|
32
|
+
var COMPACT_AUDIO_BAR_HEIGHT_PX = 48;
|
|
29
33
|
var TILE_GAP_PX = 8;
|
|
30
34
|
var EXPANDED_VIDEO_PADDING_VERTICAL_PX = 8;
|
|
31
35
|
var COMPACT_VIDEO_AREA_MARGIN_PX = 8;
|
|
@@ -41,6 +45,17 @@ var PIP_TILE_HEIGHT_16_9_PX = Math.round(PIP_PANEL_WIDTH_PX * 9 / 16);
|
|
|
41
45
|
var PIP_EXTRA_HEIGHT_PX = 36;
|
|
42
46
|
var PIP_EXTRA_HEIGHT_EXPANDED_PX = 12;
|
|
43
47
|
var PIP_HEIGHT_BASIC_PX = PIP_BAR_HEIGHT_PX + PIP_TILE_HEIGHT_16_9_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX;
|
|
48
|
+
var PIP_HEIGHT_AUDIO_PX = PIP_BAR_HEIGHT_PX + COMPACT_AUDIO_BAR_HEIGHT_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX;
|
|
49
|
+
var COMPACT_VIEW_MODES = ["basic", "expanded", "audio"];
|
|
50
|
+
function getNextCompactViewMode(current) {
|
|
51
|
+
const index = COMPACT_VIEW_MODES.indexOf(current);
|
|
52
|
+
return COMPACT_VIEW_MODES[(index + 1) % COMPACT_VIEW_MODES.length];
|
|
53
|
+
}
|
|
54
|
+
function getPipHeightForMode(mode, participantCount) {
|
|
55
|
+
if (mode === "audio") return PIP_HEIGHT_AUDIO_PX;
|
|
56
|
+
if (mode === "basic") return PIP_HEIGHT_BASIC_PX;
|
|
57
|
+
return getPipHeightExpandedPx(participantCount);
|
|
58
|
+
}
|
|
44
59
|
function getPipHeightExpandedPx(participantCount) {
|
|
45
60
|
const n = Math.min(Math.max(1, participantCount), 4);
|
|
46
61
|
return PIP_BAR_HEIGHT_PX + n * PIP_TILE_HEIGHT_16_9_PX + (n - 1) * TILE_GAP_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX + PIP_EXTRA_HEIGHT_PX + PIP_EXTRA_HEIGHT_EXPANDED_PX;
|
|
@@ -279,7 +294,7 @@ function PiPProvider({ children }) {
|
|
|
279
294
|
cameraActive: camLive
|
|
280
295
|
});
|
|
281
296
|
const openPiP = useCallback(async () => {
|
|
282
|
-
const height = compactViewMode
|
|
297
|
+
const height = getPipHeightForMode(compactViewMode, totalParticipants);
|
|
283
298
|
await openPiPRaw({ height });
|
|
284
299
|
}, [openPiPRaw, compactViewMode, totalParticipants]);
|
|
285
300
|
useEffect(() => {
|
|
@@ -298,7 +313,7 @@ function PiPProvider({ children }) {
|
|
|
298
313
|
}, [room, pipWindow, closePiP]);
|
|
299
314
|
useEffect(() => {
|
|
300
315
|
if (!pipWindow || !resizePiP) return;
|
|
301
|
-
const height = compactViewMode === "basic" ? PIP_HEIGHT_BASIC_PX + PIP_EXTRA_HEIGHT_PX :
|
|
316
|
+
const height = compactViewMode === "basic" ? PIP_HEIGHT_BASIC_PX + PIP_EXTRA_HEIGHT_PX : getPipHeightForMode(compactViewMode, totalParticipants);
|
|
302
317
|
resizePiP(PIP_PANEL_WIDTH_PX, height);
|
|
303
318
|
}, [pipWindow, resizePiP, compactViewMode, totalParticipants]);
|
|
304
319
|
const value = {
|
|
@@ -475,7 +490,8 @@ function CompactCallVideoArea({
|
|
|
475
490
|
multiCanPrev,
|
|
476
491
|
multiCanNext,
|
|
477
492
|
onMultiPrev,
|
|
478
|
-
onMultiNext
|
|
493
|
+
onMultiNext,
|
|
494
|
+
onAudioExpand
|
|
479
495
|
}) {
|
|
480
496
|
const pip = usePiP();
|
|
481
497
|
const showPiPButton = pip?.isSupported && currentParticipant;
|
|
@@ -491,6 +507,17 @@ function CompactCallVideoArea({
|
|
|
491
507
|
}
|
|
492
508
|
);
|
|
493
509
|
}
|
|
510
|
+
if (!isMobile && compactViewMode === "audio") {
|
|
511
|
+
return /* @__PURE__ */ jsx(
|
|
512
|
+
CompactCallCollapsedBar,
|
|
513
|
+
{
|
|
514
|
+
participant: currentParticipant?.participant ?? null,
|
|
515
|
+
audioTrack: currentAudioTrack ?? null,
|
|
516
|
+
onExpand: onAudioExpand,
|
|
517
|
+
className: cn("mb-2 w-[360px]", withOutShadows ? "" : "shadow-lg")
|
|
518
|
+
}
|
|
519
|
+
);
|
|
520
|
+
}
|
|
494
521
|
return /* @__PURE__ */ jsxs(
|
|
495
522
|
"div",
|
|
496
523
|
{
|
|
@@ -555,7 +582,7 @@ function CompactCallVideoArea({
|
|
|
555
582
|
isFocusToggleDisable: true
|
|
556
583
|
}
|
|
557
584
|
) : emptyState,
|
|
558
|
-
showPiPButton && /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
585
|
+
showPiPButton && compactViewMode !== "audio" && /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
559
586
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
560
587
|
Button,
|
|
561
588
|
{
|
|
@@ -606,6 +633,13 @@ function CompactCallBottomBar({
|
|
|
606
633
|
onMaximize,
|
|
607
634
|
isTutor
|
|
608
635
|
}) {
|
|
636
|
+
const nextViewMode = getNextCompactViewMode(compactViewMode);
|
|
637
|
+
const viewModeToggleMeta = {
|
|
638
|
+
expanded: { Icon: Users, label: "\u0420\u0430\u0437\u0432\u0451\u0440\u043D\u0443\u0442\u044B\u0439 \u0432\u0438\u0434 (\u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u043E\u0432)" },
|
|
639
|
+
audio: { Icon: SoundTwo, label: "\u0422\u043E\u043B\u044C\u043A\u043E \u0430\u0443\u0434\u0438\u043E" },
|
|
640
|
+
basic: { Icon: Account, label: "\u041E\u0434\u0438\u043D \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A" }
|
|
641
|
+
}[nextViewMode];
|
|
642
|
+
const ViewModeIcon = viewModeToggleMeta.Icon;
|
|
609
643
|
const barCn = cn(
|
|
610
644
|
"bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-1",
|
|
611
645
|
withOutShadows ? "" : "shadow-lg"
|
|
@@ -631,11 +665,11 @@ function CompactCallBottomBar({
|
|
|
631
665
|
variant: "none",
|
|
632
666
|
onClick: onViewModeToggle,
|
|
633
667
|
className: "hover:bg-gray-5 h-8 w-8 rounded-xl p-0 text-gray-100",
|
|
634
|
-
"aria-label":
|
|
635
|
-
children:
|
|
668
|
+
"aria-label": viewModeToggleMeta.label,
|
|
669
|
+
children: /* @__PURE__ */ jsx(ViewModeIcon, { className: "h-5 w-5" })
|
|
636
670
|
}
|
|
637
671
|
) }),
|
|
638
|
-
/* @__PURE__ */ jsx(TooltipContent, { children:
|
|
672
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: viewModeToggleMeta.label })
|
|
639
673
|
] }) }),
|
|
640
674
|
showBackToBoardButton && /* @__PURE__ */ jsx("div", { className: cn(barCn, "ml-1"), children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
641
675
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
@@ -855,7 +889,8 @@ var CompactCall = ({ saveUserChoices = true, withOutShadows = false }) => {
|
|
|
855
889
|
multiCanPrev,
|
|
856
890
|
multiCanNext,
|
|
857
891
|
onMultiPrev: () => setMultiScrollIndex((i) => Math.max(0, i - 1)),
|
|
858
|
-
onMultiNext: () => setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1))
|
|
892
|
+
onMultiNext: () => setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1)),
|
|
893
|
+
onAudioExpand: () => setCompactViewMode("basic")
|
|
859
894
|
}
|
|
860
895
|
),
|
|
861
896
|
/* @__PURE__ */ jsx(
|
|
@@ -880,7 +915,7 @@ var CompactCall = ({ saveUserChoices = true, withOutShadows = false }) => {
|
|
|
880
915
|
},
|
|
881
916
|
isMobile,
|
|
882
917
|
compactViewMode,
|
|
883
|
-
onViewModeToggle: () => setCompactViewMode(compactViewMode
|
|
918
|
+
onViewModeToggle: () => setCompactViewMode(getNextCompactViewMode(compactViewMode)),
|
|
884
919
|
showBackToBoardButton: !!showBackToBoardButton,
|
|
885
920
|
onBackToBoard: handleBackToBoard,
|
|
886
921
|
onMaximize: handleMaximize,
|
|
@@ -968,6 +1003,7 @@ var Compact = ({ children, hideOverlay = false }) => {
|
|
|
968
1003
|
};
|
|
969
1004
|
const isBoardPage = navigation.pathnameIncludes("/board");
|
|
970
1005
|
const bottomOffset = isBoardPage ? "bottom-[72px]" : "bottom-4";
|
|
1006
|
+
const mobileContentMarginTop = hideOverlay || !isMobile ? 0 : (headerHeight > 0 ? headerHeight : COMPACT_MOBILE_OVERLAY_FALLBACK_PX) + COMPACT_MOBILE_CONTENT_GAP_PX;
|
|
971
1007
|
const getCornerPosition = (corner) => {
|
|
972
1008
|
switch (corner) {
|
|
973
1009
|
case "top-left":
|
|
@@ -987,12 +1023,12 @@ var Compact = ({ children, hideOverlay = false }) => {
|
|
|
987
1023
|
};
|
|
988
1024
|
const container = /* @__PURE__ */ jsxs("div", { className: `relative flex h-dvh flex-col bg-transparent`, children: [
|
|
989
1025
|
isMobile ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
990
|
-
!hideOverlay && /* @__PURE__ */ jsx("div", { ref: headerRef, className: "fixed top-
|
|
1026
|
+
!hideOverlay && /* @__PURE__ */ jsx("div", { ref: headerRef, className: "fixed top-2 right-0 left-0 z-10 w-full px-2", children: /* @__PURE__ */ jsx(CompactCall, { withOutShadows: true }) }),
|
|
991
1027
|
/* @__PURE__ */ jsx(
|
|
992
1028
|
"div",
|
|
993
1029
|
{
|
|
994
|
-
className: "flex min-h-0 flex-1 flex-col",
|
|
995
|
-
style: { marginTop:
|
|
1030
|
+
className: "mb-16 flex min-h-0 flex-1 flex-col",
|
|
1031
|
+
style: { marginTop: mobileContentMarginTop },
|
|
996
1032
|
children
|
|
997
1033
|
}
|
|
998
1034
|
)
|
|
@@ -1067,6 +1103,13 @@ function PiPCompactCall({ pipWindow }) {
|
|
|
1067
1103
|
(mode) => updateStore("compactViewMode", mode),
|
|
1068
1104
|
[updateStore]
|
|
1069
1105
|
);
|
|
1106
|
+
const nextViewMode = getNextCompactViewMode(compactViewMode);
|
|
1107
|
+
const viewModeToggleMeta = {
|
|
1108
|
+
expanded: { Icon: Users, label: "\u0420\u0430\u0437\u0432\u0451\u0440\u043D\u0443\u0442\u044B\u0439 \u0432\u0438\u0434 (\u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u043E\u0432)" },
|
|
1109
|
+
audio: { Icon: SoundTwo, label: "\u0422\u043E\u043B\u044C\u043A\u043E \u0430\u0443\u0434\u0438\u043E" },
|
|
1110
|
+
basic: { Icon: Account, label: "\u041E\u0434\u0438\u043D \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A" }
|
|
1111
|
+
}[nextViewMode];
|
|
1112
|
+
const ViewModeIcon = viewModeToggleMeta.Icon;
|
|
1070
1113
|
const [multiScrollIndex, setMultiScrollIndex] = useState(0);
|
|
1071
1114
|
const [pipSize, setPipSize] = useState({
|
|
1072
1115
|
width: pipWindow.innerWidth,
|
|
@@ -1117,6 +1160,9 @@ function PiPCompactCall({ pipWindow }) {
|
|
|
1117
1160
|
);
|
|
1118
1161
|
const multiCanPrev = multiScrollIndex > 0;
|
|
1119
1162
|
const multiCanNext = multiScrollIndex + multiVisibleCount < totalParticipants;
|
|
1163
|
+
const currentAudioTrack = currentParticipant?.participant?.getTrackPublication(
|
|
1164
|
+
Track.Source.Microphone
|
|
1165
|
+
)?.track;
|
|
1120
1166
|
useEffect(() => {
|
|
1121
1167
|
if (multiScrollIndex + multiVisibleCount > totalParticipants && totalParticipants > 0) {
|
|
1122
1168
|
setMultiScrollIndex(Math.max(0, totalParticipants - multiVisibleCount));
|
|
@@ -1127,7 +1173,15 @@ function PiPCompactCall({ pipWindow }) {
|
|
|
1127
1173
|
"bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-0.5"
|
|
1128
1174
|
);
|
|
1129
1175
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-1 p-1", children: [
|
|
1130
|
-
/* @__PURE__ */ jsx("div", { className: "group relative min-h-0 flex-1 overflow-hidden rounded-2xl", children: compactViewMode === "
|
|
1176
|
+
/* @__PURE__ */ jsx("div", { className: "group relative min-h-0 flex-1 overflow-hidden rounded-2xl", children: compactViewMode === "audio" ? /* @__PURE__ */ jsx(
|
|
1177
|
+
CompactCallCollapsedBar,
|
|
1178
|
+
{
|
|
1179
|
+
participant: currentParticipant?.participant ?? null,
|
|
1180
|
+
audioTrack: currentAudioTrack ?? null,
|
|
1181
|
+
onExpand: () => setViewMode("basic"),
|
|
1182
|
+
className: "h-full w-full"
|
|
1183
|
+
}
|
|
1184
|
+
) : compactViewMode === "expanded" ? /* @__PURE__ */ jsxs(
|
|
1131
1185
|
"div",
|
|
1132
1186
|
{
|
|
1133
1187
|
className: "relative flex h-full flex-col overflow-hidden rounded-2xl p-0.5",
|
|
@@ -1210,13 +1264,13 @@ function PiPCompactCall({ pipWindow }) {
|
|
|
1210
1264
|
{
|
|
1211
1265
|
size: "icon",
|
|
1212
1266
|
variant: "none",
|
|
1213
|
-
onClick: () => setViewMode(compactViewMode
|
|
1267
|
+
onClick: () => setViewMode(getNextCompactViewMode(compactViewMode)),
|
|
1214
1268
|
className: "hover:bg-gray-5 h-[28px] w-[28px] rounded-xl p-0 text-gray-100",
|
|
1215
|
-
"aria-label":
|
|
1216
|
-
children:
|
|
1269
|
+
"aria-label": viewModeToggleMeta.label,
|
|
1270
|
+
children: /* @__PURE__ */ jsx(ViewModeIcon, { className: "h-4 w-4" })
|
|
1217
1271
|
}
|
|
1218
1272
|
) }),
|
|
1219
|
-
/* @__PURE__ */ jsx(TooltipContent, { children:
|
|
1273
|
+
/* @__PURE__ */ jsx(TooltipContent, { children: viewModeToggleMeta.label })
|
|
1220
1274
|
] }) }),
|
|
1221
1275
|
/* @__PURE__ */ jsxs("div", { className: cn(barCn, "ml-auto"), children: [
|
|
1222
1276
|
/* @__PURE__ */ jsx(ScreenShareButton, { className: "h-[28px] w-[28px]" }),
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/hooks/useCompactAvailableHeight.ts","../src/hooks/useCompactNavigation.ts","../src/hooks/useDocumentPiP.ts","../src/providers/PiPProvider.tsx","../src/ui/CompactCallCollapsedBar.tsx","../src/ui/CompactNavigationControls.tsx","../src/ui/CompactMultiViewControls.tsx","../src/ui/CompactCallVideoArea.tsx","../src/ui/CompactCallBottomBar.tsx","../src/ui/CompactCall.tsx","../src/ui/CompactView.tsx","../src/ui/PiPCompactCall.tsx"],"names":["useState","useEffect","useCallback","jsxs","jsx","Track","cn","Button","Tooltip","TooltipTrigger","TooltipContent","useMedia","useLocalParticipant","useCallStore","mode","useRoom","useMemo","Fragment","useCallsNavigation","useRef","usePersistentUserChoices","useTrackToggle","ParticipantTile","DevicesBar","Users","Account","ScreenShareButton","RaiseHandButton","DisconnectButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACO,IAAM,gBAAA,GAAmB,EAAA;AAGzB,IAAM,uBAAA,GAA0B,EAAA;AAGhC,IAAM,wBAAA,GAA2B,EAAA;AACjC,IAAM,qBAAA,GAAwB,EAAA;AAI9B,IAAM,WAAA,GAAc,CAAA;AAGpB,IAAM,kCAAA,GAAqC,CAAA;AAE3C,IAAM,4BAAA,GAA+B,CAAA;AAErC,IAAM,iCAAiC,uBAAA,GAA0B,WAAA;AAGjE,IAAM,sBAAA,GAAyB,GAAA;AAC/B,IAAM,mBAAA,GAAsB,IAAA,CAAK,KAAA,CAAO,sBAAA,GAAyB,IAAK,EAAE,CAAA;AAGxE,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,iBAAA,GAAoB,EAAA;AAE1B,IAAM,oBAAA,GAAuB,CAAA;AAE7B,IAAM,6BAAA,GAAgC,CAAA;AAKtC,IAAM,sBAAA,GACX,iBAAA,GACA,oBAAA,GACA,kCAAA,GACA,6BAAA;AAEK,IAAM,uBAAA,GAA0B,IAAA,CAAK,KAAA,CAAO,kBAAA,GAAqB,IAAK,EAAE,CAAA;AAExE,IAAM,mBAAA,GAAsB,EAAA;AAE5B,IAAM,4BAAA,GAA+B,EAAA;AAErC,IAAM,mBAAA,GACX,oBAAoB,uBAAA,GAA0B,kCAAA;AAMzC,SAAS,uBAAuB,gBAAA,EAAkC;AACvE,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,gBAAgB,GAAG,CAAC,CAAA;AACnD,EAAA,OACE,oBACA,CAAA,GAAI,uBAAA,GAAA,CACH,IAAI,CAAA,IAAK,WAAA,GACV,qCACA,mBAAA,GACA,4BAAA;AAEJ;;;ACrDA,SAAS,oBAAoB,aAAA,EAAgC;AAC3D,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,GAAA;AAC1C,EAAA,MAAM,YAAA,GAAe,gBACjB,8BAAA,GACA,wBAAA;AACJ,EAAA,OAAO,MAAA,CAAO,cAAc,gBAAA,GAAmB,YAAA;AACjD;AAEO,SAAS,0BAA0B,aAAA,EAAgC;AACxE,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM,mBAAA,CAAoB,aAAa,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AACvF,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,SAAS,aAAa,CAAA;AAEpE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,kBAAA,CAAmB,aAAa,CAAA;AAChC,IAAA,MAAM,QAAA,GAAW,MAAM,kBAAA,CAAmB,mBAAA,CAAoB,aAAa,CAAC,CAAA;AAC5E,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AAC1C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC5D,CAAA,EAAG,CAAC,aAAA,EAAe,aAAa,CAAC,CAAA;AAEjC,EAAA,OAAO,eAAA;AACT;AC3BO,IAAM,uBAAuB,MAAM;AACxC,EAAA,MAAM,CAAC,uBAAA,EAAyB,0BAA0B,CAAA,GAAIA,SAAS,CAAC,CAAA;AAGxE,EAAA,MAAM,YAAA,GAAe,SAAA;AAAA,IACnB;AAAA,MACE,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,CAAO,MAAA,EAAQ,iBAAiB,IAAA,EAAK;AAAA,MACrD,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,CAAO,WAAA,EAAa,iBAAiB,KAAA;AAAM,KAC7D;AAAA,IACA;AAAA,MACE,cAAA,EAAgB;AAAA;AAAA;AAClB,GACF;AAGA,EAAA,qBAAA,CAAsB,YAAY,CAAA;AAElC,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,YAAA,EAAc,CAAC,CAAA;AAE9C,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAO,uBAAuB,CAAA,IAAK,IAAA;AAC9D,EAAA,MAAM,oBAAoB,MAAA,CAAO,MAAA;AAEjC,EAAA,MAAM,SAAA,GAAY,0BAA0B,iBAAA,GAAoB,CAAA;AAChE,EAAA,MAAM,YAAY,uBAAA,GAA0B,CAAA;AAE5C,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,0BAAA,CAA2B,CAAC,IAAA,KAAS,IAAA,GAAO,CAAC,CAAA;AAAA,IAC/C;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,0BAAA,CAA2B,CAAC,IAAA,KAAS,IAAA,GAAO,CAAC,CAAA;AAAA,IAC/C;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAAkB;AACzC,IAAA,IAAI,KAAA,IAAS,CAAA,IAAK,KAAA,GAAQ,iBAAA,EAAmB;AAC3C,MAAA,0BAAA,CAA2B,KAAK,CAAA;AAAA,IAClC;AAAA,EACF,CAAA;AAGA,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,uBAAA,IAA2B,iBAAA,IAAqB,iBAAA,GAAoB,CAAA,EAAG;AACzE,MAAA,0BAAA,CAA2B,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,iBAAA,GAAoB,CAAC,CAAC,CAAA;AAAA,IAC/D;AAAA,EACF,CAAA,EAAG,CAAC,iBAAA,EAAmB,uBAAuB,CAAC,CAAA;AAK/C,EAAA,OAAO;AAAA,IACL,kBAAA;AAAA,IACA,YAAA,EAAc,MAAA;AAAA,IACd,YAAA,EAAc,uBAAA;AAAA,IACd,iBAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACF;AClCA,SAAS,mBAAmB,YAAA,EAAsB;AAChD,EAAA,CAAC,GAAG,QAAA,CAAS,WAAW,CAAA,CAAE,OAAA,CAAQ,CAAC,UAAA,KAAe;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,CAAC,GAAG,UAAA,CAAW,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,OAAO,CAAA,CAAE,KAAK,EAAE,CAAA;AAC7E,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,MAAA,KAAA,CAAM,WAAA,GAAc,QAAA;AACpB,MAAA,YAAA,CAAa,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,KAAK,CAAA;AAAA,IAC9C,CAAA,CAAA,MAAQ;AACN,MAAA,IAAI,WAAW,IAAA,EAAM;AACnB,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA;AAC1C,QAAA,IAAA,CAAK,GAAA,GAAM,YAAA;AACX,QAAA,IAAA,CAAK,IAAA,GAAO,WAAW,IAAA,IAAQ,UAAA;AAC/B,QAAA,IAAA,CAAK,KAAA,GAAQ,WAAW,KAAA,CAAM,SAAA;AAC9B,QAAA,IAAA,CAAK,OAAO,UAAA,CAAW,IAAA;AACvB,QAAA,YAAA,CAAa,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI;AACF,IAAA,QAAA,CAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC/B,MAAA,YAAA,CAAa,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAAA,IACtC,CAAC,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,cAAA,CAAe;AAAA,EAC7B,KAAA,GAAQ,GAAA;AAAA,EACR,MAAA,GAAS,GAAA;AAAA,EACT,OAAA,GAAU,IAAA;AAAA,EACV,gBAAA,GAAmB,KAAA;AAAA,EACnB,YAAA,GAAe;AACjB,CAAA,GAA2B,EAAC,EAAG;AAC7B,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAID,SAAwB,IAAI,CAAA;AAC9D,EAAA,MAAM,YAAA,GAAe,OAAsB,IAAI,CAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,OAAO,gBAAgB,CAAA;AAC5C,EAAA,MAAM,YAAA,GAAe,OAAO,YAAY,CAAA;AAExC,EAAA,YAAA,CAAa,OAAA,GAAU,gBAAA;AACvB,EAAA,YAAA,CAAa,OAAA,GAAU,YAAA;AAEvB,EAAA,MAAM,WAAA,GAAc,OAAO,MAAA,KAAW,WAAA,IAAe,0BAAA,IAA8B,MAAA;AAGnF,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,YAAA,CAAa,oBAAoB,gBAAgB,CAAA;AAAA,IAC7D,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,YAAA,CAAa,gBAAgB,YAAY,CAAA;AAAA,IACrD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,gBAAA,EAAkB,YAAY,CAAC,CAAA;AAE5C,EAAA,MAAM,OAAA,GAAU,WAAA;AAAA,IACd,OAAO,SAAA,KAA4E;AACjF,MAAA,IAAI,CAAC,WAAA,IAAe,CAAC,OAAA,EAAS,OAAO,IAAA;AACrC,MAAA,IAAI,YAAA,CAAa,OAAA,EAAS,OAAO,YAAA,CAAa,OAAA;AAE9C,MAAA,MAAM,CAAA,GAAI,WAAW,KAAA,IAAS,KAAA;AAC9B,MAAA,MAAM,CAAA,GAAI,WAAW,MAAA,IAAU,MAAA;AAE/B,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,wBAAA,CAA0B,aAAA,CAAc;AAAA,UAC/D,KAAA,EAAO,CAAA;AAAA,UACP,MAAA,EAAQ;AAAA,SACT,CAAA;AAED,QAAA,kBAAA,CAAmB,GAAG,CAAA;AAEtB,QAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,GAAA;AACjC,QAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,QAAA,GAAW,QAAA;AACnC,QAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,UAAA,GAAa,wBAAA;AAErC,QAAA,YAAA,CAAa,OAAA,GAAU,GAAA;AACvB,QAAA,YAAA,CAAa,GAAG,CAAA;AAEhB,QAAA,GAAA,CAAI,gBAAA,CAAiB,YAAY,MAAM;AACrC,UAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AACvB,UAAA,YAAA,CAAa,IAAI,CAAA;AAAA,QACnB,CAAC,CAAA;AAED,QAAA,OAAO,GAAA;AAAA,MACT,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IACA,CAAC,WAAA,EAAa,OAAA,EAAS,KAAA,EAAO,MAAM;AAAA,GACtC;AAEA,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,aAAa,OAAA,EAAS;AACxB,MAAA,YAAA,CAAa,QAAQ,KAAA,EAAM;AAAA,IAC7B;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAIL,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,OAAA,EAAS;AAE9B,IAAA,MAAM,MAAA,GAAS,uBAAA;AACf,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,aAAa,gBAAA,CAAiB,MAAA,EAAQ,MAAM,KAAK,SAAS,CAAA;AAAA,IACtE,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI;AACF,QAAA,SAAA,CAAU,YAAA,CAAa,gBAAA,CAAiB,MAAA,EAAQ,IAAI,CAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,OAAA,EAAS,OAAO,CAAC,CAAA;AAGlC,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,MAAM,yBAAyB,MAAM;AACnC,MAAA,IAAI,CAAC,QAAA,CAAS,MAAA,IAAU,YAAA,CAAa,OAAA,EAAS;AAC5C,QAAA,QAAA,EAAS;AAAA,MACX;AAAA,IACF,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,sBAAsB,CAAA;AACpE,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,kBAAA,EAAoB,sBAAsB,CAAA;AAAA,EACtF,CAAA,EAAG,CAAC,OAAA,EAAS,QAAQ,CAAC,CAAA;AAGtB,EAAAA,UAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,CAAa,SAAS,KAAA,EAAM;AAC5B,MAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AAAA,IACzB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,CAAC,CAAA,EAAW,CAAA,KAAc;AACtD,IAAA,IAAI,aAAa,OAAA,EAAS;AACxB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,OAAA,CAAQ,QAAA,CAAS,CAAA,EAAG,CAAC,CAAA;AAAA,MACpC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAa,SAAA,KAAc,IAAA;AAAA,IAC3B,OAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACF;ACjLA,IAAM,UAAA,GAAa,cAAsC,IAAI,CAAA;AAEtD,SAAS,MAAA,GAAS;AACvB,EAAA,MAAM,GAAA,GAAM,WAAW,UAAU,CAAA;AACjC,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,oBACP,GAAA,EAC8B;AAC9B,EAAA,OAAO,KAAK,KAAA,EAAO,gBAAA;AACrB;AAEA,SAAS,mBAAA,GAAsB;AAC7B,EAAA,MAAM,EAAE,eAAA,EAAiB,WAAA,EAAY,GAAI,mBAAA,EAAoB;AAC7D,EAAA,MAAM,QAAA,GAAW,oBAAoB,eAAe,CAAA;AACpD,EAAA,MAAM,QAAA,GAAW,oBAAoB,WAAW,CAAA;AAChD,EAAA,MAAM,UAAU,CAAC,CAAC,YAAY,QAAA,CAAS,UAAA,KAAe,UAAU,QAAA,CAAS,OAAA;AACzE,EAAA,MAAM,UAAU,CAAC,CAAC,YAAY,QAAA,CAAS,UAAA,KAAe,UAAU,QAAA,CAAS,OAAA;AACzE,EAAA,OAAO,EAAE,SAAS,OAAA,EAAQ;AAC5B;AAUO,SAAS,WAAA,CAAY,EAAE,QAAA,EAAS,EAAqB;AAC1D,EAAA,MAAM,QAAA,GAAW,SAAS,oBAAoB,CAAA;AAC9C,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,mBAAA,EAAoB;AACjD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,OAAA,EAAQ;AACzB,EAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,CAAC,CAAA,KAAM,EAAE,eAAe,CAAA;AAC7D,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,oBAAA,EAAqB;AAEnD,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA,EAAS,UAAA;AAAA,IACT;AAAA,MACE,cAAA,CAAe;AAAA,IACjB,SAAS,CAAC,QAAA;AAAA,IACV,KAAA,EAAO,kBAAA;AAAA,IACP,MAAA,EAAQ,mBAAA;AAAA,IACR,gBAAA,EAAkB,OAAA;AAAA,IAClB,YAAA,EAAc;AAAA,GACf,CAAA;AAED,EAAA,MAAM,OAAA,GAAUC,YAAY,YAAY;AACtC,IAAA,MAAM,MAAA,GACJ,eAAA,KAAoB,OAAA,GAAU,mBAAA,GAAsB,uBAAuB,iBAAiB,CAAA;AAC9F,IAAA,MAAM,UAAA,CAAW,EAAE,MAAA,EAAQ,CAAA;AAAA,EAC7B,CAAA,EAAG,CAAC,UAAA,EAAY,eAAA,EAAiB,iBAAiB,CAAC,CAAA;AAEnD,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,SAAA,EAAW;AACzB,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,EAAa;AAC9B,MAAA,QAAA,EAAS;AACT,MAAA;AAAA,IACF;AACA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,IAAI,IAAA,CAAK,KAAA,KAAU,WAAA,EAAa,QAAA,EAAS;AAAA,IAC3C,CAAA;AACA,IAAA,IAAA,CAAK,EAAA,CAAG,0BAA0B,WAAW,CAAA;AAC7C,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,GAAA,CAAI,0BAA0B,WAAW,CAAA;AAAA,IAChD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,SAAA,EAAW,QAAQ,CAAC,CAAA;AAE9B,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,EAAW;AAC9B,IAAA,MAAM,SACJ,eAAA,KAAoB,OAAA,GAChB,mBAAA,GAAsB,mBAAA,GACtB,uBAAuB,iBAAiB,CAAA;AAC9C,IAAA,SAAA,CAAU,oBAAoB,MAAM,CAAA;AAAA,EACtC,GAAG,CAAC,SAAA,EAAW,SAAA,EAAW,eAAA,EAAiB,iBAAiB,CAAC,CAAA;AAE7D,EAAA,MAAM,KAAA,GAAyB;AAAA,IAC7B,OAAA;AAAA,IACA,aAAa,SAAA,KAAc,IAAA;AAAA,IAC3B,WAAA,EAAa,eAAe,CAAC;AAAA,GAC/B;AAEA,EAAA,uBACE,IAAA,CAAC,UAAA,CAAW,QAAA,EAAX,EAAoB,KAAA,EAClB,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,SAAA,IAAa,6BAAa,GAAA,CAAC,cAAA,EAAA,EAAe,WAAsB,CAAA,EAAI,SAAA,CAAU,SAAS,IAAI;AAAA,GAAA,EAC9F,CAAA;AAEJ;ACnGO,SAAS,uBAAA,CAAwB;AAAA,EACtC,WAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAiC;AAC/B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,gBAAA,CAAiB,cAAc,MAAA,EAAW;AAAA,IACzD,QAAA,EAAU,EAAA;AAAA,IACV,aAAA,EAAe,CAAA;AAAA,IACf,cAAA,EAAgB;AAAA,GACjB,CAAA;AACD,EAAA,uBACEE,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,oEAAA;AAAA,QACA;AAAA,OACF;AAAA,MAGA,QAAA,EAAA;AAAA,wBAAAC,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iGACZ,QAAA,EAAA,WAAA,mBACCD,KAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAC,GAAAA;AAAA,YAAC,mBAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAU;AAAA,gBACR,WAAA;AAAA,gBACA,MAAA,EAAQC,MAAM,MAAA,CAAO;AAAA,eACvB;AAAA,cACA,IAAA,EAAK,OAAA;AAAA,cACL,KAAA,EAAO,EAAE,WAAA,EAAa,SAAA,EAAW,YAAY,aAAA;AAAc;AAAA,WAC7D;AAAA,0BACAD,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBACd,QAAA,kBAAAA,GAAAA,CAAC,eAAA,EAAA,EAAgB,WAAA,EAA0B,CAAA,EAC7C;AAAA,SAAA,EACF,CAAA,mBAEAD,IAAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,gCAAA,EAAiC,CAAA;AAAA,4BAC1DA,GAAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,8BAAA,EAA+B;AAAA,WAAA,EACpD,CAAA;AAAA,0BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kDAAiD,QAAA,EAAA,iFAAA,EAAc;AAAA,SAAA,EACjF,CAAA,EAEJ,CAAA;AAAA,QACC,+BAAeA,GAAAA,CAAC,mBAAA,EAAA,EAAoB,WAAA,EAAa,eAAe,SAAA,EAAW,CAAA;AAAA,wBAC5EA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8DAAA,EACZ,QAAA,EAAA,IAAA,CAAK,SAAS,CAAA,mBACbA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACZ,QAAA,EAAA,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,sBACZA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAU,uEAAA;AAAA,YACV,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,KAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAA,GAAI,GAAG,CAAC,CAAC,CAAA,CAAA,CAAA;AAAI,WAAA;AAAA,UAFvD;AAAA,SAIR,GACH,CAAA,mBAEAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAoC,CAAA,EAEvD,CAAA;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,MAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,OAAA,EAAS,QAAA;AAAA,YACT,SAAA,EAAU,kFAAA;AAAA,YACV,YAAA,EAAW,8DAAA;AAAA,YAEX,QAAA,kBAAAA,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,qBAAA,EAAsB;AAAA;AAAA;AACjD;AAAA;AAAA,GACF;AAEJ;ACvEO,SAAS,yBAAA,CAA0B;AAAA,EACxC,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA,EAAmC;AACjC,EAAA,IAAI,qBAAqB,CAAA,EAAG;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EAEb,QAAA,EAAA;AAAA,oBAAAC,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gEACb,QAAA,kBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,yHAAA,EACZ,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,iBAAA,IAAqB,CAAC,CAAA,EAAG,0BAC7CA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAK,QAAA;AAAA,QACL,SAAS,MAAM;AAAA,QAGf,CAAA;AAAA,QACA,SAAA,EAAW,CAAA,2CAAA,EACT,KAAA,KAAU,YAAA,GAAe,gBAAgB,qCAC3C,CAAA,CAAA;AAAA,QACA,YAAA,EAAY,CAAA,iDAAA,EAAY,KAAA,GAAQ,CAAC,CAAA;AAAA,OAAA;AAAA,MAT5B;AAAA,KAWR,GACH,CAAA,EACF,CAAA;AAAA,oBAGAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wIACb,QAAA,kBAAAD,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,UAAU,CAAC,OAAA;AAAA,QACX,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,kLAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,0BAC/BA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,+GAAA,EAAmB;AAAA;AAAA;AAAA,KAC/C,EACF,CAAA;AAAA,oBAGAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yIACb,QAAA,kBAAAD,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,UAAU,CAAC,OAAA;AAAA,QACX,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,kLAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,0BAChCA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,yGAAA,EAAkB;AAAA;AAAA;AAAA,KAC9C,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AC/DO,SAAS,wBAAA,CAAyB;AAAA,EACvC,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAkC;AAChC,EAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EAEZ,QAAA,EAAA;AAAA,IAAA,OAAA,oBACCC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qEACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,gGAAA;AAAA,QACV,YAAA,EAAW,2EAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,sBAAA,EAAuB;AAAA;AAAA,KAC5C,EACF,CAAA;AAAA,IAGD,2BACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wEACb,QAAA,kBAAAA,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,SAAA,EAAU,gGAAA;AAAA,QACV,YAAA,EAAW,qEAAA;AAAA,QAEX,QAAA,kBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,iCAAA,EAAkC;AAAA;AAAA,KACvD,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;ACTO,SAAS,oBAAA,CAAqB;AAAA,EACnC,QAAA;AAAA,EACA,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAiB,EAAC;AAAA,EAClB,gBAAgB,EAAC;AAAA,EACjB,eAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,wBAAA;AAAA,EACA,iBAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,aAAA,GAAgB,KAAK,WAAA,IAAe,kBAAA;AAE1C,EAAA,MAAM,UAAA,mBACJA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yEAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,iFAAA,EAAc,CAAA,EAC1C,CAAA;AAGF,EAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,IAAA,uBACEA,GAAAA;AAAA,MAAC,uBAAA;AAAA,MAAA;AAAA,QACC,WAAA,EAAa,oBAAoB,WAAA,IAAe,IAAA;AAAA,QAChD,YAAY,iBAAA,IAAqB,IAAA;AAAA,QACjC,QAAA,EAAU,MAAM,iBAAA,CAAkB,KAAK,CAAA;AAAA,QACvC,SAAA,EAAWE,EAAAA,CAAG,MAAA,EAAQ,cAAA,GAAiB,KAAK,WAAW;AAAA;AAAA,KACzD;AAAA,EAEJ;AAEA,EAAA,uBACEH,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAI,WAAW,EAAC,GAAI,EAAE,GAAG,cAAA,EAAgB,GAAG,aAAA,EAAc;AAAA,MAC3D,SAAA,EAAWG,EAAAA;AAAA,QACT,sDAAA;AAAA,QACA,iBAAiB,EAAA,GAAK,WAAA;AAAA,QACtB,WAAW,2CAAA,GAA8C,gCAAA;AAAA,QACzD,CAAC,QAAA,IAAY,eAAA,KAAoB,OAAA,IAAW,UAAA;AAAA,QAC5C,CAAC,QAAA,IAAY,eAAA,KAAoB,UAAA,IAAc;AAAA,OACjD;AAAA,MACA,KAAA,EAAO,CAAC,QAAA,IAAY,eAAA,KAAoB,UAAU,EAAE,MAAA,EAAQ,qBAAoB,GAAI,MAAA;AAAA,MAEnF,QAAA,EAAA;AAAA,QAAA,QAAA,GACC,qCACEF,GAAAA;AAAA,UAAC,eAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAU,kBAAA;AAAA,YACV,aAAa,kBAAA,CAAmB,WAAA;AAAA,YAChC,SAAA,EAAU,eAAA;AAAA,YACV,oBAAA,EAAoB;AAAA;AAAA,SACtB,GAEA,UAAA,GAEA,eAAA,KAAoB,UAAA,mBACtBD,IAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,8DAAA;AAAA,YACV,KAAA,EAAO,EAAE,GAAA,EAAK,WAAA,EAAY;AAAA,YAEzB,QAAA,EAAA;AAAA,cAAA,wBAAA,CAAyB,WAAW,CAAA,GACjC,UAAA,GACA,yBAAyB,GAAA,CAAI,CAAC,6BAC5BC,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBAEC,SAAA,EAAU,yDAAA;AAAA,kBACV,KAAA,EAAO,EAAE,SAAA,EAAW,iBAAA,EAAkB;AAAA,kBAEtC,QAAA,kBAAAA,GAAAA;AAAA,oBAAC,eAAA;AAAA,oBAAA;AAAA,sBACC,QAAA;AAAA,sBACA,aAAa,QAAA,CAAS,WAAA;AAAA,sBACtB,SAAA,EAAU,sCAAA;AAAA,sBACV,oBAAA,EAAoB;AAAA;AAAA;AACtB,iBAAA;AAAA,gBATK,GAAG,QAAA,CAAS,WAAA,CAAY,QAAQ,CAAA,CAAA,EAAI,SAAS,MAAM,CAAA;AAAA,eAW3D,CAAA;AAAA,8BACLA,GAAAA;AAAA,gBAAC,wBAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,YAAA;AAAA,kBACT,OAAA,EAAS,YAAA;AAAA,kBACT,MAAA,EAAQ,WAAA;AAAA,kBACR,MAAA,EAAQ;AAAA;AAAA;AACV;AAAA;AAAA,SACF,GACE,qCACFA,GAAAA;AAAA,UAAC,eAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAU,kBAAA;AAAA,YACV,aAAa,kBAAA,CAAmB,WAAA;AAAA,YAChC,SAAA,EAAU,eAAA;AAAA,YACV,oBAAA,EAAoB;AAAA;AAAA,SACtB,GAEA,UAAA;AAAA,QAGD,aAAA,oBACCD,IAAAA,CAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EACrB,QAAA,kBAAAA,GAAAA;AAAA,YAACG,MAAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAQ,MAAA;AAAA,cACR,OAAA,EAAS,MAAM,KAAK,GAAA,CAAK,OAAA,EAAQ;AAAA,cACjC,SAAA,EAAU,+FAAA;AAAA,cACV,YAAA,EAAW,mIAAA;AAAA,cAEX,QAAA,kBAAAH,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,WAChC,EACF,CAAA;AAAA,0BACAA,GAAAA,CAAC,cAAA,EAAA,EAAe,QAAA,EAAA,mIAAA,EAAwB;AAAA,SAAA,EAC1C,CAAA;AAAA,QAGD,4BACCA,GAAAA;AAAA,UAACG,MAAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,MAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,OAAA,EAAS,MAAM,iBAAA,CAAkB,IAAI,CAAA;AAAA,YACrC,SAAA,EAAU,qGAAA;AAAA,YACV,YAAA,EAAW,kDAAA;AAAA,YAEX,QAAA,kBAAAH,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,qBAAA,EAAsB;AAAA;AAAA,SAC7C;AAAA,QAGD,iBAAA,GAAoB,CAAA,KAAM,QAAA,IAAY,eAAA,KAAoB,4BACzDA,GAAAA;AAAA,UAAC,yBAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,SAAA;AAAA,YACT,OAAA,EAAS,SAAA;AAAA,YACT,MAAA;AAAA,YACA,MAAA;AAAA,YACA,YAAA;AAAA,YACA;AAAA;AAAA;AACF;AAAA;AAAA,GAEJ;AAEJ;AC7IO,SAAS,oBAAA,CAAqB;AAAA,EACnC,cAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,qBAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAA+B;AAC7B,EAAA,MAAM,KAAA,GAAQE,EAAAA;AAAA,IACZ,kFAAA;AAAA,IACA,iBAAiB,EAAA,GAAK;AAAA,GACxB;AAEA,EAAA,uBACEH,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,KAAA,EACd,QAAA,kBAAAA,GAAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,mBAAA;AAAA,QACV,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,QAC1B,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,kBAAkB,OAAA,CAAQ;AAAA;AAAA,KAC5B,EACF,CAAA;AAAA,IAEC,CAAC,QAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAWE,EAAAA,CAAG,KAAA,EAAO,MAAM,CAAA,EAC9B,QAAA,kBAAAH,IAAAA,CAACK,SAAA,EACC,QAAA,EAAA;AAAA,sBAAAJ,GAAAA,CAACK,cAAAA,EAAA,EAAe,OAAA,EAAO,MACrB,QAAA,kBAAAL,GAAAA;AAAA,QAACG,MAAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,MAAA;AAAA,UACL,OAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,gBAAA;AAAA,UACT,SAAA,EAAU,sDAAA;AAAA,UACV,YAAA,EAAY,eAAA,KAAoB,OAAA,GAAU,uFAAA,GAAoB,2EAAA;AAAA,UAE7D,QAAA,EAAA,eAAA,KAAoB,OAAA,mBACnBH,GAAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,SAAA,EAAU,CAAA,mBAE3BA,GAAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,OAEjC,EACF,CAAA;AAAA,sBACAA,GAAAA,CAACM,cAAAA,EAAA,EACE,QAAA,EAAA,eAAA,KAAoB,OAAA,GACjB,gNACA,2EAAA,EACN;AAAA,KAAA,EACF,CAAA,EACF,CAAA;AAAA,IAGD,qBAAA,oBACCN,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAWE,EAAAA,CAAG,KAAA,EAAO,MAAM,CAAA,EAC9B,QAAA,kBAAAH,IAAAA,CAACK,OAAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAJ,GAAAA,CAACK,cAAAA,EAAA,EAAe,OAAA,EAAO,MACrB,QAAA,kBAAAL,GAAAA;AAAA,QAACG,MAAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,MAAA;AAAA,UACL,OAAA,EAAQ,SAAA;AAAA,UACR,SAAA,EAAU,wBAAA;AAAA,UACV,OAAA,EAAS,aAAA;AAAA,UACT,YAAA,EAAW,6CAAA;AAAA,UAEX,QAAA,kBAAAH,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,qBAAA,EAAsB;AAAA;AAAA,OAC9C,EACF,CAAA;AAAA,sBACAA,GAAAA,CAACM,cAAAA,EAAA,EAAe,QAAA,EAAA,wFAAA,EAAgB;AAAA,KAAA,EAClC,CAAA,EACF,CAAA;AAAA,oBAGFP,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAWG,EAAAA,CAAG,KAAA,EAAO,SAAS,CAAA,EACjC,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,iBAAA,EAAA,EAAkB,SAAA,EAAU,mBAAA,EAAoB,CAAA;AAAA,sBACjDA,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,4BAAA,EAA6B,CAAA;AAAA,sBACnDA,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,mBAAA,EAAoB;AAAA,KAAA,EACjD,CAAA;AAAA,oBAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAWG,EAAAA,CAAG,KAAA,EAAO,MAAM,CAAA,EAC7B,QAAA,EAAA;AAAA,MAAA,OAAA,mBACCH,KAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAA,IAAAA,CAACK,SAAA,EACC,QAAA,EAAA;AAAA,0BAAAJ,GAAAA,CAACK,cAAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EACrB,0BAAAL,GAAAA,CAAC,mBAAA,EAAA,EAAoB,OAAA,EAAO,IAAA,EAC1B,QAAA,kBAAAA,GAAAA;AAAA,YAACG,MAAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,MAAA;AAAA,cACL,OAAA,EAAQ,MAAA;AAAA,cACR,SAAA,EAAU,mEAAA;AAAA,cAEV,QAAA,kBAAAH,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,eAAA,EAAgB;AAAA;AAAA,aAExC,CAAA,EACF,CAAA;AAAA,0BACAA,GAAAA,CAACM,cAAAA,EAAA,EAAe,QAAA,EAAA,kIAAA,EAAuB;AAAA,SAAA,EACzC,CAAA;AAAA,wBACAP,KAAC,mBAAA,EAAA,EAAoB,IAAA,EAAK,OAAM,KAAA,EAAM,KAAA,EAAM,WAAU,sBAAA,EACpD,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,iBAAA,EAAA,EAAkB,SAAA,EAAU,sBAAA,EAAuB,QAAA,EAAA,sHAAA,EAEpD,CAAA;AAAA,0BACAA,GAAAA;AAAA,YAAC,gBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,MAAM,UAAA,CAAW,KAAK,CAAA;AAAA,cAC/B,SAAA,EAAU,qCAAA;AAAA,cACX,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAA,GAAAA;AAAA,YAAC,gBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,cAC9B,SAAA,EAAU,qCAAA;AAAA,cACX,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EACF;AAAA,OAAA,EACF,CAAA,mBAEAD,IAAAA,CAACK,OAAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAJ,GAAAA,CAACK,cAAAA,EAAA,EAAe,OAAA,EAAO,MACrB,QAAA,kBAAAL,GAAAA;AAAA,UAACG,MAAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,MAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,OAAA,EAAS,MAAM,UAAA,CAAW,KAAK,CAAA;AAAA,YAC/B,SAAA,EAAU,mEAAA;AAAA,YAEV,QAAA,kBAAAH,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,eAAA,EAAgB;AAAA;AAAA,SACtC,EACF,CAAA;AAAA,wBACAA,GAAAA,CAACM,cAAAA,EAAA,EAAe,QAAA,EAAA,kIAAA,EAAuB;AAAA,OAAA,EACzC,CAAA;AAAA,sBAEFN,GAAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAU,8BAAA,EAA+B;AAAA,KAAA,EAC7D;AAAA,GAAA,EACF,CAAA;AAEJ;AC7JO,IAAM,cAAc,CAAC,EAAE,kBAAkB,IAAA,EAAM,cAAA,GAAiB,OAAM,KAAM;AACjF,EAAA,MAAM,QAAA,GAAWO,SAAS,oBAAoB,CAAA;AAC9C,EAAA,MAAM,EAAE,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,SAAA,KAAc,YAAA,CAAa;AAAA,IACpE,EAAA,EAAI,gBAAA;AAAA,IACJ,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,MAAM,KAAA,GAAQ,WAAW,MAAA,GAAY,EAAE,WAAW,GAAA,CAAI,SAAA,CAAU,QAAA,CAAS,SAAS,CAAA,EAAE;AAEpF,EAAA,MAAM,EAAE,qBAAA,EAAuB,qBAAA,EAAsB,GAAI,wBAAA,CAAyB;AAAA,IAChF,aAAa,CAAC;AAAA,GACf,CAAA;AACD,EAAA,MAAM,EAAE,mBAAA,EAAqB,eAAA,EAAiB,eAAA,EAAiB,WAAA,KAC7DC,mBAAAA,EAAoB;AACtB,EAAA,MAAM,aAAa,WAAA,EAAa,KAAA;AAEhC,EAAA,MAAM,IAAA,GAAOC,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA;AAC/C,EAAA,YAAA,CAAa,IAAA,KAAS,SAAA,GAAY,UAAA,GAAa,IAAI,CAAA;AAEnD,EAAA,MAAM,mBAAmB,cAAA,CAAe;AAAA,IACtC,MAAA,EAAQR,MAAM,MAAA,CAAO,UAAA;AAAA,IACrB,QAAA,EAAU,CAAC,OAAA,EAAkB,eAAA,KAA6B;AACxD,MAAA,IAAI,eAAA,wBAAuC,OAAO,CAAA;AAAA,IACpD;AAAA,GACD,CAAA;AACD,EAAA,MAAM,eAAe,cAAA,CAAe;AAAA,IAClC,MAAA,EAAQA,MAAM,MAAA,CAAO,MAAA;AAAA,IACrB,QAAA,EAAU,CAAC,OAAA,EAAkB,eAAA,KAA6B;AACxD,MAAA,IAAI,eAAA,wBAAuC,OAAO,CAAA;AAAA,IACpD;AAAA,GACD,CAAA;AAED,EAAA,MAAM,sBAAA,GAAyBH,YAAY,MAAM,gBAAA,CAAiB,QAAO,EAAG,CAAC,gBAAgB,CAAC,CAAA;AAC9F,EAAA,MAAM,kBAAA,GAAqBA,YAAY,MAAM,YAAA,CAAa,QAAO,EAAG,CAAC,YAAY,CAAC,CAAA;AAElF,EAAA,MAAM,oBAAoB,oBAAA,EAAqB;AAC/C,EAAA,MAAM;AAAA,IACJ,kBAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF,GAAI,iBAAA;AACJ,EAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAE3C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIF,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,eAAA,GAAkBa,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,eAAe,CAAA;AACrE,EAAA,MAAM,WAAA,GAAcA,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,WAAW,CAAA;AAC7D,EAAA,MAAM,kBAAA,GAAqBX,WAAAA;AAAA,IACzB,CAACY,KAAAA,KAA+B,WAAA,CAAY,iBAAA,EAAmBA,KAAI,CAAA;AAAA,IACnE,CAAC,WAAW;AAAA,GACd;AACA,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAId,SAAS,CAAC,CAAA;AAE1D,EAAA,MAAM,iBAAA,GAAoB,oBAAoB,WAAA,EAAa,mBAAA;AAAA,IACzDK,MAAM,MAAA,CAAO;AAAA,GACf,EAAG,KAAA;AAKH,EAAA,MAAM,EAAE,gBAAA,EAAiB,GAAI,WAAA,EAAY;AACzC,EAAA,MAAM,aAAA,GAAgBQ,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,aAAa,CAAA;AACjE,EAAA,MAAM,eAAA,GAAkBA,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,eAAe,CAAA;AACrE,EAAA,MAAM,EAAE,IAAA,EAAK,GAAIE,OAAAA,EAAQ;AACzB,EAAA,MAAM,KAAA,GAAQF,YAAAA,CAAa,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAEjD,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,KAAS,QAAA,EAAS,CAAE,KAAK,cAAA,EAAe;AAEtD,EAAA,MAAM,OAAA,GAAU,MAAM,cAAA,KAAmB,OAAA;AACzC,EAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,gBAAA,CAAiB,QAAQ,CAAA;AAC7D,EAAA,MAAM,gBACJ,eAAA,CAAgB,MAAA,CAAO,gBAAgB,eAAA,IACvC,eAAA,CAAgB,OAAO,OAAA,KAAY,aAAA;AACrC,EAAA,MAAM,qBAAA,GACJ,SAAS,SAAA,IAAa,CAAC,CAAC,aAAA,IAAiB,CAAC,CAAC,eAAA,IAAmB,CAAC,aAAA;AAEjE,EAAA,MAAM,eAAA,GAAkB,0BAA0B,WAAW,CAAA;AAE7D,EAAA,MAAM,eAAA,GAAkBG,QAAQ,MAAM;AACpC,IAAA,MAAM,iBAAiB,IAAA,CAAK,GAAA;AAAA,MAC1B,CAAA;AAAA,MACA,eAAA,GACE,wBACA,kCAAA,GACA;AAAA,KACJ;AAEA,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA;AAAA,MACxB,iBAAA;AAAA,MACA,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,OAAO,cAAA,GAAiB,WAAA,KAAgB,mBAAA,GAAsB,WAAA,CAAY,CAAC;AAAA,KAC9F;AACA,IAAA,OAAO,EAAE,YAAA,EAAc,YAAA,EAAc,mBAAA,EAAoB;AAAA,EAC3D,CAAA,EAAG,CAAC,eAAA,EAAiB,iBAAiB,CAAC,CAAA;AAEvC,EAAA,MAAM,EAAE,YAAA,EAAc,iBAAA,EAAmB,YAAA,EAAc,mBAAkB,GAAI,eAAA;AAC7E,EAAA,MAAM,eAAe,gBAAA,GAAmB,CAAA;AACxC,EAAA,MAAM,YAAA,GAAe,mBAAmB,iBAAA,GAAoB,iBAAA;AAC5D,EAAA,MAAM,2BAA2B,YAAA,CAAa,KAAA;AAAA,IAC5C,gBAAA;AAAA,IACA,gBAAA,GAAmB;AAAA,GACrB;AAEA,EAAAf,UAAU,MAAM;AACd,IAAA,IAAI,gBAAA,GAAmB,iBAAA,GAAoB,iBAAA,IAAqB,iBAAA,GAAoB,CAAA,EAAG;AACrF,MAAA,mBAAA,CAAoB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,iBAAA,GAAoB,iBAAiB,CAAC,CAAA;AAAA,IACxE;AAAA,EACF,CAAA,EAAG,CAAC,iBAAA,EAAmB,iBAAA,EAAmB,gBAAgB,CAAC,CAAA;AAE3D,EAAA,MAAM,iBAAA,GAAoBC,YAAY,MAAM;AAC1C,IAAA,IAAI,CAAC,aAAA,IAAiB,CAAC,eAAA,EAAiB;AACxC,IAAA,eAAA,CAAgB,wBAAA,CAAyB,iBAAiB,aAAa,CAAA;AAAA,EACzE,CAAA,EAAG,CAAC,aAAA,EAAe,eAAA,EAAiB,eAAe,CAAC,CAAA;AAEpD,EAAA,MAAM,cAAA,GAAiBA,WAAAA;AAAA,IACrB,CAAC,YAAqB,KAAA,KAAU;AAC9B,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,KAAA,IAAS,IAAA,CAAK,UAAU,WAAA,EAAa;AACnD,MAAA,MAAM,SAAA,GAAY,gBAAgB,MAAA,CAAO,IAAA;AACzC,MAAA,MAAM,gBACH,OAAO,SAAA,KAAc,WAAW,SAAA,CAAU,OAAA,CAAQ,UAAU,EAAE,CAAA,CAAE,IAAA,EAAK,GAAI,OAC1E,eAAA,IACA,eAAA,CAAgB,OAAO,WAAA,IACvB,eAAA,CAAgB,WAAU,IAC1B,EAAA;AACF,MAAA,IAAI,SAAA,IAAa,OAAA,IAAW,aAAA,IAAiB,YAAA,EAAc;AACzD,QAAA,WAAA,CAAY,iBAAiB,KAAK,CAAA;AAClC,QAAA,WAAA,CAAY,QAAQ,MAAM,CAAA;AAC1B,QAAA,WAAA,CAAY,iBAAiB,MAAS,CAAA;AACtC,QAAA,WAAA,CAAY,mBAAmB,MAAS,CAAA;AACxC,QAAA,gBAAA,CAAiB,MAAA,EAAQ,QAAW,YAAY,CAAA;AAAA,MAClD,CAAA,MAAO;AACL,QAAA,WAAA,CAAY,iBAAiB,IAAI,CAAA;AACjC,QAAA,WAAA,CAAY,QAAQ,MAAM,CAAA;AAAA,MAC5B;AACA,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,eAAA,CAAgB,cAAA,CAAe,YAAA,EAAc,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,MAChE;AAAA,IACF,CAAA;AAAA,IACA;AAAA,MACE,IAAA;AAAA,MACA,KAAA;AAAA,MACA,eAAA;AAAA,MACA,eAAA;AAAA,MACA,OAAA;AAAA,MACA,aAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,UAAA;AAAA,MACL,KAAA;AAAA,MACA,SAAA,EAAW,CAAA,qCAAA,EAAwC,QAAA,GAAW,QAAA,GAAW,WAAW,CAAA,CAAA;AAAA,MAEpF,QAAA,EAAA;AAAA,wBAAAC,GAAAA;AAAA,UAAC,oBAAA;AAAA,UAAA;AAAA,YACC,QAAA;AAAA,YACA,WAAA;AAAA,YACA,iBAAA,EAAmB,cAAA;AAAA,YACnB,cAAA;AAAA,YACA,cAAA,EAAgB,UAAA;AAAA,YAChB,aAAA,EAAe,SAAA;AAAA,YACf,eAAA;AAAA,YACA,kBAAA;AAAA,YACA,mBAAmB,iBAAA,IAAqB,IAAA;AAAA,YACxC,iBAAA;AAAA,YACA,SAAA;AAAA,YACA,SAAA;AAAA,YACA,MAAA,EAAQ,QAAA;AAAA,YACR,MAAA,EAAQ,QAAA;AAAA,YACR,YAAA;AAAA,YACA,wBAAA;AAAA,YACA,iBAAA;AAAA,YACA,YAAA;AAAA,YACA,YAAA;AAAA,YACA,WAAA,EAAa,MAAM,mBAAA,CAAoB,CAAC,CAAA,KAAM,KAAK,GAAA,CAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,YAChE,WAAA,EAAa,MACX,mBAAA,CAAoB,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,GAAoB,iBAAA,EAAmB,CAAA,GAAI,CAAC,CAAC;AAAA;AAAA,SAErF;AAAA,wBACAA,GAAAA;AAAA,UAAC,oBAAA;AAAA,UAAA;AAAA,YACC,cAAA;AAAA,YACA,OAAA,EAAS;AAAA,cACP,YAAY,eAAA,EAAiB,KAAA;AAAA,cAC7B,YAAA,EAAc,mBAAA;AAAA,cACd,gBAAA,EAAkB;AAAA,gBAChB,QAAA,EAAU,IAAA;AAAA,gBACV,MAAA,EAAQC,MAAM,MAAA,CAAO,UAAA;AAAA,gBACrB,QAAA,EAAU;AAAA,eACZ;AAAA,cACA,YAAY,WAAA,EAAa,KAAA;AAAA,cACzB,YAAA,EAAc,eAAA;AAAA,cACd,gBAAA,EAAkB;AAAA,gBAChB,QAAA,EAAU,IAAA;AAAA,gBACV,MAAA,EAAQA,MAAM,MAAA,CAAO,MAAA;AAAA,gBACrB,QAAA,EAAU;AAAA;AACZ,aACF;AAAA,YACA,QAAA;AAAA,YACA,eAAA;AAAA,YACA,kBAAkB,MAChB,kBAAA,CAAmB,eAAA,KAAoB,OAAA,GAAU,aAAa,OAAO,CAAA;AAAA,YAEvE,qBAAA,EAAuB,CAAC,CAAC,qBAAA;AAAA,YACzB,aAAA,EAAe,iBAAA;AAAA,YACf,UAAA,EAAY,cAAA;AAAA,YACZ,OAAA,EAAS,CAAC,CAAC;AAAA;AAAA;AACb;AAAA;AAAA,GACF;AAEJ;ACjNA,IAAM,eAAA,GAA4C;AAAA,EAChD,UAAA,EAAY,WAAA;AAAA,EACZ,WAAA,EAAa,UAAA;AAAA,EACb,aAAA,EAAe,cAAA;AAAA,EACf,cAAA,EAAgB;AAClB,CAAA;AAEA,IAAM,eAAA,GAAkB,CAAC,EAAE,EAAA,EAAI,WAAU,KAAyC;AAChF,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,YAAA,CAAa;AAAA,IAClC;AAAA,GACD,CAAA;AACD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIL,SAAS,KAAK,CAAA;AAElD,EAAA,aAAA,CAAc;AAAA,IACZ,aAAa,MAAM;AACjB,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB,CAAA;AAAA,IACA,WAAW,MAAM;AACf,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB;AAAA,GACD,CAAA;AAED,EAAA,uBACEI,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,UAAA;AAAA,MACL,WAAW,CAAA,wBAAA,EAA2B,SAAS,CAAA,iDAAA,EAC7C,UAAA,GAAa,sEAAsE,EACrF,CAAA;AAAA;AAAA,GACF;AAEJ,CAAA;AAEA,IAAM,iBAAqB,MAAM;AAC/B,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIJ,SAAS,KAAK,CAAA;AAElD,EAAA,aAAA,CAAc;AAAA,IACZ,aAAa,MAAM;AACjB,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB,CAAA;AAAA,IACA,WAAW,MAAM;AACf,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB;AAAA,GACD,CAAA;AAED,EAAA,uBACEG,IAAAA,CAAAc,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAb,GAAAA,CAAC,eAAA,EAAA,EAAgB,EAAA,EAAG,UAAA,EAAW,WAAU,eAAA,EAAgB,CAAA;AAAA,oBACzDA,GAAAA,CAAC,eAAA,EAAA,EAAgB,EAAA,EAAG,WAAA,EAAY,WAAU,gBAAA,EAAiB,CAAA;AAAA,oBAC3DA,GAAAA,CAAC,eAAA,EAAA,EAAgB,EAAA,EAAG,aAAA,EAAc,WAAU,kBAAA,EAAmB,CAAA;AAAA,oBAC/DA,GAAAA,CAAC,eAAA,EAAA,EAAgB,EAAA,EAAG,cAAA,EAAe,WAAU,mBAAA,EAAoB,CAAA;AAAA,oBACjEA,IAAC,WAAA,EAAA,EAAa,QAAA,EAAA,UAAA,mBAAaA,GAAAA,CAAC,WAAA,EAAA,EAAY,IAAK,IAAA,EAAK;AAAA,GAAA,EACpD,CAAA;AAEJ,CAAA;AAOO,IAAM,UAA6B,CAAC,EAAE,QAAA,EAAU,WAAA,GAAc,OAAM,KAAM;AAC/E,EAAA,MAAM,aAAac,kBAAAA,EAAmB;AACtC,EAAA,MAAM,EAAE,YAAA,EAAc,WAAA,EAAY,GAAIL,YAAAA,EAAa;AACnD,EAAA,MAAM,QAAA,GAAWF,SAAS,oBAAoB,CAAA;AAC9C,EAAA,MAAM,SAAA,GAAYQ,OAAuB,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAInB,SAAS,CAAC,CAAA;AAElD,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAA,IAAY,WAAA,IAAe,CAAC,UAAU,OAAA,EAAS;AACpD,IAAA,MAAM,KAAK,SAAA,CAAU,OAAA;AACrB,IAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,CAAC,OAAA,KAAY;AAC/C,MAAA,MAAM,KAAA,GAAQ,QAAQ,CAAC,CAAA;AACvB,MAAA,IAAI,KAAA,EAAO,eAAA,CAAgB,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA;AAAA,IACrD,CAAC,CAAA;AACD,IAAA,QAAA,CAAS,QAAQ,EAAE,CAAA;AACnB,IAAA,eAAA,CAAgB,EAAA,CAAG,qBAAA,EAAsB,CAAE,MAAM,CAAA;AACjD,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,QAAA,EAAU,WAAW,CAAC,CAAA;AAE1B,EAAA,MAAM,OAAA,GAAU,UAAA;AAAA,IACd,UAAU,aAAA,EAAe;AAAA,MACvB,oBAAA,EAAsB;AAAA,QACpB,QAAA,EAAU;AAAA;AACZ,KACD;AAAA,GACH;AAEA,EAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAwB;AAC7C,IAAA,MAAM,EAAE,MAAK,GAAI,KAAA;AACjB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,WAAA,CAAY,cAAA,EAAgB,KAAK,EAAa,CAAA;AAAA,IAChD;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,gBAAA,CAAiB,QAAQ,CAAA;AACxD,EAAA,MAAM,YAAA,GAAe,cAAc,eAAA,GAAkB,UAAA;AAErD,EAAA,MAAM,iBAAA,GAAoB,CAAC,MAAA,KAAoB;AAC7C,IAAA,QAAQ,MAAA;AAAQ,MACd,KAAK,UAAA;AACH,QAAA,OAAO,eAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,gBAAA;AAAA,MACT,KAAK,aAAA;AACH,QAAA,OAAO,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,MACxB,KAAK,cAAA;AACH,QAAA,OAAO,GAAG,YAAY,CAAA,QAAA,CAAA;AAAA;AAC1B,EACF,CAAA;AAGA,EAAA,MAAM,sBAAA,GAAyB,CAAC,MAAA,KAAoB;AAClD,IAAA,MAAM,QAAA,GAAW,gBAAgB,MAAM,CAAA;AACvC,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,QAAA,CAAS,MAAM,IAAI,SAAA,GAAY,SAAA;AAC3D,IAAA,OAAO,CAAA,OAAA,EAAU,YAAY,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,EAC7C,CAAA;AAEA,EAAA,MAAM,SAAA,mBACJE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,CAAA,2CAAA,CAAA,EACb,QAAA,EAAA;AAAA,IAAA,QAAA,mBACCA,IAAAA,CAAAc,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,CAAC,WAAA,oBACAb,GAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,SAAA,EAAW,SAAA,EAAU,kDAAA,EAC7B,QAAA,kBAAAA,GAAAA,CAAC,WAAA,EAAA,EAAY,cAAA,EAAc,MAAC,CAAA,EAC9B,CAAA;AAAA,sBAEFA,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,8BAAA;AAAA,UACV,KAAA,EAAO,EAAE,SAAA,EAAW,WAAA,GAAc,IAAI,YAAA,GAAe,CAAA,GAAI,eAAe,GAAA,EAAI;AAAA,UAE3E;AAAA;AAAA;AACH,KAAA,EACF,CAAA,mBAEAD,IAAAA,CAAAc,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,CAAC,WAAA,oBACAd,IAAAA,CAAAc,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAb,IAAC,cAAA,EAAA,EAAe,CAAA;AAAA,wBAChBA,GAAAA,CAAC,IAAA,EAAA,EAAK,wBAAA,EAA0B,sBAAA,CAAuB,YAAY,CAAA,EAAG,CAAA;AAAA,wBACtEA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,CAAA,eAAA,EAAkB,iBAAA,CAAkB,YAAY,CAAC,CAAA,qCAAA,CAAA;AAAA,YAE5D,QAAA,kBAAAA,IAAC,WAAA,EAAA,EAAY;AAAA;AAAA;AACf,OAAA,EACF,CAAA;AAAA,MAED;AAAA,KAAA,EACH,CAAA;AAAA,oBAGFA,IAAC,iBAAA,EAAA,EAAkB;AAAA,GAAA,EACrB,CAAA;AAKF,EAAA,uBACEA,GAAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAkB,SAAA,EAAW,eAAe,SAAA,EAAW,CAAC,qBAAqB,CAAA,EACtF,QAAA,EAAA,SAAA,EACH,CAAA;AAEJ,CAAA;AAEA,IAAM,gBAAA,GAAmB,CAAC,EAAE,QAAA,EAAS,KAAyB;AAC5D,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAIS,YAAAA,EAAa;AACrC,EAAA,MAAM,EAAE,IAAA,EAAK,GAAIE,OAAAA,EAAQ;AACzB,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,WAAA,GAAc,CAAC,CAAC,GAAA,EAAK,WAAA;AAG3B,EAAA,sBAAA,EAAuB;AACvB,EAAA,oBAAA,EAAqB;AAErB,EAAA,MAAM,aAAaG,kBAAAA,EAAmB;AACtC,EAAA,MAAM,EAAE,WAAA,EAAa,eAAA,EAAgB,GAAI,YAAA,EAAa;AAEtD,EAAAjB,UAAU,MAAM;AACd,IAAA,MAAM,EAAE,eAAA,EAAgB,GAAIY,YAAAA,CAAa,QAAA,EAAS;AAClD,IAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,gBAAA,CAAiB,QAAQ,CAAA;AAE1D,IAAA,IAAA,CAAK,CAAC,IAAA,IAAQ,CAAC,KAAA,KAAU,UAAA,CAAW,OAAO,IAAA,IAAQ,CAAC,aAAA,IAAiB,CAAC,eAAA,EAAiB;AACrF,MAAA,UAAA,CAAW,oBAAA,EAAqB;AAGhC,MAAA,MAAM,EAAE,mBAAA,EAAqB,WAAA,EAAa,eAAA,EAAgB,GAAIA,aAAa,QAAA,EAAS;AAEpF,MAAA,mBAAA,EAAoB;AAGpB,MAAA,eAAA,CAAgB,cAAc,KAAK,CAAA;AACnC,MAAA,eAAA,CAAgB,cAAA,EAAgB,EAAE,CAAA;AAClC,MAAA,eAAA,CAAgB,uBAAuB,CAAC,CAAA;AAGxC,MAAA,eAAA,CAAgB,iBAAiB,MAAS,CAAA;AAC1C,MAAA,eAAA,CAAgB,mBAAmB,MAAS,CAAA;AAE5C,MAAA,eAAA,CAAgB,QAAQ,MAAM,CAAA;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,KAAA,EAAO,UAAA,EAAY,eAAe,CAAC,CAAA;AAE7C,EAAA,MAAM,cAAA,mBACJT,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAS,CAAA,EAC5C,CAAA;AAGF,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,KAAA,EAAO;AACnB,IAAA,uBACED,IAAAA,CAAAc,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,cAAA;AAAA,sBACDb,IAAC,iBAAA,EAAA,EAAkB;AAAA,KAAA,EACrB,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,uBACED,IAAAA,CAAAc,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,cAAA;AAAA,sBACDb,IAAC,iBAAA,EAAA,EAAkB;AAAA,KAAA,EACrB,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACED,IAAAA,CAAAc,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAb,GAAAA,CAAC,OAAA,EAAA,EAAQ,WAAA,EAAa,WAAA,EAAc,QAAA,EAAS,CAAA;AAAA,oBAC7CA,IAAC,iBAAA,EAAA,EAAkB;AAAA,GAAA,EACrB,CAAA;AAEJ,CAAA;AAEO,IAAM,WAAA,GAAc,CAAC,EAAE,QAAA,EAAS,qBACrCA,GAAAA,CAAC,WAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,gBAAA,EAAA,EAAkB,QAAA,EAAS,CAAA,EAC9B;AClPF,SAAS,kBAAkB,CAAA,EAAmB;AAC5C,EAAA,OAAO,sBAAA,GAAyB,IAAI,uBAAA,GAA0B,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,WAAA;AACrF;AAMO,SAAS,cAAA,CAAe,EAAE,SAAA,EAAU,EAAyB;AAClE,EAAA,MAAM,eAAA,GAAkBS,YAAAA,CAAa,CAAC,CAAA,KAAM,EAAE,eAAe,CAAA;AAC7D,EAAA,MAAM,WAAA,GAAcA,YAAAA,CAAa,CAAC,CAAA,KAAM,EAAE,WAAW,CAAA;AACrD,EAAA,MAAM,WAAA,GAAcX,WAAAA;AAAA,IAClB,CAAC,IAAA,KAA+B,WAAA,CAAY,iBAAA,EAAmB,IAAI,CAAA;AAAA,IACnE,CAAC,WAAW;AAAA,GACd;AACA,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIF,SAAS,CAAC,CAAA;AAC1D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,QAAAA,CAAS;AAAA,IACrC,OAAO,SAAA,CAAU,UAAA;AAAA,IACjB,QAAQ,SAAA,CAAU;AAAA,GACnB,CAAA;AAED,EAAA,MAAM,EAAE,qBAAA,EAAuB,qBAAA,EAAsB,GAAIoB,wBAAAA,EAAyB;AAClF,EAAA,MAAM,EAAE,mBAAA,EAAqB,eAAA,EAAiB,eAAA,EAAiB,WAAA,KAC7DR,mBAAAA,EAAoB;AAEtB,EAAA,MAAM,mBAAmBS,cAAAA,CAAe;AAAA,IACtC,MAAA,EAAQhB,MAAM,MAAA,CAAO,UAAA;AAAA,IACrB,QAAA,EAAU,CAAC,OAAA,EAAkB,eAAA,KAA6B;AACxD,MAAA,IAAI,eAAA,wBAAuC,OAAO,CAAA;AAAA,IACpD;AAAA,GACD,CAAA;AACD,EAAA,MAAM,eAAegB,cAAAA,CAAe;AAAA,IAClC,MAAA,EAAQhB,MAAM,MAAA,CAAO,MAAA;AAAA,IACrB,QAAA,EAAU,CAAC,OAAA,EAAkB,eAAA,KAA6B;AACxD,MAAA,IAAI,eAAA,wBAAuC,OAAO,CAAA;AAAA,IACpD;AAAA,GACD,CAAA;AAED,EAAA,MAAM,sBAAA,GAAyBH,YAAY,MAAM,gBAAA,CAAiB,QAAO,EAAG,CAAC,gBAAgB,CAAC,CAAA;AAC9F,EAAA,MAAM,kBAAA,GAAqBA,YAAY,MAAM,YAAA,CAAa,QAAO,EAAG,CAAC,YAAY,CAAC,CAAA;AAElF,EAAA,MAAM;AAAA,IACJ,kBAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,MACE,oBAAA,EAAqB;AAGzB,EAAAD,UAAU,MAAM;AACd,IAAA,MAAM,UAAA,GAAa,MACjB,UAAA,CAAW,EAAE,KAAA,EAAO,UAAU,UAAA,EAAY,MAAA,EAAQ,SAAA,CAAU,WAAA,EAAa,CAAA;AAC3E,IAAA,UAAA,EAAW;AACX,IAAA,SAAA,CAAU,gBAAA,CAAiB,UAAU,UAAU,CAAA;AAC/C,IAAA,OAAO,MAAM,SAAA,CAAU,mBAAA,CAAoB,QAAA,EAAU,UAAU,CAAA;AAAA,EACjE,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAId,EAAA,MAAM,iBAAA,GAAoBe,QAAQ,MAAM;AACtC,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,OAAO,IAAI,iBAAA,IAAqB,iBAAA,CAAkB,IAAI,CAAC,CAAA,IAAK,QAAQ,MAAA,EAAQ;AAC1E,MAAA,CAAA,EAAA;AAAA,IACF;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAA,CAAQ,MAAA,EAAQ,iBAAiB,CAAC,CAAA;AAEtC,EAAA,MAAM,wBAAA,GAA2BA,OAAAA;AAAA,IAC/B,MAAM,YAAA,CAAa,KAAA,CAAM,gBAAA,EAAkB,mBAAmB,iBAAiB,CAAA;AAAA,IAC/E,CAAC,YAAA,EAAc,gBAAA,EAAkB,iBAAiB;AAAA,GACpD;AACA,EAAA,MAAM,eAAe,gBAAA,GAAmB,CAAA;AACxC,EAAA,MAAM,YAAA,GAAe,mBAAmB,iBAAA,GAAoB,iBAAA;AAE5D,EAAAf,UAAU,MAAM;AACd,IAAA,IAAI,gBAAA,GAAmB,iBAAA,GAAoB,iBAAA,IAAqB,iBAAA,GAAoB,CAAA,EAAG;AACrF,MAAA,mBAAA,CAAoB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,iBAAA,GAAoB,iBAAiB,CAAC,CAAA;AAAA,IACxE;AAAA,EACF,CAAA,EAAG,CAAC,iBAAA,EAAmB,iBAAA,EAAmB,gBAAgB,CAAC,CAAA;AAE3D,EAAA,MAAM,UAAA,mBACJG,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qFAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,iFAAA,EAAc,CAAA,EAC1C,CAAA;AAGF,EAAA,MAAM,KAAA,GAAQE,EAAAA;AAAA,IACZ;AAAA,GACF;AAEA,EAAA,uBACEH,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2DAAA,EACZ,QAAA,EAAA,eAAA,KAAoB,6BACnBD,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,iEAAA;AAAA,QACV,KAAA,EAAO,EAAE,GAAA,EAAK,WAAA,EAAY;AAAA,QAEzB,QAAA,EAAA;AAAA,UAAA,wBAAA,CAAyB,WAAW,CAAA,GACjC,UAAA,GACA,yBAAyB,GAAA,CAAI,CAAC,6BAC5BC,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,SAAA,EAAU,yDAAA;AAAA,cACV,KAAA,EAAO,EAAE,SAAA,EAAW,uBAAA,EAAwB;AAAA,cAE5C,QAAA,kBAAAA,GAAAA;AAAA,gBAACkB,eAAAA;AAAA,gBAAA;AAAA,kBACC,QAAA;AAAA,kBACA,aAAa,QAAA,CAAS,WAAA;AAAA,kBACtB,SAAA,EAAU,sCAAA;AAAA,kBACV,oBAAA,EAAoB;AAAA;AAAA;AACtB,aAAA;AAAA,YATK,GAAG,QAAA,CAAS,WAAA,CAAY,QAAQ,CAAA,CAAA,EAAI,SAAS,MAAM,CAAA;AAAA,WAW3D,CAAA;AAAA,0BACLlB,GAAAA;AAAA,YAAC,wBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,YAAA;AAAA,cACT,OAAA,EAAS,YAAA;AAAA,cACT,MAAA,EAAQ,MAAM,mBAAA,CAAoB,CAAC,CAAA,KAAM,KAAK,GAAA,CAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,cAC3D,MAAA,EAAQ,MACN,mBAAA,CAAoB,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,GAAoB,iBAAA,EAAmB,CAAA,GAAI,CAAC,CAAC;AAAA;AAAA;AAErF;AAAA;AAAA,KACF,GACE,kBAAA,mBACFD,IAAAA,CAAAc,UAAA,EACE,QAAA,EAAA;AAAA,sBAAAb,GAAAA;AAAA,QAACkB,eAAAA;AAAA,QAAA;AAAA,UACC,QAAA,EAAU,kBAAA;AAAA,UACV,aAAa,kBAAA,CAAmB,WAAA;AAAA,UAChC,SAAA,EAAU,eAAA;AAAA,UACV,oBAAA,EAAoB;AAAA;AAAA,OACtB;AAAA,MACC,iBAAA,GAAoB,qBACnBlB,GAAAA;AAAA,QAAC,yBAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,SAAA;AAAA,UACT,OAAA,EAAS,SAAA;AAAA,UACT,MAAA,EAAQ,QAAA;AAAA,UACR,MAAA,EAAQ,QAAA;AAAA,UACR,YAAA;AAAA,UACA;AAAA;AAAA;AACF,KAAA,EAEJ,IAEA,UAAA,EAEJ,CAAA;AAAA,oBAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yCAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,KAAA,EACd,QAAA,kBAAAA,GAAAA;AAAA,QAACmB,UAAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,mBAAA;AAAA,UACV,YAAY,eAAA,EAAiB,KAAA;AAAA,UAC7B,YAAA,EAAc,mBAAA;AAAA,UACd,gBAAA,EAAkB;AAAA,YAChB,QAAA,EAAU,IAAA;AAAA,YACV,MAAA,EAAQlB,MAAM,MAAA,CAAO,UAAA;AAAA,YACrB,QAAA,EAAU;AAAA,WACZ;AAAA,UACA,YAAY,WAAA,EAAa,KAAA;AAAA,UACzB,YAAA,EAAc,eAAA;AAAA,UACd,gBAAA,EAAkB;AAAA,YAChB,QAAA,EAAU,IAAA;AAAA,YACV,MAAA,EAAQA,MAAM,MAAA,CAAO,MAAA;AAAA,YACrB,QAAA,EAAU;AAAA;AACZ;AAAA,OACF,EACF,CAAA;AAAA,sBAEAD,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OACd,QAAA,kBAAAD,IAAAA,CAACK,SAAA,EACC,QAAA,EAAA;AAAA,wBAAAJ,GAAAA,CAACK,cAAAA,EAAA,EAAe,OAAA,EAAO,MACrB,QAAA,kBAAAL,GAAAA;AAAA,UAACG,MAAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,MAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,SAAS,MAAM,WAAA,CAAY,eAAA,KAAoB,OAAA,GAAU,aAAa,OAAO,CAAA;AAAA,YAC7E,SAAA,EAAU,gEAAA;AAAA,YACV,YAAA,EAAY,eAAA,KAAoB,OAAA,GAAU,uFAAA,GAAoB,2EAAA;AAAA,YAE7D,QAAA,EAAA,eAAA,KAAoB,OAAA,mBACnBH,GAAAA,CAACoB,OAAA,EAAM,SAAA,EAAU,SAAA,EAAU,CAAA,mBAE3BpB,GAAAA,CAACqB,OAAAA,EAAA,EAAQ,WAAU,SAAA,EAAU;AAAA;AAAA,SAEjC,EACF,CAAA;AAAA,wBACArB,GAAAA,CAACM,cAAAA,EAAA,EACE,QAAA,EAAA,eAAA,KAAoB,OAAA,GACjB,gNACA,2EAAA,EACN;AAAA,OAAA,EACF,CAAA,EACF,CAAA;AAAA,sBAEAP,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAWG,EAAAA,CAAG,KAAA,EAAO,SAAS,CAAA,EACjC,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAACsB,iBAAAA,EAAA,EAAkB,SAAA,EAAU,mBAAA,EAAoB,CAAA;AAAA,wBACjDtB,GAAAA,CAACuB,eAAAA,EAAA,EAAgB,WAAU,mBAAA,EAAoB;AAAA,OAAA,EACjD,CAAA;AAAA,sBAEAvB,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,KAAA,EACd,QAAA,kBAAAA,GAAAA,CAACwB,gBAAAA,EAAA,EAAiB,SAAA,EAAU,8BAAA,EAA+B,CAAA,EAC7D;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"index.mjs","sourcesContent":["/** Высота шапки приложения (top-16) */\nexport const HEADER_HEIGHT_PX = 64;\n/** Тулбар доски сверху и снизу при работе на доске */\nexport const BOARD_TOP_TOOLBAR_PX = 64;\nexport const BOARD_BOTTOM_TOOLBAR_PX = 64;\n/** Нижний отступ: при доске — тулбар доски, иначе общий отступ */\nexport const BOTTOM_OFFSET_BOARD_PX = BOARD_BOTTOM_TOOLBAR_PX;\nexport const BOTTOM_OFFSET_DEFAULT_PX = 16;\nexport const COMPACT_BOTTOM_BAR_PX = 40;\nexport const TILES_PADDING_PX = 16;\n\nexport const TILE_MIN_HEIGHT_PX = 120;\nexport const TILE_GAP_PX = 8;\n\n/** Вертикальный padding контейнера expanded-режима (p-1: 4px сверху + 4px снизу) */\nexport const EXPANDED_VIDEO_PADDING_VERTICAL_PX = 8;\n/** Отступ между областью видео и нижней панелью (mb-2 на контейнере видео) */\nexport const COMPACT_VIDEO_AREA_MARGIN_PX = 8;\n/** Нижний отступ compact call на странице доски, соответствует CSS bottom-[72px] */\nexport const COMPACT_BOTTOM_OFFSET_BOARD_PX = BOARD_BOTTOM_TOOLBAR_PX + TILE_GAP_PX; // 72\n\n/** Ширина панели компакт-ВКС (с запасом под кнопку чата); высота плитки 16:9 при этой ширине */\nexport const COMPACT_PANEL_WIDTH_PX = 360;\nexport const TILE_HEIGHT_16_9_PX = Math.round((COMPACT_PANEL_WIDTH_PX * 9) / 16); // 203 при ширине 360\n\n/** Размеры окна PiP Document */\nexport const PIP_PANEL_WIDTH_PX = 380;\nexport const PIP_BAR_HEIGHT_PX = 48;\n/** Зазор между областью видео и нижней панелью в PiP (gap-1) */\nexport const PIP_VIDEO_BAR_GAP_PX = 4;\n/** Внутренний вертикальный padding области плиток в PiP expanded (p-0.5) */\nexport const PIP_EXPANDED_INNER_PADDING_PX = 4;\n/**\n * Высота, всегда резервируемая под панель и отступы в PiP (панель всегда видна).\n * bar + gap + outer padding + inner padding области плиток.\n */\nexport const PIP_RESERVED_HEIGHT_PX =\n PIP_BAR_HEIGHT_PX +\n PIP_VIDEO_BAR_GAP_PX +\n EXPANDED_VIDEO_PADDING_VERTICAL_PX +\n PIP_EXPANDED_INNER_PADDING_PX;\n/** Высота одной плитки 16:9 при ширине PiP */\nexport const PIP_TILE_HEIGHT_16_9_PX = Math.round((PIP_PANEL_WIDTH_PX * 9) / 16);\n/** Дополнительные 36px высоты при открытии/ресайзе PiP (basic и expanded) */\nexport const PIP_EXTRA_HEIGHT_PX = 36;\n/** Ещё 12px при expanded (переключение basic → expanded) */\nexport const PIP_EXTRA_HEIGHT_EXPANDED_PX = 12;\n/** Высота окна PiP в basic: панель + одна плитка 16:9 + padding */\nexport const PIP_HEIGHT_BASIC_PX =\n PIP_BAR_HEIGHT_PX + PIP_TILE_HEIGHT_16_9_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX;\n\n/**\n * Высота окна PiP в expanded: панель + до 4 плиток 16:9 + зазоры + padding + доп. высота.\n * @param participantCount — число участников (локальный + удалённые)\n */\nexport function getPipHeightExpandedPx(participantCount: number): number {\n const n = Math.min(Math.max(1, participantCount), 4);\n return (\n PIP_BAR_HEIGHT_PX +\n n * PIP_TILE_HEIGHT_16_9_PX +\n (n - 1) * TILE_GAP_PX +\n EXPANDED_VIDEO_PADDING_VERTICAL_PX +\n PIP_EXTRA_HEIGHT_PX +\n PIP_EXTRA_HEIGHT_EXPANDED_PX\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n BOTTOM_OFFSET_DEFAULT_PX,\n COMPACT_BOTTOM_OFFSET_BOARD_PX,\n HEADER_HEIGHT_PX,\n} from '../constants';\n\n/**\n * Максимальная высота, доступная для всего контейнера compact call\n * (видеообласть + нижняя панель). Соответствует CSS-позиционированию\n * top-16 / bottom-[72px] | bottom-4 в CompactView.\n */\nfunction calcAvailableHeight(isOnBoardPage: boolean): number {\n if (typeof window === 'undefined') return 400;\n const bottomOffset = isOnBoardPage\n ? COMPACT_BOTTOM_OFFSET_BOARD_PX // 72, matches bottom-[72px]\n : BOTTOM_OFFSET_DEFAULT_PX; // 16, matches bottom-4\n return window.innerHeight - HEADER_HEIGHT_PX - bottomOffset;\n}\n\nexport function useCompactAvailableHeight(isOnBoardPage: boolean): number {\n const initialHeight = useMemo(() => calcAvailableHeight(isOnBoardPage), [isOnBoardPage]);\n const [availableHeight, setAvailableHeight] = useState(initialHeight);\n\n useEffect(() => {\n setAvailableHeight(initialHeight);\n const onResize = () => setAvailableHeight(calcAvailableHeight(isOnBoardPage));\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isOnBoardPage, initialHeight]);\n\n return availableHeight;\n}\n","import { useState, useEffect } from 'react';\nimport { Track } from 'livekit-client';\nimport { useTracks } from '@livekit/components-react';\nimport { useScreenShareCleanup, useSortedTracks } from '@xipkg/calls-hooks';\n\nexport const useCompactNavigation = () => {\n const [currentParticipantIndex, setCurrentParticipantIndex] = useState(0);\n\n // Получаем треки через useTracks (как в VideoGrid) для автоматического обновления\n const participants = useTracks(\n [\n { source: Track.Source.Camera, withPlaceholder: true },\n { source: Track.Source.ScreenShare, withPlaceholder: false },\n ],\n {\n onlySubscribed: false, // Получаем все треки, включая неподписанные для корректного подсчета участников\n },\n );\n\n // Автоматическое удаление треков демонстрации экрана при их завершении\n useScreenShareCleanup(participants);\n\n const sorted = useSortedTracks(participants, 1);\n\n const currentParticipant = sorted[currentParticipantIndex] || null;\n const totalParticipants = sorted.length;\n\n const canGoNext = currentParticipantIndex < totalParticipants - 1;\n const canGoPrev = currentParticipantIndex > 0;\n\n const goToNext = () => {\n if (canGoNext) {\n setCurrentParticipantIndex((prev) => prev + 1);\n }\n };\n\n const goToPrev = () => {\n if (canGoPrev) {\n setCurrentParticipantIndex((prev) => prev - 1);\n }\n };\n\n const goToParticipant = (index: number) => {\n if (index >= 0 && index < totalParticipants) {\n setCurrentParticipantIndex(index);\n }\n };\n\n // Сброс индекса при изменении количества участников\n useEffect(() => {\n if (currentParticipantIndex >= totalParticipants && totalParticipants > 0) {\n setCurrentParticipantIndex(Math.max(0, totalParticipants - 1));\n }\n }, [totalParticipants, currentParticipantIndex]);\n\n // useTracks автоматически обновляется при изменениях треков,\n // поэтому дополнительные обработчики событий не нужны\n\n return {\n currentParticipant,\n participants: sorted,\n currentIndex: currentParticipantIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n goToParticipant,\n };\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\ndeclare global {\n interface DocumentPictureInPicture {\n requestWindow(options?: {\n width?: number;\n height?: number;\n disallowReturnToOpener?: boolean;\n preferInitialWindowPlacement?: boolean;\n }): Promise<Window>;\n window: Window | null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface DocumentPictureInPictureEvent extends Event {}\n\n interface Window {\n documentPictureInPicture?: DocumentPictureInPicture;\n }\n\n // setMicrophoneActive / setCameraActive есть в Chrome 93+, в lib.dom.d.ts пока нет\n interface MediaSession {\n setMicrophoneActive(active: boolean): void;\n setCameraActive(active: boolean): void;\n }\n}\n\ntype UseDocumentPiPOptions = {\n width?: number;\n height?: number;\n enabled?: boolean;\n microphoneActive?: boolean;\n cameraActive?: boolean;\n};\n\nfunction copyStylesToWindow(targetWindow: Window) {\n [...document.styleSheets].forEach((styleSheet) => {\n try {\n const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');\n const style = document.createElement('style');\n style.textContent = cssRules;\n targetWindow.document.head.appendChild(style);\n } catch {\n if (styleSheet.href) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.type = styleSheet.type || 'text/css';\n link.media = styleSheet.media.mediaText;\n link.href = styleSheet.href;\n targetWindow.document.head.appendChild(link);\n }\n }\n });\n\n try {\n document.fonts.forEach((font) => {\n targetWindow.document.fonts.add(font);\n });\n } catch {\n // ignore\n }\n}\n\nexport function useDocumentPiP({\n width = 380,\n height = 270,\n enabled = true,\n microphoneActive = false,\n cameraActive = false,\n}: UseDocumentPiPOptions = {}) {\n const [pipWindow, setPipWindow] = useState<Window | null>(null);\n const pipWindowRef = useRef<Window | null>(null);\n const micActiveRef = useRef(microphoneActive);\n const camActiveRef = useRef(cameraActive);\n\n micActiveRef.current = microphoneActive;\n camActiveRef.current = cameraActive;\n\n const isSupported = typeof window !== 'undefined' && 'documentPictureInPicture' in window;\n\n // Chrome для авто-PiP при видеозвонках требует setCameraActive / setMicrophoneActive\n useEffect(() => {\n if (!enabled) return;\n try {\n navigator.mediaSession.setMicrophoneActive(microphoneActive);\n } catch {\n // ignore\n }\n try {\n navigator.mediaSession.setCameraActive(cameraActive);\n } catch {\n // ignore\n }\n }, [enabled, microphoneActive, cameraActive]);\n\n const openPiP = useCallback(\n async (overrides?: { width?: number; height?: number }): Promise<Window | null> => {\n if (!isSupported || !enabled) return null;\n if (pipWindowRef.current) return pipWindowRef.current;\n\n const w = overrides?.width ?? width;\n const h = overrides?.height ?? height;\n\n try {\n const pip = await window.documentPictureInPicture!.requestWindow({\n width: w,\n height: h,\n });\n\n copyStylesToWindow(pip);\n\n pip.document.body.style.margin = '0';\n pip.document.body.style.overflow = 'hidden';\n pip.document.body.style.background = 'var(--xi-gray-0, #fff)';\n\n pipWindowRef.current = pip;\n setPipWindow(pip);\n\n pip.addEventListener('pagehide', () => {\n pipWindowRef.current = null;\n setPipWindow(null);\n });\n\n return pip;\n } catch {\n return null;\n }\n },\n [isSupported, enabled, width, height],\n );\n\n const closePiP = useCallback(() => {\n if (pipWindowRef.current) {\n pipWindowRef.current.close();\n }\n }, []);\n\n // Регистрируем Media Session handler — Chrome вызывает его сам при переключении вкладки.\n // Handler должен быть зарегистрирован и не сниматься (компонент не размонтироваться при роутинге).\n useEffect(() => {\n if (!isSupported || !enabled) return;\n\n const action = 'enterpictureinpicture' as MediaSessionAction;\n try {\n navigator.mediaSession.setActionHandler(action, () => void openPiP());\n } catch {\n // enterpictureinpicture не поддерживается\n }\n\n return () => {\n try {\n navigator.mediaSession.setActionHandler(action, null);\n } catch {\n // ignore\n }\n };\n }, [isSupported, enabled, openPiP]);\n\n // Закрываем PiP при возврате на вкладку\n useEffect(() => {\n if (!enabled) return;\n\n const handleVisibilityChange = () => {\n if (!document.hidden && pipWindowRef.current) {\n closePiP();\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => document.removeEventListener('visibilitychange', handleVisibilityChange);\n }, [enabled, closePiP]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n pipWindowRef.current?.close();\n pipWindowRef.current = null;\n };\n }, []);\n\n const resizePiP = useCallback((w: number, h: number) => {\n if (pipWindowRef.current) {\n try {\n pipWindowRef.current.resizeTo(w, h);\n } catch {\n // ignore\n }\n }\n }, []);\n\n return {\n isSupported,\n pipWindow,\n isPiPActive: pipWindow !== null,\n openPiP,\n closePiP,\n resizePiP,\n };\n}\n","import { createContext, useCallback, useContext, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useLocalParticipant } from '@livekit/components-react';\nimport { useDocumentPiP, useCompactNavigation } from '../hooks';\nimport { PiPCompactCall } from '../ui';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { useMedia } from '@xipkg/calls-utils';\nimport {\n getPipHeightExpandedPx,\n PIP_EXTRA_HEIGHT_PX,\n PIP_HEIGHT_BASIC_PX,\n PIP_PANEL_WIDTH_PX,\n} from '../constants';\n\ntype PiPContextValue = {\n openPiP: () => Promise<void>;\n isPiPActive: boolean;\n isSupported: boolean;\n};\n\nconst PiPContext = createContext<PiPContextValue | null>(null);\n\nexport function usePiP() {\n const ctx = useContext(PiPContext);\n return ctx;\n}\n\nfunction getMediaStreamTrack(\n pub: { track?: { mediaStreamTrack?: MediaStreamTrack } } | undefined,\n): MediaStreamTrack | undefined {\n return pub?.track?.mediaStreamTrack;\n}\n\nfunction useMediaCaptureLive() {\n const { microphoneTrack, cameraTrack } = useLocalParticipant();\n const micTrack = getMediaStreamTrack(microphoneTrack);\n const camTrack = getMediaStreamTrack(cameraTrack);\n const micLive = !!micTrack && micTrack.readyState === 'live' && micTrack.enabled;\n const camLive = !!camTrack && camTrack.readyState === 'live' && camTrack.enabled;\n return { micLive, camLive };\n}\n\ntype PiPProviderProps = {\n children: React.ReactNode;\n};\n\n/**\n * Предоставляет API PiP (openPiP, isSupported) дочерним компонентам и управляет\n * Document Picture-in-Picture (логика из PiPManager).\n */\nexport function PiPProvider({ children }: PiPProviderProps) {\n const isMobile = useMedia('(max-width: 720px)');\n const { micLive, camLive } = useMediaCaptureLive();\n const { room } = useRoom();\n const compactViewMode = useCallStore((s) => s.compactViewMode);\n const { totalParticipants } = useCompactNavigation();\n\n const {\n pipWindow,\n closePiP,\n resizePiP,\n openPiP: openPiPRaw,\n isSupported,\n } = useDocumentPiP({\n enabled: !isMobile,\n width: PIP_PANEL_WIDTH_PX,\n height: PIP_HEIGHT_BASIC_PX,\n microphoneActive: micLive,\n cameraActive: camLive,\n });\n\n const openPiP = useCallback(async () => {\n const height =\n compactViewMode === 'basic' ? PIP_HEIGHT_BASIC_PX : getPipHeightExpandedPx(totalParticipants);\n await openPiPRaw({ height });\n }, [openPiPRaw, compactViewMode, totalParticipants]);\n\n useEffect(() => {\n if (!room || !pipWindow) return;\n if (room.state !== 'connected') {\n closePiP();\n return;\n }\n const handleState = () => {\n if (room.state !== 'connected') closePiP();\n };\n room.on('connectionStateChanged', handleState);\n return () => {\n room.off('connectionStateChanged', handleState);\n };\n }, [room, pipWindow, closePiP]);\n\n useEffect(() => {\n if (!pipWindow || !resizePiP) return;\n const height =\n compactViewMode === 'basic'\n ? PIP_HEIGHT_BASIC_PX + PIP_EXTRA_HEIGHT_PX\n : getPipHeightExpandedPx(totalParticipants);\n resizePiP(PIP_PANEL_WIDTH_PX, height);\n }, [pipWindow, resizePiP, compactViewMode, totalParticipants]);\n\n const value: PiPContextValue = {\n openPiP,\n isPiPActive: pipWindow !== null,\n isSupported: isSupported && !isMobile,\n };\n\n return (\n <PiPContext.Provider value={value}>\n {children}\n {pipWindow && createPortal(<PiPCompactCall pipWindow={pipWindow} />, pipWindow.document.body)}\n </PiPContext.Provider>\n );\n}\n","import { useAudioWaveform } from '@livekit/components-react';\nimport type { LocalAudioTrack, RemoteAudioTrack } from 'livekit-client';\nimport { Participant, Track } from 'livekit-client';\nimport { ChevronBottom, MicrophoneOff, RedLine } from '@xipkg/icons';\nimport { Button } from '@xipkg/button';\nimport { ParticipantName, TrackMutedIndicator, RaisedHandIndicator } from '@xipkg/calls-ui';\nimport { cn } from '@xipkg/utils';\n\ntype CompactCallCollapsedBarProps = {\n participant: Participant | null;\n audioTrack?: LocalAudioTrack | RemoteAudioTrack | null;\n onExpand: () => void;\n className?: string;\n};\n\nexport function CompactCallCollapsedBar({\n participant,\n audioTrack,\n onExpand,\n className,\n}: CompactCallCollapsedBarProps) {\n const { bars } = useAudioWaveform(audioTrack ?? undefined, {\n barCount: 24,\n volMultiplier: 4,\n updateInterval: 50,\n });\n return (\n <div\n className={cn(\n 'bg-gray-20 flex items-center gap-2 rounded-2xl px-2 py-2 shadow-lg',\n className,\n )}\n >\n {/* Тот же блок, что и в плитке участника ВКС: микрофон + имя */}\n <div className=\"bg-gray-0/80 flex h-6 max-w-[45%] min-w-0 shrink gap-1.5 rounded-lg px-1.5 py-1 backdrop-blur\">\n {participant ? (\n <>\n <TrackMutedIndicator\n trackRef={{\n participant,\n source: Track.Source.Microphone,\n }}\n show=\"muted\"\n style={{ marginRight: '0.45rem', background: 'transparent' }}\n />\n <span className=\"flex min-w-0 truncate\">\n <ParticipantName participant={participant} />\n </span>\n </>\n ) : (\n <>\n <div className=\"relative w-3 shrink-0\">\n <MicrophoneOff className=\"absolute h-4 w-4 fill-gray-100\" />\n <RedLine className=\"fill-red-80 absolute h-4 w-4\" />\n </div>\n <span className=\"text-xs-base-size leading-[16px] text-gray-100\">Нет участников</span>\n </>\n )}\n </div>\n {participant && <RaisedHandIndicator participant={participant ?? 'unknown'} />}\n <div className=\"flex min-w-0 flex-1 items-center justify-center gap-0.5 py-1\">\n {bars.length > 0 ? (\n <div className=\"flex h-4 items-end justify-center gap-0.5\">\n {bars.map((h, i) => (\n <div\n key={i}\n className=\"bg-brand-80 w-0.5 min-w-[2px] rounded-full transition-all duration-75\"\n style={{ height: `${Math.min(100, Math.max(20, h * 150))}%` }}\n />\n ))}\n </div>\n ) : (\n <div className=\"bg-brand-60 h-2 w-12 rounded-full\" />\n )}\n </div>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={onExpand}\n className=\"bg-brand-100 hover:bg-brand-100/80 h-8 w-8 shrink-0 rounded-xl p-0 text-gray-100\"\n aria-label=\"Развернуть\"\n >\n <ChevronBottom className=\"fill-gray-0 h-4 w-4\" />\n </Button>\n </div>\n );\n}\n","import { ArrowLeft, ArrowRight } from '@xipkg/icons';\n\ninterface CompactNavigationControlsProps {\n canPrev: boolean;\n canNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n currentIndex: number;\n totalParticipants: number;\n}\n\n/**\n * Элементы управления навигацией для компактного вида\n * Показывает кнопки навигации и индикаторы участников только при наведении\n */\nexport function CompactNavigationControls({\n canPrev,\n canNext,\n onPrev,\n onNext,\n currentIndex,\n totalParticipants,\n}: CompactNavigationControlsProps) {\n if (totalParticipants <= 1) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0\">\n {/* Индикатор участников вверху */}\n <div className=\"pointer-events-auto absolute top-2 left-1/2 -translate-x-1/2\">\n <div className=\"bg-gray-10/80 flex gap-1 rounded-full px-2 py-1 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n {Array.from({ length: totalParticipants }, (_, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => {\n // Здесь можно добавить логику для прямого перехода к участнику\n // Пока оставляем только навигацию через кнопки\n }}\n className={`h-1.5 w-1.5 rounded-full transition-colors ${\n index === currentIndex ? 'bg-gray-100' : 'bg-gray-100/50 hover:bg-gray-100/75'\n }`}\n aria-label={`Участник ${index + 1}`}\n />\n ))}\n </div>\n </div>\n\n {/* Кнопка \"Предыдущий участник\" */}\n <div className=\"pointer-events-auto absolute top-1/2 left-2 -translate-y-1/2 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n <button\n type=\"button\"\n disabled={!canPrev}\n onClick={onPrev}\n className=\"bg-gray-10/80 hover:bg-gray-10 z-10 flex items-center justify-center rounded-full fill-gray-100 p-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n <span className=\"sr-only\">Предыдущий участник</span>\n </button>\n </div>\n\n {/* Кнопка \"Следующий участник\" */}\n <div className=\"pointer-events-auto absolute top-1/2 right-2 -translate-y-1/2 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n <button\n type=\"button\"\n disabled={!canNext}\n onClick={onNext}\n className=\"bg-gray-10/80 hover:bg-gray-10 z-10 flex items-center justify-center rounded-full fill-gray-100 p-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ArrowRight className=\"h-4 w-4\" />\n <span className=\"sr-only\">Следующий участник</span>\n </button>\n </div>\n </div>\n );\n}\n","import { ArrowUp } from '@xipkg/icons';\n\ninterface CompactMultiViewControlsProps {\n canPrev: boolean;\n canNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n}\n\n/**\n * Стрелки листания для развёрнутого мульти-вида ВКС:\n * сверху на первой плитке — стрелка вверх, снизу на последней — стрелка вниз\n */\nexport function CompactMultiViewControls({\n canPrev,\n canNext,\n onPrev,\n onNext,\n}: CompactMultiViewControlsProps) {\n return (\n <div className=\"pointer-events-none absolute inset-0\">\n {/* Стрелка вверх — по центру сверху (на первой плитке), если есть куда листать */}\n {canPrev && (\n <div className=\"pointer-events-auto absolute top-2 left-1/2 z-10 -translate-x-1/2\">\n <button\n type=\"button\"\n onClick={onPrev}\n className=\"bg-gray-10/80 hover:bg-gray-10 flex items-center justify-center rounded-full fill-gray-100 p-2\"\n aria-label=\"Листать вверх\"\n >\n <ArrowUp className=\"h-4 w-4 fill-inherit\" />\n </button>\n </div>\n )}\n {/* Стрелка вниз — по центру снизу (на последней плитке) */}\n {canNext && (\n <div className=\"pointer-events-auto absolute bottom-2 left-1/2 z-10 -translate-x-1/2\">\n <button\n type=\"button\"\n onClick={onNext}\n className=\"bg-gray-10/80 hover:bg-gray-10 flex items-center justify-center rounded-full fill-gray-100 p-2\"\n aria-label=\"Листать вниз\"\n >\n <ArrowUp className=\"h-4 w-4 rotate-180 fill-inherit\" />\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';\nimport { Button } from '@xipkg/button';\nimport { ChevronUp, External } from '@xipkg/icons';\nimport { cn } from '@xipkg/utils';\nimport { usePiP } from '../providers';\nimport { CompactCallCollapsedBar } from './CompactCallCollapsedBar';\nimport { CompactNavigationControls } from './CompactNavigationControls';\nimport { CompactMultiViewControls } from './CompactMultiViewControls';\nimport { ParticipantTile } from '@xipkg/calls-ui';\nimport { TILE_GAP_PX, TILE_HEIGHT_16_9_PX } from '../constants';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\n\ntype CompactCallVideoAreaProps = {\n isMobile: boolean;\n isCollapsed: boolean;\n onCollapsedChange: (collapsed: boolean) => void;\n withOutShadows: boolean;\n dragAttributes?: object;\n dragListeners?: object;\n /** Режим вида на десктопе */\n compactViewMode: 'basic' | 'expanded';\n currentParticipant: TrackReferenceOrPlaceholder | null;\n currentAudioTrack:\n | import('livekit-client').RemoteAudioTrack\n | import('livekit-client').LocalAudioTrack\n | null;\n totalParticipants: number;\n canGoPrev: boolean;\n canGoNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n currentIndex: number;\n multiVisibleParticipants: TrackReferenceOrPlaceholder[];\n multiTileHeightPx: number;\n multiCanPrev: boolean;\n multiCanNext: boolean;\n onMultiPrev: () => void;\n onMultiNext: () => void;\n};\n\nexport function CompactCallVideoArea({\n isMobile,\n isCollapsed,\n onCollapsedChange,\n withOutShadows,\n dragAttributes = {},\n dragListeners = {},\n compactViewMode,\n currentParticipant,\n currentAudioTrack,\n totalParticipants,\n canGoPrev,\n canGoNext,\n onPrev,\n onNext,\n currentIndex,\n multiVisibleParticipants,\n multiTileHeightPx,\n multiCanPrev,\n multiCanNext,\n onMultiPrev,\n onMultiNext,\n}: CompactCallVideoAreaProps) {\n const pip = usePiP();\n const showPiPButton = pip?.isSupported && currentParticipant;\n\n const emptyState = (\n <div className=\"bg-gray-40 flex h-full w-full items-center justify-center text-gray-100\">\n <span className=\"text-sm\">Нет участников</span>\n </div>\n );\n\n if (isMobile && isCollapsed) {\n return (\n <CompactCallCollapsedBar\n participant={currentParticipant?.participant ?? null}\n audioTrack={currentAudioTrack ?? null}\n onExpand={() => onCollapsedChange(false)}\n className={cn('mb-2', withOutShadows ? '' : 'shadow-lg')}\n />\n );\n }\n\n return (\n <div\n {...(isMobile ? {} : { ...dragAttributes, ...dragListeners })}\n className={cn(\n 'group relative mb-2 flex overflow-hidden rounded-2xl',\n withOutShadows ? '' : 'shadow-lg',\n isMobile ? 'h-auto w-full items-center justify-center' : 'w-[360px] cursor-move flex-col',\n !isMobile && compactViewMode === 'basic' && 'shrink-0',\n !isMobile && compactViewMode === 'expanded' && 'h-auto',\n )}\n style={!isMobile && compactViewMode === 'basic' ? { height: TILE_HEIGHT_16_9_PX } : undefined}\n >\n {isMobile ? (\n currentParticipant ? (\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n ) : (\n emptyState\n )\n ) : compactViewMode === 'expanded' ? (\n <div\n className=\"relative flex flex-col gap-2 overflow-hidden rounded-2xl p-1\"\n style={{ gap: TILE_GAP_PX }}\n >\n {multiVisibleParticipants.length === 0\n ? emptyState\n : multiVisibleParticipants.map((trackRef) => (\n <div\n key={`${trackRef.participant.identity}-${trackRef.source}`}\n className=\"aspect-video w-full shrink-0 overflow-hidden rounded-xl\"\n style={{ minHeight: multiTileHeightPx }}\n >\n <ParticipantTile\n trackRef={trackRef}\n participant={trackRef.participant}\n className=\"h-full w-full [&_video]:object-cover\"\n isFocusToggleDisable\n />\n </div>\n ))}\n <CompactMultiViewControls\n canPrev={multiCanPrev}\n canNext={multiCanNext}\n onPrev={onMultiPrev}\n onNext={onMultiNext}\n />\n </div>\n ) : currentParticipant ? (\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n ) : (\n emptyState\n )}\n\n {showPiPButton && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => void pip!.openPiP()}\n className=\"bg-gray-10/80 hover:bg-gray-10 text-gray-0 absolute top-2 right-2 z-10 h-8 w-8 rounded-xl p-0\"\n aria-label=\"Открыть в отдельном окне\"\n >\n <External className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Открыть в отдельном окне</TooltipContent>\n </Tooltip>\n )}\n\n {isMobile && (\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => onCollapsedChange(true)}\n className=\"bg-brand-100 hover:bg-brand-100/80 absolute top-2 right-2 z-10 h-8 w-8 rounded-xl p-0 text-gray-100\"\n aria-label=\"Свернуть\"\n >\n <ChevronUp className=\"fill-gray-0 h-4 w-4\" />\n </Button>\n )}\n\n {totalParticipants > 0 && (isMobile || compactViewMode === 'basic') && (\n <CompactNavigationControls\n canPrev={canGoPrev}\n canNext={canGoNext}\n onPrev={onPrev}\n onNext={onNext}\n currentIndex={currentIndex}\n totalParticipants={totalParticipants}\n />\n )}\n </div>\n );\n}\n","import type { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';\nimport { Button } from '@xipkg/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from '@xipkg/dropdown';\nimport { Account, Maximize, Users, WhiteBoard } from '@xipkg/icons';\nimport { cn } from '@xipkg/utils';\nimport { DevicesBar, DisconnectButton, ScreenShareButton } from '@xipkg/calls-ui';\nimport { ChatButton } from '@xipkg/calls-chat';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\n\ntype CompactCallDevicesPropsT = {\n microTrack: LocalAudioTrack | undefined;\n microEnabled: boolean;\n microTrackToggle: {\n showIcon: boolean;\n source: import('livekit-client').Track.Source;\n onChange: () => void;\n };\n videoTrack: LocalVideoTrack | undefined;\n videoEnabled: boolean;\n videoTrackToggle: {\n showIcon: boolean;\n source: import('livekit-client').Track.Source;\n onChange: () => void;\n };\n};\n\ntype CompactCallBottomBarPropsT = {\n withOutShadows: boolean;\n devices: CompactCallDevicesPropsT;\n isMobile: boolean;\n compactViewMode: 'basic' | 'expanded';\n onViewModeToggle: () => void;\n showBackToBoardButton: boolean;\n onBackToBoard: () => void;\n onMaximize: (syncToAll?: boolean) => void;\n isTutor: boolean;\n};\n\nexport function CompactCallBottomBar({\n withOutShadows,\n devices,\n isMobile,\n compactViewMode,\n onViewModeToggle,\n showBackToBoardButton,\n onBackToBoard,\n onMaximize,\n isTutor,\n}: CompactCallBottomBarPropsT) {\n const barCn = cn(\n 'bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-1',\n withOutShadows ? '' : 'shadow-lg',\n );\n\n return (\n <div className=\"flex h-[40px] flex-row\">\n <div className={barCn}>\n <DevicesBar\n className=\"h-[32px] w-[32px]\"\n microTrack={devices.microTrack}\n microEnabled={devices.microEnabled}\n microTrackToggle={devices.microTrackToggle}\n videoTrack={devices.videoTrack}\n videoEnabled={devices.videoEnabled}\n videoTrackToggle={devices.videoTrackToggle}\n />\n </div>\n\n {!isMobile && (\n <div className={cn(barCn, 'ml-1')}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={onViewModeToggle}\n className=\"hover:bg-gray-5 h-8 w-8 rounded-xl p-0 text-gray-100\"\n aria-label={compactViewMode === 'basic' ? 'Развёрнутый вид' : 'Один участник'}\n >\n {compactViewMode === 'basic' ? (\n <Users className=\"h-5 w-5\" />\n ) : (\n <Account className=\"h-5 w-5\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {compactViewMode === 'basic'\n ? 'Развёрнутый вид (несколько участников)'\n : 'Один участник'}\n </TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {showBackToBoardButton && (\n <div className={cn(barCn, 'ml-1')}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"primary\"\n className=\"h-8 w-8 rounded-xl p-0\"\n onClick={onBackToBoard}\n aria-label=\"На доску\"\n >\n <WhiteBoard className=\"fill-gray-0 h-5 w-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Обратно на доску</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n <div className={cn(barCn, 'ml-auto')}>\n <ScreenShareButton className=\"h-[32px] w-[32px]\" />\n <ChatButton className=\"h-8 w-8 min-w-8 rounded-xl\" />\n <RaiseHandButton className=\"h-[32px] w-[32px]\" />\n </div>\n\n <div className={cn(barCn, 'ml-1')}>\n {isTutor ? (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n className=\"hover:bg-gray-5 relative m-0 h-8 w-8 rounded-xl p-0 text-gray-100\"\n >\n <Maximize className=\"fill-gray-100\" />\n </Button>\n </DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent>Вернуться в конференцию</TooltipContent>\n </Tooltip>\n <DropdownMenuContent side=\"top\" align=\"end\" className=\"z-1000 min-w-[200px]\">\n <DropdownMenuLabel className=\"text-gray-60 text-sm\">\n Вернуть в конференцию\n </DropdownMenuLabel>\n <DropdownMenuItem\n onClick={() => onMaximize(false)}\n className=\"text-gray-80 cursor-pointer text-sm\"\n >\n Только меня\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => onMaximize(true)}\n className=\"text-gray-80 cursor-pointer text-sm\"\n >\n Всех участников\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => onMaximize(false)}\n className=\"hover:bg-gray-5 relative m-0 h-8 w-8 rounded-xl p-0 text-gray-100\"\n >\n <Maximize className=\"fill-gray-100\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Вернуться в конференцию</TooltipContent>\n </Tooltip>\n )}\n <DisconnectButton className=\"h-[32px] w-[32px] rounded-xl\" />\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDraggable } from '@dnd-kit/core';\nimport { CSS } from '@dnd-kit/utilities';\nimport {\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { useCompactAvailableHeight, useCompactNavigation } from '../hooks';\nimport { useVideoBlur, useModeSync } from '@xipkg/calls-hooks';\nimport { useRoom, useCalls, useCallsNavigation } from '@xipkg/calls-providers';\nimport { useMedia } from '@xipkg/calls-utils';\nimport { CompactCallVideoArea } from './CompactCallVideoArea';\nimport { CompactCallBottomBar } from './CompactCallBottomBar';\nimport {\n COMPACT_BOTTOM_BAR_PX,\n COMPACT_VIDEO_AREA_MARGIN_PX,\n EXPANDED_VIDEO_PADDING_VERTICAL_PX,\n TILE_GAP_PX,\n TILE_HEIGHT_16_9_PX,\n} from '../constants';\n\nexport const CompactCall = ({ saveUserChoices = true, withOutShadows = false }) => {\n const isMobile = useMedia('(max-width: 720px)');\n const { attributes, listeners, setNodeRef, transform } = useDraggable({\n id: 'draggable-call',\n disabled: isMobile,\n });\n const style = isMobile ? undefined : { transform: CSS.Translate.toString(transform) };\n\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices({\n preventSave: !saveUserChoices,\n });\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n const videoTrack = cameraTrack?.track as LocalVideoTrack | undefined;\n\n const mode = useCallStore((state) => state.mode);\n useVideoBlur(mode === 'compact' ? videoTrack : null);\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveAudioInputEnabled(enabled);\n },\n });\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveVideoInputEnabled(enabled);\n },\n });\n\n const handleMicrophoneToggle = useCallback(() => microphoneToggle.toggle(), [microphoneToggle]);\n const handleCameraToggle = useCallback(() => cameraToggle.toggle(), [cameraToggle]);\n\n const compactNavigation = useCompactNavigation();\n const {\n currentParticipant,\n participants,\n currentIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n } = compactNavigation;\n const callsNavigation = useCallsNavigation();\n\n const [isCollapsed, setIsCollapsed] = useState(false);\n const compactViewMode = useCallStore((state) => state.compactViewMode);\n const updateStore = useCallStore((state) => state.updateStore);\n const setCompactViewMode = useCallback(\n (mode: 'basic' | 'expanded') => updateStore('compactViewMode', mode),\n [updateStore],\n );\n const [multiScrollIndex, setMultiScrollIndex] = useState(0);\n\n const currentAudioTrack = currentParticipant?.participant?.getTrackPublication(\n Track.Source.Microphone,\n )?.track as\n | import('livekit-client').RemoteAudioTrack\n | import('livekit-client').LocalAudioTrack\n | undefined;\n\n const { syncModeToOthers } = useModeSync();\n const activeBoardId = useCallStore((state) => state.activeBoardId);\n const activeClassroom = useCallStore((state) => state.activeClassroom);\n const { room } = useRoom();\n const token = useCallStore((state) => state.token);\n\n const { data: user } = useCalls().auth.useCurrentUser();\n\n const isTutor = user?.default_layout === 'tutor';\n const isBoardPage = callsNavigation.pathnameIncludes('/board');\n const isOnBoardPage =\n callsNavigation.params.classroomId === activeClassroom &&\n callsNavigation.params.boardId === activeBoardId;\n const showBackToBoardButton =\n mode === 'compact' && !!activeBoardId && !!activeClassroom && !isOnBoardPage;\n\n const availableHeight = useCompactAvailableHeight(isBoardPage);\n\n const multiViewLayout = useMemo(() => {\n const heightForTiles = Math.max(\n 0,\n availableHeight -\n COMPACT_BOTTOM_BAR_PX -\n EXPANDED_VIDEO_PADDING_VERTICAL_PX -\n COMPACT_VIDEO_AREA_MARGIN_PX,\n );\n // Плитки имеют aspect-video (16:9), их высота фиксирована шириной контейнера\n const visibleCount = Math.min(\n totalParticipants,\n Math.max(1, Math.floor((heightForTiles + TILE_GAP_PX) / (TILE_HEIGHT_16_9_PX + TILE_GAP_PX))),\n );\n return { visibleCount, tileHeightPx: TILE_HEIGHT_16_9_PX };\n }, [availableHeight, totalParticipants]);\n\n const { visibleCount: multiVisibleCount, tileHeightPx: multiTileHeightPx } = multiViewLayout;\n const multiCanPrev = multiScrollIndex > 0;\n const multiCanNext = multiScrollIndex + multiVisibleCount < totalParticipants;\n const multiVisibleParticipants = participants.slice(\n multiScrollIndex,\n multiScrollIndex + multiVisibleCount,\n );\n\n useEffect(() => {\n if (multiScrollIndex + multiVisibleCount > totalParticipants && totalParticipants > 0) {\n setMultiScrollIndex(Math.max(0, totalParticipants - multiVisibleCount));\n }\n }, [totalParticipants, multiVisibleCount, multiScrollIndex]);\n\n const handleBackToBoard = useCallback(() => {\n if (!activeBoardId || !activeClassroom) return;\n callsNavigation.navigateToClassroomBoard(activeClassroom, activeBoardId);\n }, [activeBoardId, activeClassroom, callsNavigation]);\n\n const handleMaximize = useCallback(\n (syncToAll: boolean = false) => {\n if (!room || !token || room.state !== 'connected') return;\n const callParam = callsNavigation.search.call;\n const targetCallId =\n (typeof callParam === 'string' ? callParam.replace(/^\"|\"$/g, '').trim() : '') ||\n activeClassroom ||\n callsNavigation.params.classroomId ||\n callsNavigation.getCallId() ||\n '';\n if (syncToAll && isTutor && activeBoardId && targetCallId) {\n updateStore('localFullView', false);\n updateStore('mode', 'full');\n updateStore('activeBoardId', undefined);\n updateStore('activeClassroom', undefined);\n syncModeToOthers('full', undefined, targetCallId);\n } else {\n updateStore('localFullView', true);\n updateStore('mode', 'full');\n }\n if (targetCallId) {\n callsNavigation.navigateToCall(targetCallId, { replace: true });\n }\n },\n [\n room,\n token,\n callsNavigation,\n activeClassroom,\n isTutor,\n activeBoardId,\n updateStore,\n syncModeToOthers,\n ],\n );\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={`compact-call-container flex flex-col ${isMobile ? 'w-full' : 'w-[360px]'}`}\n >\n <CompactCallVideoArea\n isMobile={isMobile}\n isCollapsed={isCollapsed}\n onCollapsedChange={setIsCollapsed}\n withOutShadows={withOutShadows}\n dragAttributes={attributes as object}\n dragListeners={listeners as object}\n compactViewMode={compactViewMode}\n currentParticipant={currentParticipant}\n currentAudioTrack={currentAudioTrack ?? null}\n totalParticipants={totalParticipants}\n canGoPrev={canGoPrev}\n canGoNext={canGoNext}\n onPrev={goToPrev}\n onNext={goToNext}\n currentIndex={currentIndex}\n multiVisibleParticipants={multiVisibleParticipants}\n multiTileHeightPx={multiTileHeightPx}\n multiCanPrev={multiCanPrev}\n multiCanNext={multiCanNext}\n onMultiPrev={() => setMultiScrollIndex((i) => Math.max(0, i - 1))}\n onMultiNext={() =>\n setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1))\n }\n />\n <CompactCallBottomBar\n withOutShadows={withOutShadows}\n devices={{\n microTrack: microphoneTrack?.track as LocalAudioTrack,\n microEnabled: isMicrophoneEnabled,\n microTrackToggle: {\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n },\n videoTrack: cameraTrack?.track as unknown as LocalVideoTrack,\n videoEnabled: isCameraEnabled,\n videoTrackToggle: {\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n },\n }}\n isMobile={isMobile}\n compactViewMode={compactViewMode}\n onViewModeToggle={() =>\n setCompactViewMode(compactViewMode === 'basic' ? 'expanded' : 'basic')\n }\n showBackToBoardButton={!!showBackToBoardButton}\n onBackToBoard={handleBackToBoard}\n onMaximize={handleMaximize}\n isTutor={!!isTutor}\n />\n </div>\n );\n};\n","import { FC, useEffect, useRef, useState } from 'react';\nimport {\n DndContext,\n DragEndEvent,\n useSensor,\n useSensors,\n PointerSensor,\n useDroppable,\n DragOverlay,\n useDndMonitor,\n} from '@dnd-kit/core';\nimport { useCallsNavigation } from '@xipkg/calls-providers';\nimport { restrictToWindowEdges } from '@dnd-kit/modifiers';\nimport { RoomAudioRenderer } from '@livekit/components-react';\nimport { CompactCall } from './CompactCall';\nimport { Chat, useChatStore } from '@xipkg/calls-chat';\nimport { PermissionsDialog } from '@xipkg/calls-ui';\nimport { useCallStore } from '@xipkg/calls-store';\nimport type { CornerT } from '@xipkg/calls-store';\nimport { useMedia } from '@xipkg/calls-utils';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { PiPProvider, usePiP } from '../providers';\nimport { useParticipantSounds, useParticipantJoinSync } from '@xipkg/calls-hooks';\n\ntype CompactViewPropsT = {\n children: React.ReactNode;\n};\n\nconst OPPOSITE_CORNER: Record<CornerT, CornerT> = {\n 'top-left': 'top-right',\n 'top-right': 'top-left',\n 'bottom-left': 'bottom-right',\n 'bottom-right': 'bottom-left',\n};\n\nconst DroppableCorner = ({ id, className }: { id: string; className: string }) => {\n const { setNodeRef } = useDroppable({\n id,\n });\n const [isDragging, setIsDragging] = useState(false);\n\n useDndMonitor({\n onDragStart: () => {\n setIsDragging(true);\n },\n onDragEnd: () => {\n setIsDragging(false);\n },\n });\n\n return (\n <div\n ref={setNodeRef}\n className={`absolute z-100 size-1/3 ${className} pointer-events-none transition-all duration-200 ${\n isDragging ? 'bg-brand-0/20 ring-brand-20 pointer-events-auto rounded-lg ring-2' : ''\n }`}\n />\n );\n};\n\nconst DroppableAreas: FC = () => {\n const [isDragging, setIsDragging] = useState(false);\n\n useDndMonitor({\n onDragStart: () => {\n setIsDragging(true);\n },\n onDragEnd: () => {\n setIsDragging(false);\n },\n });\n\n return (\n <>\n <DroppableCorner id=\"top-left\" className=\"top-16 left-4\" />\n <DroppableCorner id=\"top-right\" className=\"top-16 right-4\" />\n <DroppableCorner id=\"bottom-left\" className=\"bottom-18 left-4\" />\n <DroppableCorner id=\"bottom-right\" className=\"right-4 bottom-18\" />\n <DragOverlay>{isDragging ? <CompactCall /> : null}</DragOverlay>\n </>\n );\n};\n\ntype CompactPropsT = CompactViewPropsT & {\n /** При true не рендерить оверлей (звонок, чат, углы). Используется при PiP, чтобы children не размонтировались. */\n hideOverlay?: boolean;\n};\n\nexport const Compact: FC<CompactPropsT> = ({ children, hideOverlay = false }) => {\n const navigation = useCallsNavigation();\n const { activeCorner, updateStore } = useCallStore();\n const isMobile = useMedia('(max-width: 720px)');\n const headerRef = useRef<HTMLDivElement>(null);\n const [headerHeight, setHeaderHeight] = useState(0);\n\n useEffect(() => {\n if (!isMobile || hideOverlay || !headerRef.current) return;\n const el = headerRef.current;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) setHeaderHeight(entry.contentRect.height);\n });\n observer.observe(el);\n setHeaderHeight(el.getBoundingClientRect().height);\n return () => observer.disconnect();\n }, [isMobile, hideOverlay]);\n\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 8,\n },\n }),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { over } = event;\n if (over) {\n updateStore('activeCorner', over.id as CornerT);\n }\n };\n\n const isBoardPage = navigation.pathnameIncludes('/board');\n const bottomOffset = isBoardPage ? 'bottom-[72px]' : 'bottom-4';\n\n const getCornerPosition = (corner: CornerT) => {\n switch (corner) {\n case 'top-left':\n return 'top-16 left-4';\n case 'top-right':\n return 'top-16 right-4';\n case 'bottom-left':\n return `${bottomOffset} left-4`;\n case 'bottom-right':\n return `${bottomOffset} right-4`;\n }\n };\n\n /** Противоположный угол для чата (та же логика позиционирования, другой угол) */\n const getChatPositionClasses = (corner: CornerT) => {\n const opposite = OPPOSITE_CORNER[corner];\n const horizontal = opposite.includes('left') ? 'left-22' : 'right-4';\n return `top-32 ${bottomOffset} ${horizontal}`;\n };\n\n const container = (\n <div className={`relative flex h-dvh flex-col bg-transparent`}>\n {isMobile ? (\n <>\n {!hideOverlay && (\n <div ref={headerRef} className=\"fixed top-[64px] right-0 left-0 z-10 w-full px-2\">\n <CompactCall withOutShadows />\n </div>\n )}\n <div\n className=\"flex min-h-0 flex-1 flex-col\"\n style={{ marginTop: hideOverlay ? 0 : headerHeight > 0 ? headerHeight : 120 }}\n >\n {children}\n </div>\n </>\n ) : (\n <>\n {!hideOverlay && (\n <>\n <DroppableAreas />\n <Chat compactPositionClassName={getChatPositionClasses(activeCorner)} />\n <div\n className={`absolute z-100 ${getCornerPosition(activeCorner)} transition-all duration-500 ease-out`}\n >\n <CompactCall />\n </div>\n </>\n )}\n {children}\n </>\n )}\n\n <RoomAudioRenderer />\n </div>\n );\n\n // Всегда один и тот же корень (DndContext), иначе при hideOverlay React размонтирует\n // container и всё дерево доски (YjsProvider пересоздаётся → белый экран).\n return (\n <DndContext sensors={sensors} onDragEnd={handleDragEnd} modifiers={[restrictToWindowEdges]}>\n {container}\n </DndContext>\n );\n};\n\nconst CompactViewInner = ({ children }: CompactViewPropsT) => {\n const { mode, token } = useCallStore();\n const { room } = useRoom();\n const pip = usePiP();\n const isPiPActive = !!pip?.isPiPActive;\n\n // Синхронизация состояния при подключении новых участников (работает и в compact mode)\n useParticipantJoinSync();\n useParticipantSounds();\n\n const navigation = useCallsNavigation();\n const { updateStore: updateChatStore } = useChatStore();\n\n useEffect(() => {\n const { activeClassroom } = useCallStore.getState();\n const isOnBoardPage = navigation.pathnameIncludes('/board');\n\n if ((!room || !token) && navigation.search.call && !isOnBoardPage && !activeClassroom) {\n navigation.clearCallSearchParam();\n\n // Очищаем все состояния интерфейса при отключении\n const { clearAllRaisedHands, updateStore: updateCallStore } = useCallStore.getState();\n // Очищаем поднятые руки\n clearAllRaisedHands();\n\n // Очищаем чат\n updateChatStore('isChatOpen', false);\n updateChatStore('chatMessages', []);\n updateChatStore('unreadMessagesCount', 0);\n\n // Очищаем информацию о доске при отключении\n updateCallStore('activeBoardId', undefined);\n updateCallStore('activeClassroom', undefined);\n\n updateCallStore('mode', 'full');\n }\n }, [room, token, navigation, updateChatStore]);\n\n const contentWrapper = (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"min-h-0 flex-1\">{children}</div>\n </div>\n );\n\n if (!room || !token) {\n return (\n <>\n {contentWrapper}\n <PermissionsDialog />\n </>\n );\n }\n\n if (mode === 'full') {\n return (\n <>\n {contentWrapper}\n <PermissionsDialog />\n </>\n );\n }\n\n // Всегда один и тот же Compact — при PiP только скрываем оверлей (hideOverlay).\n return (\n <>\n <Compact hideOverlay={isPiPActive}>{children}</Compact>\n <PermissionsDialog />\n </>\n );\n};\n\nexport const CompactView = ({ children }: CompactViewPropsT) => (\n <PiPProvider>\n <CompactViewInner>{children}</CompactViewInner>\n </PiPProvider>\n);\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { Track, LocalAudioTrack, LocalVideoTrack } from 'livekit-client';\nimport { Account, Users } from '@xipkg/icons';\nimport { Button } from '@xipkg/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { cn } from '@xipkg/utils';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { useCompactNavigation } from '../hooks/useCompactNavigation';\nimport { ParticipantTile, DevicesBar, DisconnectButton, ScreenShareButton } from '@xipkg/calls-ui';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\nimport { CompactNavigationControls } from './CompactNavigationControls';\nimport { CompactMultiViewControls } from './CompactMultiViewControls';\nimport { PIP_RESERVED_HEIGHT_PX, PIP_TILE_HEIGHT_16_9_PX, TILE_GAP_PX } from '../constants';\n\n/**\n * Минимальная высота окна PiP, необходимая для отображения n полных плиток\n * вместе с панелью управления и всеми отступами.\n */\nfunction requiredPipHeight(n: number): number {\n return PIP_RESERVED_HEIGHT_PX + n * PIP_TILE_HEIGHT_16_9_PX + Math.max(0, n - 1) * TILE_GAP_PX;\n}\n\ntype PiPCompactCallPropsT = {\n pipWindow: Window;\n};\n\nexport function PiPCompactCall({ pipWindow }: PiPCompactCallPropsT) {\n const compactViewMode = useCallStore((s) => s.compactViewMode);\n const updateStore = useCallStore((s) => s.updateStore);\n const setViewMode = useCallback(\n (mode: 'basic' | 'expanded') => updateStore('compactViewMode', mode),\n [updateStore],\n );\n const [multiScrollIndex, setMultiScrollIndex] = useState(0);\n const [pipSize, setPipSize] = useState({\n width: pipWindow.innerWidth,\n height: pipWindow.innerHeight,\n });\n\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices();\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveAudioInputEnabled(enabled);\n },\n });\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveVideoInputEnabled(enabled);\n },\n });\n\n const handleMicrophoneToggle = useCallback(() => microphoneToggle.toggle(), [microphoneToggle]);\n const handleCameraToggle = useCallback(() => cameraToggle.toggle(), [cameraToggle]);\n\n const {\n currentParticipant,\n participants,\n currentIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n } = useCompactNavigation();\n\n // Размер окна PiP:\n useEffect(() => {\n const updateSize = () =>\n setPipSize({ width: pipWindow.innerWidth, height: pipWindow.innerHeight });\n updateSize();\n pipWindow.addEventListener('resize', updateSize);\n return () => pipWindow.removeEventListener('resize', updateSize);\n }, [pipWindow]);\n\n // Сколько полных плиток (16:9) помещается при текущей высоте окна.\n // Плитка добавляется, только когда есть полное место; убирается сразу, как перестаёт влезать.\n const multiVisibleCount = useMemo(() => {\n let n = 1;\n while (n < totalParticipants && requiredPipHeight(n + 1) <= pipSize.height) {\n n++;\n }\n return n;\n }, [pipSize.height, totalParticipants]);\n\n const multiVisibleParticipants = useMemo(\n () => participants.slice(multiScrollIndex, multiScrollIndex + multiVisibleCount),\n [participants, multiScrollIndex, multiVisibleCount],\n );\n const multiCanPrev = multiScrollIndex > 0;\n const multiCanNext = multiScrollIndex + multiVisibleCount < totalParticipants;\n\n useEffect(() => {\n if (multiScrollIndex + multiVisibleCount > totalParticipants && totalParticipants > 0) {\n setMultiScrollIndex(Math.max(0, totalParticipants - multiVisibleCount));\n }\n }, [totalParticipants, multiVisibleCount, multiScrollIndex]);\n\n const emptyState = (\n <div className=\"bg-gray-40 flex h-full w-full items-center justify-center rounded-2xl text-gray-100\">\n <span className=\"text-sm\">Нет участников</span>\n </div>\n );\n\n const barCn = cn(\n 'bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-0.5',\n );\n\n return (\n <div className=\"flex h-full flex-col gap-1 p-1\">\n <div className=\"group relative min-h-0 flex-1 overflow-hidden rounded-2xl\">\n {compactViewMode === 'expanded' ? (\n <div\n className=\"relative flex h-full flex-col overflow-hidden rounded-2xl p-0.5\"\n style={{ gap: TILE_GAP_PX }}\n >\n {multiVisibleParticipants.length === 0\n ? emptyState\n : multiVisibleParticipants.map((trackRef) => (\n <div\n key={`${trackRef.participant.identity}-${trackRef.source}`}\n className=\"aspect-video w-full shrink-0 overflow-hidden rounded-xl\"\n style={{ minHeight: PIP_TILE_HEIGHT_16_9_PX }}\n >\n <ParticipantTile\n trackRef={trackRef}\n participant={trackRef.participant}\n className=\"h-full w-full [&_video]:object-cover\"\n isFocusToggleDisable\n />\n </div>\n ))}\n <CompactMultiViewControls\n canPrev={multiCanPrev}\n canNext={multiCanNext}\n onPrev={() => setMultiScrollIndex((i) => Math.max(0, i - 1))}\n onNext={() =>\n setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1))\n }\n />\n </div>\n ) : currentParticipant ? (\n <>\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n {totalParticipants > 1 && (\n <CompactNavigationControls\n canPrev={canGoPrev}\n canNext={canGoNext}\n onPrev={goToPrev}\n onNext={goToNext}\n currentIndex={currentIndex}\n totalParticipants={totalParticipants}\n />\n )}\n </>\n ) : (\n emptyState\n )}\n </div>\n\n <div className=\"flex h-12 shrink-0 items-center gap-0.5\">\n <div className={barCn}>\n <DevicesBar\n className=\"h-[28px] w-[28px]\"\n microTrack={microphoneTrack?.track as LocalAudioTrack}\n microEnabled={isMicrophoneEnabled}\n microTrackToggle={{\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n }}\n videoTrack={cameraTrack?.track as unknown as LocalVideoTrack}\n videoEnabled={isCameraEnabled}\n videoTrackToggle={{\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n }}\n />\n </div>\n\n <div className={barCn}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => setViewMode(compactViewMode === 'basic' ? 'expanded' : 'basic')}\n className=\"hover:bg-gray-5 h-[28px] w-[28px] rounded-xl p-0 text-gray-100\"\n aria-label={compactViewMode === 'basic' ? 'Развёрнутый вид' : 'Один участник'}\n >\n {compactViewMode === 'basic' ? (\n <Users className=\"h-4 w-4\" />\n ) : (\n <Account className=\"h-4 w-4\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {compactViewMode === 'basic'\n ? 'Развёрнутый вид (несколько участников)'\n : 'Один участник'}\n </TooltipContent>\n </Tooltip>\n </div>\n\n <div className={cn(barCn, 'ml-auto')}>\n <ScreenShareButton className=\"h-[28px] w-[28px]\" />\n <RaiseHandButton className=\"h-[28px] w-[28px]\" />\n </div>\n\n <div className={barCn}>\n <DisconnectButton className=\"h-[28px] w-[28px] rounded-xl\" />\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/hooks/useCompactAvailableHeight.ts","../src/hooks/useCompactNavigation.ts","../src/hooks/useDocumentPiP.ts","../src/providers/PiPProvider.tsx","../src/ui/CompactCallCollapsedBar.tsx","../src/ui/CompactNavigationControls.tsx","../src/ui/CompactMultiViewControls.tsx","../src/ui/CompactCallVideoArea.tsx","../src/ui/CompactCallBottomBar.tsx","../src/ui/CompactCall.tsx","../src/ui/CompactView.tsx","../src/ui/PiPCompactCall.tsx"],"names":["useState","useEffect","useCallback","jsxs","jsx","Track","cn","Button","Tooltip","TooltipTrigger","TooltipContent","useMedia","useLocalParticipant","useCallStore","mode","useRoom","useMemo","Fragment","useCallsNavigation","useRef","Users","SoundTwo","Account","usePersistentUserChoices","useTrackToggle","ParticipantTile","DevicesBar","ScreenShareButton","RaiseHandButton","DisconnectButton"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { CompactViewModeT } from '@xipkg/calls-store';\n\n/** Высота шапки приложения (top-16) */\nexport const HEADER_HEIGHT_PX = 64;\n/**\n * Доп. зазор между fixed compact overlay и контентом доски на mobile.\n * marginTop контента = высота overlay + этот отступ.\n */\nexport const COMPACT_MOBILE_CONTENT_GAP_PX = 12;\n/** Fallback высоты overlay, пока ResizeObserver ещё не дал headerHeight */\nexport const COMPACT_MOBILE_OVERLAY_FALLBACK_PX = 120;\n/** Тулбар доски сверху и снизу при работе на доске */\nexport const BOARD_TOP_TOOLBAR_PX = 64;\nexport const BOARD_BOTTOM_TOOLBAR_PX = 64;\n/** Нижний отступ: при доске — тулбар доски, иначе общий отступ */\nexport const BOTTOM_OFFSET_BOARD_PX = BOARD_BOTTOM_TOOLBAR_PX;\nexport const BOTTOM_OFFSET_DEFAULT_PX = 16;\nexport const COMPACT_BOTTOM_BAR_PX = 40;\n/** Высота полоски «только аудио» (CompactCallCollapsedBar) */\nexport const COMPACT_AUDIO_BAR_HEIGHT_PX = 48;\nexport const TILES_PADDING_PX = 16;\n\nexport const TILE_MIN_HEIGHT_PX = 120;\nexport const TILE_GAP_PX = 8;\n\n/** Вертикальный padding контейнера expanded-режима (p-1: 4px сверху + 4px снизу) */\nexport const EXPANDED_VIDEO_PADDING_VERTICAL_PX = 8;\n/** Отступ между областью видео и нижней панелью (mb-2 на контейнере видео) */\nexport const COMPACT_VIDEO_AREA_MARGIN_PX = 8;\n/** Нижний отступ compact call на странице доски, соответствует CSS bottom-[72px] */\nexport const COMPACT_BOTTOM_OFFSET_BOARD_PX = BOARD_BOTTOM_TOOLBAR_PX + TILE_GAP_PX; // 72\n\n/** Ширина панели компакт-ВКС (с запасом под кнопку чата); высота плитки 16:9 при этой ширине */\nexport const COMPACT_PANEL_WIDTH_PX = 360;\nexport const TILE_HEIGHT_16_9_PX = Math.round((COMPACT_PANEL_WIDTH_PX * 9) / 16); // 203 при ширине 360\n\n/** Размеры окна PiP Document */\nexport const PIP_PANEL_WIDTH_PX = 380;\nexport const PIP_BAR_HEIGHT_PX = 48;\n/** Зазор между областью видео и нижней панелью в PiP (gap-1) */\nexport const PIP_VIDEO_BAR_GAP_PX = 4;\n/** Внутренний вертикальный padding области плиток в PiP expanded (p-0.5) */\nexport const PIP_EXPANDED_INNER_PADDING_PX = 4;\n/**\n * Высота, всегда резервируемая под панель и отступы в PiP (панель всегда видна).\n * bar + gap + outer padding + inner padding области плиток.\n */\nexport const PIP_RESERVED_HEIGHT_PX =\n PIP_BAR_HEIGHT_PX +\n PIP_VIDEO_BAR_GAP_PX +\n EXPANDED_VIDEO_PADDING_VERTICAL_PX +\n PIP_EXPANDED_INNER_PADDING_PX;\n/** Высота одной плитки 16:9 при ширине PiP */\nexport const PIP_TILE_HEIGHT_16_9_PX = Math.round((PIP_PANEL_WIDTH_PX * 9) / 16);\n/** Дополнительные 36px высоты при открытии/ресайзе PiP (basic и expanded) */\nexport const PIP_EXTRA_HEIGHT_PX = 36;\n/** Ещё 12px при expanded (переключение basic → expanded) */\nexport const PIP_EXTRA_HEIGHT_EXPANDED_PX = 12;\n/** Высота окна PiP в basic: панель + одна плитка 16:9 + padding */\nexport const PIP_HEIGHT_BASIC_PX =\n PIP_BAR_HEIGHT_PX + PIP_TILE_HEIGHT_16_9_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX;\n/** Высота окна PiP в режиме «только аудио» */\nexport const PIP_HEIGHT_AUDIO_PX =\n PIP_BAR_HEIGHT_PX + COMPACT_AUDIO_BAR_HEIGHT_PX + EXPANDED_VIDEO_PADDING_VERTICAL_PX;\n\nconst COMPACT_VIEW_MODES: CompactViewModeT[] = ['basic', 'expanded', 'audio'];\n\nexport function getNextCompactViewMode(current: CompactViewModeT): CompactViewModeT {\n const index = COMPACT_VIEW_MODES.indexOf(current);\n return COMPACT_VIEW_MODES[(index + 1) % COMPACT_VIEW_MODES.length];\n}\n\nexport function getPipHeightForMode(mode: CompactViewModeT, participantCount: number): number {\n if (mode === 'audio') return PIP_HEIGHT_AUDIO_PX;\n if (mode === 'basic') return PIP_HEIGHT_BASIC_PX;\n return getPipHeightExpandedPx(participantCount);\n}\n\n/**\n * Высота окна PiP в expanded: панель + до 4 плиток 16:9 + зазоры + padding + доп. высота.\n * @param participantCount — число участников (локальный + удалённые)\n */\nexport function getPipHeightExpandedPx(participantCount: number): number {\n const n = Math.min(Math.max(1, participantCount), 4);\n return (\n PIP_BAR_HEIGHT_PX +\n n * PIP_TILE_HEIGHT_16_9_PX +\n (n - 1) * TILE_GAP_PX +\n EXPANDED_VIDEO_PADDING_VERTICAL_PX +\n PIP_EXTRA_HEIGHT_PX +\n PIP_EXTRA_HEIGHT_EXPANDED_PX\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n BOTTOM_OFFSET_DEFAULT_PX,\n COMPACT_BOTTOM_OFFSET_BOARD_PX,\n HEADER_HEIGHT_PX,\n} from '../constants';\n\n/**\n * Максимальная высота, доступная для всего контейнера compact call\n * (видеообласть + нижняя панель). Соответствует CSS-позиционированию\n * top-16 / bottom-[72px] | bottom-4 в CompactView.\n */\nfunction calcAvailableHeight(isOnBoardPage: boolean): number {\n if (typeof window === 'undefined') return 400;\n const bottomOffset = isOnBoardPage\n ? COMPACT_BOTTOM_OFFSET_BOARD_PX // 72, matches bottom-[72px]\n : BOTTOM_OFFSET_DEFAULT_PX; // 16, matches bottom-4\n return window.innerHeight - HEADER_HEIGHT_PX - bottomOffset;\n}\n\nexport function useCompactAvailableHeight(isOnBoardPage: boolean): number {\n const initialHeight = useMemo(() => calcAvailableHeight(isOnBoardPage), [isOnBoardPage]);\n const [availableHeight, setAvailableHeight] = useState(initialHeight);\n\n useEffect(() => {\n setAvailableHeight(initialHeight);\n const onResize = () => setAvailableHeight(calcAvailableHeight(isOnBoardPage));\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isOnBoardPage, initialHeight]);\n\n return availableHeight;\n}\n","import { useState, useEffect } from 'react';\nimport { Track } from 'livekit-client';\nimport { useTracks } from '@livekit/components-react';\nimport { useScreenShareCleanup, useSortedTracks } from '@xipkg/calls-hooks';\n\nexport const useCompactNavigation = () => {\n const [currentParticipantIndex, setCurrentParticipantIndex] = useState(0);\n\n // Получаем треки через useTracks (как в VideoGrid) для автоматического обновления\n const participants = useTracks(\n [\n { source: Track.Source.Camera, withPlaceholder: true },\n { source: Track.Source.ScreenShare, withPlaceholder: false },\n ],\n {\n onlySubscribed: false, // Получаем все треки, включая неподписанные для корректного подсчета участников\n },\n );\n\n // Автоматическое удаление треков демонстрации экрана при их завершении\n useScreenShareCleanup(participants);\n\n const sorted = useSortedTracks(participants, 1);\n\n const currentParticipant = sorted[currentParticipantIndex] || null;\n const totalParticipants = sorted.length;\n\n const canGoNext = currentParticipantIndex < totalParticipants - 1;\n const canGoPrev = currentParticipantIndex > 0;\n\n const goToNext = () => {\n if (canGoNext) {\n setCurrentParticipantIndex((prev) => prev + 1);\n }\n };\n\n const goToPrev = () => {\n if (canGoPrev) {\n setCurrentParticipantIndex((prev) => prev - 1);\n }\n };\n\n const goToParticipant = (index: number) => {\n if (index >= 0 && index < totalParticipants) {\n setCurrentParticipantIndex(index);\n }\n };\n\n // Сброс индекса при изменении количества участников\n useEffect(() => {\n if (currentParticipantIndex >= totalParticipants && totalParticipants > 0) {\n setCurrentParticipantIndex(Math.max(0, totalParticipants - 1));\n }\n }, [totalParticipants, currentParticipantIndex]);\n\n // useTracks автоматически обновляется при изменениях треков,\n // поэтому дополнительные обработчики событий не нужны\n\n return {\n currentParticipant,\n participants: sorted,\n currentIndex: currentParticipantIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n goToParticipant,\n };\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\ndeclare global {\n interface DocumentPictureInPicture {\n requestWindow(options?: {\n width?: number;\n height?: number;\n disallowReturnToOpener?: boolean;\n preferInitialWindowPlacement?: boolean;\n }): Promise<Window>;\n window: Window | null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface DocumentPictureInPictureEvent extends Event {}\n\n interface Window {\n documentPictureInPicture?: DocumentPictureInPicture;\n }\n\n // setMicrophoneActive / setCameraActive есть в Chrome 93+, в lib.dom.d.ts пока нет\n interface MediaSession {\n setMicrophoneActive(active: boolean): void;\n setCameraActive(active: boolean): void;\n }\n}\n\ntype UseDocumentPiPOptions = {\n width?: number;\n height?: number;\n enabled?: boolean;\n microphoneActive?: boolean;\n cameraActive?: boolean;\n};\n\nfunction copyStylesToWindow(targetWindow: Window) {\n [...document.styleSheets].forEach((styleSheet) => {\n try {\n const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');\n const style = document.createElement('style');\n style.textContent = cssRules;\n targetWindow.document.head.appendChild(style);\n } catch {\n if (styleSheet.href) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.type = styleSheet.type || 'text/css';\n link.media = styleSheet.media.mediaText;\n link.href = styleSheet.href;\n targetWindow.document.head.appendChild(link);\n }\n }\n });\n\n try {\n document.fonts.forEach((font) => {\n targetWindow.document.fonts.add(font);\n });\n } catch {\n // ignore\n }\n}\n\nexport function useDocumentPiP({\n width = 380,\n height = 270,\n enabled = true,\n microphoneActive = false,\n cameraActive = false,\n}: UseDocumentPiPOptions = {}) {\n const [pipWindow, setPipWindow] = useState<Window | null>(null);\n const pipWindowRef = useRef<Window | null>(null);\n const micActiveRef = useRef(microphoneActive);\n const camActiveRef = useRef(cameraActive);\n\n micActiveRef.current = microphoneActive;\n camActiveRef.current = cameraActive;\n\n const isSupported = typeof window !== 'undefined' && 'documentPictureInPicture' in window;\n\n // Chrome для авто-PiP при видеозвонках требует setCameraActive / setMicrophoneActive\n useEffect(() => {\n if (!enabled) return;\n try {\n navigator.mediaSession.setMicrophoneActive(microphoneActive);\n } catch {\n // ignore\n }\n try {\n navigator.mediaSession.setCameraActive(cameraActive);\n } catch {\n // ignore\n }\n }, [enabled, microphoneActive, cameraActive]);\n\n const openPiP = useCallback(\n async (overrides?: { width?: number; height?: number }): Promise<Window | null> => {\n if (!isSupported || !enabled) return null;\n if (pipWindowRef.current) return pipWindowRef.current;\n\n const w = overrides?.width ?? width;\n const h = overrides?.height ?? height;\n\n try {\n const pip = await window.documentPictureInPicture!.requestWindow({\n width: w,\n height: h,\n });\n\n copyStylesToWindow(pip);\n\n pip.document.body.style.margin = '0';\n pip.document.body.style.overflow = 'hidden';\n pip.document.body.style.background = 'var(--xi-gray-0, #fff)';\n\n pipWindowRef.current = pip;\n setPipWindow(pip);\n\n pip.addEventListener('pagehide', () => {\n pipWindowRef.current = null;\n setPipWindow(null);\n });\n\n return pip;\n } catch {\n return null;\n }\n },\n [isSupported, enabled, width, height],\n );\n\n const closePiP = useCallback(() => {\n if (pipWindowRef.current) {\n pipWindowRef.current.close();\n }\n }, []);\n\n // Регистрируем Media Session handler — Chrome вызывает его сам при переключении вкладки.\n // Handler должен быть зарегистрирован и не сниматься (компонент не размонтироваться при роутинге).\n useEffect(() => {\n if (!isSupported || !enabled) return;\n\n const action = 'enterpictureinpicture' as MediaSessionAction;\n try {\n navigator.mediaSession.setActionHandler(action, () => void openPiP());\n } catch {\n // enterpictureinpicture не поддерживается\n }\n\n return () => {\n try {\n navigator.mediaSession.setActionHandler(action, null);\n } catch {\n // ignore\n }\n };\n }, [isSupported, enabled, openPiP]);\n\n // Закрываем PiP при возврате на вкладку\n useEffect(() => {\n if (!enabled) return;\n\n const handleVisibilityChange = () => {\n if (!document.hidden && pipWindowRef.current) {\n closePiP();\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => document.removeEventListener('visibilitychange', handleVisibilityChange);\n }, [enabled, closePiP]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n pipWindowRef.current?.close();\n pipWindowRef.current = null;\n };\n }, []);\n\n const resizePiP = useCallback((w: number, h: number) => {\n if (pipWindowRef.current) {\n try {\n pipWindowRef.current.resizeTo(w, h);\n } catch {\n // ignore\n }\n }\n }, []);\n\n return {\n isSupported,\n pipWindow,\n isPiPActive: pipWindow !== null,\n openPiP,\n closePiP,\n resizePiP,\n };\n}\n","import { createContext, useCallback, useContext, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useLocalParticipant } from '@livekit/components-react';\nimport { useDocumentPiP, useCompactNavigation } from '../hooks';\nimport { PiPCompactCall } from '../ui';\nimport { useCallStore } from '@xipkg/calls-store';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { useMedia } from '@xipkg/calls-utils';\nimport {\n getPipHeightForMode,\n PIP_EXTRA_HEIGHT_PX,\n PIP_HEIGHT_BASIC_PX,\n PIP_PANEL_WIDTH_PX,\n} from '../constants';\n\ntype PiPContextValue = {\n openPiP: () => Promise<void>;\n isPiPActive: boolean;\n isSupported: boolean;\n};\n\nconst PiPContext = createContext<PiPContextValue | null>(null);\n\nexport function usePiP() {\n const ctx = useContext(PiPContext);\n return ctx;\n}\n\nfunction getMediaStreamTrack(\n pub: { track?: { mediaStreamTrack?: MediaStreamTrack } } | undefined,\n): MediaStreamTrack | undefined {\n return pub?.track?.mediaStreamTrack;\n}\n\nfunction useMediaCaptureLive() {\n const { microphoneTrack, cameraTrack } = useLocalParticipant();\n const micTrack = getMediaStreamTrack(microphoneTrack);\n const camTrack = getMediaStreamTrack(cameraTrack);\n const micLive = !!micTrack && micTrack.readyState === 'live' && micTrack.enabled;\n const camLive = !!camTrack && camTrack.readyState === 'live' && camTrack.enabled;\n return { micLive, camLive };\n}\n\ntype PiPProviderProps = {\n children: React.ReactNode;\n};\n\n/**\n * Предоставляет API PiP (openPiP, isSupported) дочерним компонентам и управляет\n * Document Picture-in-Picture (логика из PiPManager).\n */\nexport function PiPProvider({ children }: PiPProviderProps) {\n const isMobile = useMedia('(max-width: 720px)');\n const { micLive, camLive } = useMediaCaptureLive();\n const { room } = useRoom();\n const compactViewMode = useCallStore((s) => s.compactViewMode);\n const { totalParticipants } = useCompactNavigation();\n\n const {\n pipWindow,\n closePiP,\n resizePiP,\n openPiP: openPiPRaw,\n isSupported,\n } = useDocumentPiP({\n enabled: !isMobile,\n width: PIP_PANEL_WIDTH_PX,\n height: PIP_HEIGHT_BASIC_PX,\n microphoneActive: micLive,\n cameraActive: camLive,\n });\n\n const openPiP = useCallback(async () => {\n const height = getPipHeightForMode(compactViewMode, totalParticipants);\n await openPiPRaw({ height });\n }, [openPiPRaw, compactViewMode, totalParticipants]);\n\n useEffect(() => {\n if (!room || !pipWindow) return;\n if (room.state !== 'connected') {\n closePiP();\n return;\n }\n const handleState = () => {\n if (room.state !== 'connected') closePiP();\n };\n room.on('connectionStateChanged', handleState);\n return () => {\n room.off('connectionStateChanged', handleState);\n };\n }, [room, pipWindow, closePiP]);\n\n useEffect(() => {\n if (!pipWindow || !resizePiP) return;\n const height =\n compactViewMode === 'basic'\n ? PIP_HEIGHT_BASIC_PX + PIP_EXTRA_HEIGHT_PX\n : getPipHeightForMode(compactViewMode, totalParticipants);\n resizePiP(PIP_PANEL_WIDTH_PX, height);\n }, [pipWindow, resizePiP, compactViewMode, totalParticipants]);\n\n const value: PiPContextValue = {\n openPiP,\n isPiPActive: pipWindow !== null,\n isSupported: isSupported && !isMobile,\n };\n\n return (\n <PiPContext.Provider value={value}>\n {children}\n {pipWindow && createPortal(<PiPCompactCall pipWindow={pipWindow} />, pipWindow.document.body)}\n </PiPContext.Provider>\n );\n}\n","import { useAudioWaveform } from '@livekit/components-react';\nimport type { LocalAudioTrack, RemoteAudioTrack } from 'livekit-client';\nimport { Participant, Track } from 'livekit-client';\nimport { ChevronBottom, MicrophoneOff, RedLine } from '@xipkg/icons';\nimport { Button } from '@xipkg/button';\nimport { ParticipantName, TrackMutedIndicator, RaisedHandIndicator } from '@xipkg/calls-ui';\nimport { cn } from '@xipkg/utils';\n\ntype CompactCallCollapsedBarProps = {\n participant: Participant | null;\n audioTrack?: LocalAudioTrack | RemoteAudioTrack | null;\n onExpand: () => void;\n className?: string;\n};\n\nexport function CompactCallCollapsedBar({\n participant,\n audioTrack,\n onExpand,\n className,\n}: CompactCallCollapsedBarProps) {\n const { bars } = useAudioWaveform(audioTrack ?? undefined, {\n barCount: 24,\n volMultiplier: 4,\n updateInterval: 50,\n });\n return (\n <div\n className={cn(\n 'bg-gray-20 flex items-center gap-2 rounded-2xl px-2 py-2 shadow-lg',\n className,\n )}\n >\n {/* Тот же блок, что и в плитке участника ВКС: микрофон + имя */}\n <div className=\"bg-gray-0/80 flex h-6 max-w-[45%] min-w-0 shrink gap-1.5 rounded-lg px-1.5 py-1 backdrop-blur\">\n {participant ? (\n <>\n <TrackMutedIndicator\n trackRef={{\n participant,\n source: Track.Source.Microphone,\n }}\n show=\"muted\"\n style={{ marginRight: '0.45rem', background: 'transparent' }}\n />\n <span className=\"flex min-w-0 truncate\">\n <ParticipantName participant={participant} />\n </span>\n </>\n ) : (\n <>\n <div className=\"relative w-3 shrink-0\">\n <MicrophoneOff className=\"absolute h-4 w-4 fill-gray-100\" />\n <RedLine className=\"fill-red-80 absolute h-4 w-4\" />\n </div>\n <span className=\"text-xs-base-size leading-[16px] text-gray-100\">Нет участников</span>\n </>\n )}\n </div>\n {participant && <RaisedHandIndicator participant={participant ?? 'unknown'} />}\n <div className=\"flex min-w-0 flex-1 items-center justify-center gap-0.5 py-1\">\n {bars.length > 0 ? (\n <div className=\"flex h-4 items-end justify-center gap-0.5\">\n {bars.map((h, i) => (\n <div\n key={i}\n className=\"bg-brand-80 w-0.5 min-w-[2px] rounded-full transition-all duration-75\"\n style={{ height: `${Math.min(100, Math.max(20, h * 150))}%` }}\n />\n ))}\n </div>\n ) : (\n <div className=\"bg-brand-60 h-2 w-12 rounded-full\" />\n )}\n </div>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={onExpand}\n className=\"bg-brand-100 hover:bg-brand-100/80 h-8 w-8 shrink-0 rounded-xl p-0 text-gray-100\"\n aria-label=\"Развернуть\"\n >\n <ChevronBottom className=\"fill-gray-0 h-4 w-4\" />\n </Button>\n </div>\n );\n}\n","import { ArrowLeft, ArrowRight } from '@xipkg/icons';\n\ninterface CompactNavigationControlsProps {\n canPrev: boolean;\n canNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n currentIndex: number;\n totalParticipants: number;\n}\n\n/**\n * Элементы управления навигацией для компактного вида\n * Показывает кнопки навигации и индикаторы участников только при наведении\n */\nexport function CompactNavigationControls({\n canPrev,\n canNext,\n onPrev,\n onNext,\n currentIndex,\n totalParticipants,\n}: CompactNavigationControlsProps) {\n if (totalParticipants <= 1) {\n return null;\n }\n\n return (\n <div className=\"pointer-events-none absolute inset-0\">\n {/* Индикатор участников вверху */}\n <div className=\"pointer-events-auto absolute top-2 left-1/2 -translate-x-1/2\">\n <div className=\"bg-gray-10/80 flex gap-1 rounded-full px-2 py-1 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n {Array.from({ length: totalParticipants }, (_, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => {\n // Здесь можно добавить логику для прямого перехода к участнику\n // Пока оставляем только навигацию через кнопки\n }}\n className={`h-1.5 w-1.5 rounded-full transition-colors ${\n index === currentIndex ? 'bg-gray-100' : 'bg-gray-100/50 hover:bg-gray-100/75'\n }`}\n aria-label={`Участник ${index + 1}`}\n />\n ))}\n </div>\n </div>\n\n {/* Кнопка \"Предыдущий участник\" */}\n <div className=\"pointer-events-auto absolute top-1/2 left-2 -translate-y-1/2 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n <button\n type=\"button\"\n disabled={!canPrev}\n onClick={onPrev}\n className=\"bg-gray-10/80 hover:bg-gray-10 z-10 flex items-center justify-center rounded-full fill-gray-100 p-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n <span className=\"sr-only\">Предыдущий участник</span>\n </button>\n </div>\n\n {/* Кнопка \"Следующий участник\" */}\n <div className=\"pointer-events-auto absolute top-1/2 right-2 -translate-y-1/2 transition-opacity duration-200 sm:opacity-0 sm:group-hover:opacity-100\">\n <button\n type=\"button\"\n disabled={!canNext}\n onClick={onNext}\n className=\"bg-gray-10/80 hover:bg-gray-10 z-10 flex items-center justify-center rounded-full fill-gray-100 p-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ArrowRight className=\"h-4 w-4\" />\n <span className=\"sr-only\">Следующий участник</span>\n </button>\n </div>\n </div>\n );\n}\n","import { ArrowUp } from '@xipkg/icons';\n\ninterface CompactMultiViewControlsProps {\n canPrev: boolean;\n canNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n}\n\n/**\n * Стрелки листания для развёрнутого мульти-вида ВКС:\n * сверху на первой плитке — стрелка вверх, снизу на последней — стрелка вниз\n */\nexport function CompactMultiViewControls({\n canPrev,\n canNext,\n onPrev,\n onNext,\n}: CompactMultiViewControlsProps) {\n return (\n <div className=\"pointer-events-none absolute inset-0\">\n {/* Стрелка вверх — по центру сверху (на первой плитке), если есть куда листать */}\n {canPrev && (\n <div className=\"pointer-events-auto absolute top-2 left-1/2 z-10 -translate-x-1/2\">\n <button\n type=\"button\"\n onClick={onPrev}\n className=\"bg-gray-10/80 hover:bg-gray-10 flex items-center justify-center rounded-full fill-gray-100 p-2\"\n aria-label=\"Листать вверх\"\n >\n <ArrowUp className=\"h-4 w-4 fill-inherit\" />\n </button>\n </div>\n )}\n {/* Стрелка вниз — по центру снизу (на последней плитке) */}\n {canNext && (\n <div className=\"pointer-events-auto absolute bottom-2 left-1/2 z-10 -translate-x-1/2\">\n <button\n type=\"button\"\n onClick={onNext}\n className=\"bg-gray-10/80 hover:bg-gray-10 flex items-center justify-center rounded-full fill-gray-100 p-2\"\n aria-label=\"Листать вниз\"\n >\n <ArrowUp className=\"h-4 w-4 rotate-180 fill-inherit\" />\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';\nimport type { CompactViewModeT } from '@xipkg/calls-store';\nimport { Button } from '@xipkg/button';\nimport { ChevronUp, External } from '@xipkg/icons';\nimport { cn } from '@xipkg/utils';\nimport { usePiP } from '../providers';\nimport { CompactCallCollapsedBar } from './CompactCallCollapsedBar';\nimport { CompactNavigationControls } from './CompactNavigationControls';\nimport { CompactMultiViewControls } from './CompactMultiViewControls';\nimport { ParticipantTile } from '@xipkg/calls-ui';\nimport { TILE_GAP_PX, TILE_HEIGHT_16_9_PX } from '../constants';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\n\ntype CompactCallVideoAreaProps = {\n isMobile: boolean;\n isCollapsed: boolean;\n onCollapsedChange: (collapsed: boolean) => void;\n withOutShadows: boolean;\n dragAttributes?: object;\n dragListeners?: object;\n /** Режим вида на десктопе */\n compactViewMode: CompactViewModeT;\n currentParticipant: TrackReferenceOrPlaceholder | null;\n currentAudioTrack:\n | import('livekit-client').RemoteAudioTrack\n | import('livekit-client').LocalAudioTrack\n | null;\n totalParticipants: number;\n canGoPrev: boolean;\n canGoNext: boolean;\n onPrev: () => void;\n onNext: () => void;\n currentIndex: number;\n multiVisibleParticipants: TrackReferenceOrPlaceholder[];\n multiTileHeightPx: number;\n multiCanPrev: boolean;\n multiCanNext: boolean;\n onMultiPrev: () => void;\n onMultiNext: () => void;\n onAudioExpand: () => void;\n};\n\nexport function CompactCallVideoArea({\n isMobile,\n isCollapsed,\n onCollapsedChange,\n withOutShadows,\n dragAttributes = {},\n dragListeners = {},\n compactViewMode,\n currentParticipant,\n currentAudioTrack,\n totalParticipants,\n canGoPrev,\n canGoNext,\n onPrev,\n onNext,\n currentIndex,\n multiVisibleParticipants,\n multiTileHeightPx,\n multiCanPrev,\n multiCanNext,\n onMultiPrev,\n onMultiNext,\n onAudioExpand,\n}: CompactCallVideoAreaProps) {\n const pip = usePiP();\n const showPiPButton = pip?.isSupported && currentParticipant;\n\n const emptyState = (\n <div className=\"bg-gray-40 flex h-full w-full items-center justify-center text-gray-100\">\n <span className=\"text-sm\">Нет участников</span>\n </div>\n );\n\n if (isMobile && isCollapsed) {\n return (\n <CompactCallCollapsedBar\n participant={currentParticipant?.participant ?? null}\n audioTrack={currentAudioTrack ?? null}\n onExpand={() => onCollapsedChange(false)}\n className={cn('mb-2', withOutShadows ? '' : 'shadow-lg')}\n />\n );\n }\n\n if (!isMobile && compactViewMode === 'audio') {\n return (\n <CompactCallCollapsedBar\n participant={currentParticipant?.participant ?? null}\n audioTrack={currentAudioTrack ?? null}\n onExpand={onAudioExpand}\n className={cn('mb-2 w-[360px]', withOutShadows ? '' : 'shadow-lg')}\n />\n );\n }\n\n return (\n <div\n {...(isMobile ? {} : { ...dragAttributes, ...dragListeners })}\n className={cn(\n 'group relative mb-2 flex overflow-hidden rounded-2xl',\n withOutShadows ? '' : 'shadow-lg',\n isMobile ? 'h-auto w-full items-center justify-center' : 'w-[360px] cursor-move flex-col',\n !isMobile && compactViewMode === 'basic' && 'shrink-0',\n !isMobile && compactViewMode === 'expanded' && 'h-auto',\n )}\n style={!isMobile && compactViewMode === 'basic' ? { height: TILE_HEIGHT_16_9_PX } : undefined}\n >\n {isMobile ? (\n currentParticipant ? (\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n ) : (\n emptyState\n )\n ) : compactViewMode === 'expanded' ? (\n <div\n className=\"relative flex flex-col gap-2 overflow-hidden rounded-2xl p-1\"\n style={{ gap: TILE_GAP_PX }}\n >\n {multiVisibleParticipants.length === 0\n ? emptyState\n : multiVisibleParticipants.map((trackRef) => (\n <div\n key={`${trackRef.participant.identity}-${trackRef.source}`}\n className=\"aspect-video w-full shrink-0 overflow-hidden rounded-xl\"\n style={{ minHeight: multiTileHeightPx }}\n >\n <ParticipantTile\n trackRef={trackRef}\n participant={trackRef.participant}\n className=\"h-full w-full [&_video]:object-cover\"\n isFocusToggleDisable\n />\n </div>\n ))}\n <CompactMultiViewControls\n canPrev={multiCanPrev}\n canNext={multiCanNext}\n onPrev={onMultiPrev}\n onNext={onMultiNext}\n />\n </div>\n ) : currentParticipant ? (\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n ) : (\n emptyState\n )}\n\n {showPiPButton && compactViewMode !== 'audio' && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => void pip!.openPiP()}\n className=\"bg-gray-10/80 hover:bg-gray-10 text-gray-0 absolute top-2 right-2 z-10 h-8 w-8 rounded-xl p-0\"\n aria-label=\"Открыть в отдельном окне\"\n >\n <External className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Открыть в отдельном окне</TooltipContent>\n </Tooltip>\n )}\n\n {isMobile && (\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => onCollapsedChange(true)}\n className=\"bg-brand-100 hover:bg-brand-100/80 absolute top-2 right-2 z-10 h-8 w-8 rounded-xl p-0 text-gray-100\"\n aria-label=\"Свернуть\"\n >\n <ChevronUp className=\"fill-gray-0 h-4 w-4\" />\n </Button>\n )}\n\n {totalParticipants > 0 && (isMobile || compactViewMode === 'basic') && (\n <CompactNavigationControls\n canPrev={canGoPrev}\n canNext={canGoNext}\n onPrev={onPrev}\n onNext={onNext}\n currentIndex={currentIndex}\n totalParticipants={totalParticipants}\n />\n )}\n </div>\n );\n}\n","import type { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';\nimport { Button } from '@xipkg/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from '@xipkg/dropdown';\nimport { Account, Maximize, SoundTwo, Users, WhiteBoard } from '@xipkg/icons';\nimport { cn } from '@xipkg/utils';\nimport type { CompactViewModeT } from '@xipkg/calls-store';\nimport { getNextCompactViewMode } from '../constants';\nimport { DevicesBar, DisconnectButton, ScreenShareButton } from '@xipkg/calls-ui';\nimport { ChatButton } from '@xipkg/calls-chat';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\n\ntype CompactCallDevicesPropsT = {\n microTrack: LocalAudioTrack | undefined;\n microEnabled: boolean;\n microTrackToggle: {\n showIcon: boolean;\n source: import('livekit-client').Track.Source;\n onChange: () => void;\n };\n videoTrack: LocalVideoTrack | undefined;\n videoEnabled: boolean;\n videoTrackToggle: {\n showIcon: boolean;\n source: import('livekit-client').Track.Source;\n onChange: () => void;\n };\n};\n\ntype CompactCallBottomBarPropsT = {\n withOutShadows: boolean;\n devices: CompactCallDevicesPropsT;\n isMobile: boolean;\n compactViewMode: CompactViewModeT;\n onViewModeToggle: () => void;\n showBackToBoardButton: boolean;\n onBackToBoard: () => void;\n onMaximize: (syncToAll?: boolean) => void;\n isTutor: boolean;\n};\n\nexport function CompactCallBottomBar({\n withOutShadows,\n devices,\n isMobile,\n compactViewMode,\n onViewModeToggle,\n showBackToBoardButton,\n onBackToBoard,\n onMaximize,\n isTutor,\n}: CompactCallBottomBarPropsT) {\n const nextViewMode = getNextCompactViewMode(compactViewMode);\n const viewModeToggleMeta = {\n expanded: { Icon: Users, label: 'Развёрнутый вид (несколько участников)' },\n audio: { Icon: SoundTwo, label: 'Только аудио' },\n basic: { Icon: Account, label: 'Один участник' },\n }[nextViewMode];\n const ViewModeIcon = viewModeToggleMeta.Icon;\n\n const barCn = cn(\n 'bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-1',\n withOutShadows ? '' : 'shadow-lg',\n );\n\n return (\n <div className=\"flex h-[40px] flex-row\">\n <div className={barCn}>\n <DevicesBar\n className=\"h-[32px] w-[32px]\"\n microTrack={devices.microTrack}\n microEnabled={devices.microEnabled}\n microTrackToggle={devices.microTrackToggle}\n videoTrack={devices.videoTrack}\n videoEnabled={devices.videoEnabled}\n videoTrackToggle={devices.videoTrackToggle}\n />\n </div>\n\n {!isMobile && (\n <div className={cn(barCn, 'ml-1')}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={onViewModeToggle}\n className=\"hover:bg-gray-5 h-8 w-8 rounded-xl p-0 text-gray-100\"\n aria-label={viewModeToggleMeta.label}\n >\n <ViewModeIcon className=\"h-5 w-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{viewModeToggleMeta.label}</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {showBackToBoardButton && (\n <div className={cn(barCn, 'ml-1')}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"primary\"\n className=\"h-8 w-8 rounded-xl p-0\"\n onClick={onBackToBoard}\n aria-label=\"На доску\"\n >\n <WhiteBoard className=\"fill-gray-0 h-5 w-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Обратно на доску</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n <div className={cn(barCn, 'ml-auto')}>\n <ScreenShareButton className=\"h-[32px] w-[32px]\" />\n <ChatButton className=\"h-8 w-8 min-w-8 rounded-xl\" />\n <RaiseHandButton className=\"h-[32px] w-[32px]\" />\n </div>\n\n <div className={cn(barCn, 'ml-1')}>\n {isTutor ? (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n className=\"hover:bg-gray-5 relative m-0 h-8 w-8 rounded-xl p-0 text-gray-100\"\n >\n <Maximize className=\"fill-gray-100\" />\n </Button>\n </DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent>Вернуться в конференцию</TooltipContent>\n </Tooltip>\n <DropdownMenuContent side=\"top\" align=\"end\" className=\"z-1000 min-w-[200px]\">\n <DropdownMenuLabel className=\"text-gray-60 text-sm\">\n Вернуть в конференцию\n </DropdownMenuLabel>\n <DropdownMenuItem\n onClick={() => onMaximize(false)}\n className=\"text-gray-80 cursor-pointer text-sm\"\n >\n Только меня\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => onMaximize(true)}\n className=\"text-gray-80 cursor-pointer text-sm\"\n >\n Всех участников\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => onMaximize(false)}\n className=\"hover:bg-gray-5 relative m-0 h-8 w-8 rounded-xl p-0 text-gray-100\"\n >\n <Maximize className=\"fill-gray-100\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Вернуться в конференцию</TooltipContent>\n </Tooltip>\n )}\n <DisconnectButton className=\"h-[32px] w-[32px] rounded-xl\" />\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDraggable } from '@dnd-kit/core';\nimport { CSS } from '@dnd-kit/utilities';\nimport {\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { LocalAudioTrack, LocalVideoTrack, Track } from 'livekit-client';\nimport { useCallStore, type CompactViewModeT } from '@xipkg/calls-store';\nimport { useCompactAvailableHeight, useCompactNavigation } from '../hooks';\nimport { useVideoBlur, useModeSync } from '@xipkg/calls-hooks';\nimport { useRoom, useCalls, useCallsNavigation } from '@xipkg/calls-providers';\nimport { useMedia } from '@xipkg/calls-utils';\nimport { CompactCallVideoArea } from './CompactCallVideoArea';\nimport { CompactCallBottomBar } from './CompactCallBottomBar';\nimport {\n COMPACT_BOTTOM_BAR_PX,\n COMPACT_VIDEO_AREA_MARGIN_PX,\n EXPANDED_VIDEO_PADDING_VERTICAL_PX,\n TILE_GAP_PX,\n TILE_HEIGHT_16_9_PX,\n getNextCompactViewMode,\n} from '../constants';\n\nexport const CompactCall = ({ saveUserChoices = true, withOutShadows = false }) => {\n const isMobile = useMedia('(max-width: 720px)');\n const { attributes, listeners, setNodeRef, transform } = useDraggable({\n id: 'draggable-call',\n disabled: isMobile,\n });\n const style = isMobile ? undefined : { transform: CSS.Translate.toString(transform) };\n\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices({\n preventSave: !saveUserChoices,\n });\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n const videoTrack = cameraTrack?.track as LocalVideoTrack | undefined;\n\n const mode = useCallStore((state) => state.mode);\n useVideoBlur(mode === 'compact' ? videoTrack : null);\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveAudioInputEnabled(enabled);\n },\n });\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveVideoInputEnabled(enabled);\n },\n });\n\n const handleMicrophoneToggle = useCallback(() => microphoneToggle.toggle(), [microphoneToggle]);\n const handleCameraToggle = useCallback(() => cameraToggle.toggle(), [cameraToggle]);\n\n const compactNavigation = useCompactNavigation();\n const {\n currentParticipant,\n participants,\n currentIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n } = compactNavigation;\n const callsNavigation = useCallsNavigation();\n\n const [isCollapsed, setIsCollapsed] = useState(false);\n const compactViewMode = useCallStore((state) => state.compactViewMode);\n const updateStore = useCallStore((state) => state.updateStore);\n const setCompactViewMode = useCallback(\n (mode: CompactViewModeT) => updateStore('compactViewMode', mode),\n [updateStore],\n );\n const [multiScrollIndex, setMultiScrollIndex] = useState(0);\n\n const currentAudioTrack = currentParticipant?.participant?.getTrackPublication(\n Track.Source.Microphone,\n )?.track as\n | import('livekit-client').RemoteAudioTrack\n | import('livekit-client').LocalAudioTrack\n | undefined;\n\n const { syncModeToOthers } = useModeSync();\n const activeBoardId = useCallStore((state) => state.activeBoardId);\n const activeClassroom = useCallStore((state) => state.activeClassroom);\n const { room } = useRoom();\n const token = useCallStore((state) => state.token);\n\n const { data: user } = useCalls().auth.useCurrentUser();\n\n const isTutor = user?.default_layout === 'tutor';\n const isBoardPage = callsNavigation.pathnameIncludes('/board');\n const isOnBoardPage =\n callsNavigation.params.classroomId === activeClassroom &&\n callsNavigation.params.boardId === activeBoardId;\n const showBackToBoardButton =\n mode === 'compact' && !!activeBoardId && !!activeClassroom && !isOnBoardPage;\n\n const availableHeight = useCompactAvailableHeight(isBoardPage);\n\n const multiViewLayout = useMemo(() => {\n const heightForTiles = Math.max(\n 0,\n availableHeight -\n COMPACT_BOTTOM_BAR_PX -\n EXPANDED_VIDEO_PADDING_VERTICAL_PX -\n COMPACT_VIDEO_AREA_MARGIN_PX,\n );\n // Плитки имеют aspect-video (16:9), их высота фиксирована шириной контейнера\n const visibleCount = Math.min(\n totalParticipants,\n Math.max(1, Math.floor((heightForTiles + TILE_GAP_PX) / (TILE_HEIGHT_16_9_PX + TILE_GAP_PX))),\n );\n return { visibleCount, tileHeightPx: TILE_HEIGHT_16_9_PX };\n }, [availableHeight, totalParticipants]);\n\n const { visibleCount: multiVisibleCount, tileHeightPx: multiTileHeightPx } = multiViewLayout;\n const multiCanPrev = multiScrollIndex > 0;\n const multiCanNext = multiScrollIndex + multiVisibleCount < totalParticipants;\n const multiVisibleParticipants = participants.slice(\n multiScrollIndex,\n multiScrollIndex + multiVisibleCount,\n );\n\n useEffect(() => {\n if (multiScrollIndex + multiVisibleCount > totalParticipants && totalParticipants > 0) {\n setMultiScrollIndex(Math.max(0, totalParticipants - multiVisibleCount));\n }\n }, [totalParticipants, multiVisibleCount, multiScrollIndex]);\n\n const handleBackToBoard = useCallback(() => {\n if (!activeBoardId || !activeClassroom) return;\n callsNavigation.navigateToClassroomBoard(activeClassroom, activeBoardId);\n }, [activeBoardId, activeClassroom, callsNavigation]);\n\n const handleMaximize = useCallback(\n (syncToAll: boolean = false) => {\n if (!room || !token || room.state !== 'connected') return;\n const callParam = callsNavigation.search.call;\n const targetCallId =\n (typeof callParam === 'string' ? callParam.replace(/^\"|\"$/g, '').trim() : '') ||\n activeClassroom ||\n callsNavigation.params.classroomId ||\n callsNavigation.getCallId() ||\n '';\n if (syncToAll && isTutor && activeBoardId && targetCallId) {\n updateStore('localFullView', false);\n updateStore('mode', 'full');\n updateStore('activeBoardId', undefined);\n updateStore('activeClassroom', undefined);\n syncModeToOthers('full', undefined, targetCallId);\n } else {\n updateStore('localFullView', true);\n updateStore('mode', 'full');\n }\n if (targetCallId) {\n callsNavigation.navigateToCall(targetCallId, { replace: true });\n }\n },\n [\n room,\n token,\n callsNavigation,\n activeClassroom,\n isTutor,\n activeBoardId,\n updateStore,\n syncModeToOthers,\n ],\n );\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={`compact-call-container flex flex-col ${isMobile ? 'w-full' : 'w-[360px]'}`}\n >\n <CompactCallVideoArea\n isMobile={isMobile}\n isCollapsed={isCollapsed}\n onCollapsedChange={setIsCollapsed}\n withOutShadows={withOutShadows}\n dragAttributes={attributes as object}\n dragListeners={listeners as object}\n compactViewMode={compactViewMode}\n currentParticipant={currentParticipant}\n currentAudioTrack={currentAudioTrack ?? null}\n totalParticipants={totalParticipants}\n canGoPrev={canGoPrev}\n canGoNext={canGoNext}\n onPrev={goToPrev}\n onNext={goToNext}\n currentIndex={currentIndex}\n multiVisibleParticipants={multiVisibleParticipants}\n multiTileHeightPx={multiTileHeightPx}\n multiCanPrev={multiCanPrev}\n multiCanNext={multiCanNext}\n onMultiPrev={() => setMultiScrollIndex((i) => Math.max(0, i - 1))}\n onMultiNext={() =>\n setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1))\n }\n onAudioExpand={() => setCompactViewMode('basic')}\n />\n <CompactCallBottomBar\n withOutShadows={withOutShadows}\n devices={{\n microTrack: microphoneTrack?.track as LocalAudioTrack,\n microEnabled: isMicrophoneEnabled,\n microTrackToggle: {\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n },\n videoTrack: cameraTrack?.track as unknown as LocalVideoTrack,\n videoEnabled: isCameraEnabled,\n videoTrackToggle: {\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n },\n }}\n isMobile={isMobile}\n compactViewMode={compactViewMode}\n onViewModeToggle={() => setCompactViewMode(getNextCompactViewMode(compactViewMode))}\n showBackToBoardButton={!!showBackToBoardButton}\n onBackToBoard={handleBackToBoard}\n onMaximize={handleMaximize}\n isTutor={!!isTutor}\n />\n </div>\n );\n};\n","import { FC, useEffect, useRef, useState } from 'react';\nimport {\n DndContext,\n DragEndEvent,\n useSensor,\n useSensors,\n PointerSensor,\n useDroppable,\n DragOverlay,\n useDndMonitor,\n} from '@dnd-kit/core';\nimport { useCallsNavigation } from '@xipkg/calls-providers';\nimport { restrictToWindowEdges } from '@dnd-kit/modifiers';\nimport { RoomAudioRenderer } from '@livekit/components-react';\nimport { CompactCall } from './CompactCall';\nimport { Chat, useChatStore } from '@xipkg/calls-chat';\nimport { PermissionsDialog } from '@xipkg/calls-ui';\nimport { useCallStore } from '@xipkg/calls-store';\nimport type { CornerT } from '@xipkg/calls-store';\nimport { useMedia } from '@xipkg/calls-utils';\nimport { useRoom } from '@xipkg/calls-providers';\nimport { PiPProvider, usePiP } from '../providers';\nimport { useParticipantSounds, useParticipantJoinSync } from '@xipkg/calls-hooks';\nimport { COMPACT_MOBILE_CONTENT_GAP_PX, COMPACT_MOBILE_OVERLAY_FALLBACK_PX } from '../constants';\n\ntype CompactViewPropsT = {\n children: React.ReactNode;\n};\n\nconst OPPOSITE_CORNER: Record<CornerT, CornerT> = {\n 'top-left': 'top-right',\n 'top-right': 'top-left',\n 'bottom-left': 'bottom-right',\n 'bottom-right': 'bottom-left',\n};\n\nconst DroppableCorner = ({ id, className }: { id: string; className: string }) => {\n const { setNodeRef } = useDroppable({\n id,\n });\n const [isDragging, setIsDragging] = useState(false);\n\n useDndMonitor({\n onDragStart: () => {\n setIsDragging(true);\n },\n onDragEnd: () => {\n setIsDragging(false);\n },\n });\n\n return (\n <div\n ref={setNodeRef}\n className={`absolute z-100 size-1/3 ${className} pointer-events-none transition-all duration-200 ${\n isDragging ? 'bg-brand-0/20 ring-brand-20 pointer-events-auto rounded-lg ring-2' : ''\n }`}\n />\n );\n};\n\nconst DroppableAreas: FC = () => {\n const [isDragging, setIsDragging] = useState(false);\n\n useDndMonitor({\n onDragStart: () => {\n setIsDragging(true);\n },\n onDragEnd: () => {\n setIsDragging(false);\n },\n });\n\n return (\n <>\n <DroppableCorner id=\"top-left\" className=\"top-16 left-4\" />\n <DroppableCorner id=\"top-right\" className=\"top-16 right-4\" />\n <DroppableCorner id=\"bottom-left\" className=\"bottom-18 left-4\" />\n <DroppableCorner id=\"bottom-right\" className=\"right-4 bottom-18\" />\n <DragOverlay>{isDragging ? <CompactCall /> : null}</DragOverlay>\n </>\n );\n};\n\ntype CompactPropsT = CompactViewPropsT & {\n /** При true не рендерить оверлей (звонок, чат, углы). Используется при PiP, чтобы children не размонтировались. */\n hideOverlay?: boolean;\n};\n\nexport const Compact: FC<CompactPropsT> = ({ children, hideOverlay = false }) => {\n const navigation = useCallsNavigation();\n const { activeCorner, updateStore } = useCallStore();\n const isMobile = useMedia('(max-width: 720px)');\n const headerRef = useRef<HTMLDivElement>(null);\n const [headerHeight, setHeaderHeight] = useState(0);\n\n useEffect(() => {\n if (!isMobile || hideOverlay || !headerRef.current) return;\n const el = headerRef.current;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) setHeaderHeight(entry.contentRect.height);\n });\n observer.observe(el);\n setHeaderHeight(el.getBoundingClientRect().height);\n return () => observer.disconnect();\n }, [isMobile, hideOverlay]);\n\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 8,\n },\n }),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { over } = event;\n if (over) {\n updateStore('activeCorner', over.id as CornerT);\n }\n };\n\n const isBoardPage = navigation.pathnameIncludes('/board');\n const bottomOffset = isBoardPage ? 'bottom-[72px]' : 'bottom-4';\n\n const mobileContentMarginTop =\n hideOverlay || !isMobile\n ? 0\n : (headerHeight > 0 ? headerHeight : COMPACT_MOBILE_OVERLAY_FALLBACK_PX) +\n COMPACT_MOBILE_CONTENT_GAP_PX;\n\n const getCornerPosition = (corner: CornerT) => {\n switch (corner) {\n case 'top-left':\n return 'top-16 left-4';\n case 'top-right':\n return 'top-16 right-4';\n case 'bottom-left':\n return `${bottomOffset} left-4`;\n case 'bottom-right':\n return `${bottomOffset} right-4`;\n }\n };\n\n /** Противоположный угол для чата (та же логика позиционирования, другой угол) */\n const getChatPositionClasses = (corner: CornerT) => {\n const opposite = OPPOSITE_CORNER[corner];\n const horizontal = opposite.includes('left') ? 'left-22' : 'right-4';\n return `top-32 ${bottomOffset} ${horizontal}`;\n };\n\n const container = (\n <div className={`relative flex h-dvh flex-col bg-transparent`}>\n {isMobile ? (\n <>\n {!hideOverlay && (\n <div ref={headerRef} className=\"fixed top-2 right-0 left-0 z-10 w-full px-2\">\n <CompactCall withOutShadows />\n </div>\n )}\n <div\n className=\"mb-16 flex min-h-0 flex-1 flex-col\"\n style={{ marginTop: mobileContentMarginTop }}\n >\n {children}\n </div>\n </>\n ) : (\n <>\n {!hideOverlay && (\n <>\n <DroppableAreas />\n <Chat compactPositionClassName={getChatPositionClasses(activeCorner)} />\n <div\n className={`absolute z-100 ${getCornerPosition(activeCorner)} transition-all duration-500 ease-out`}\n >\n <CompactCall />\n </div>\n </>\n )}\n {children}\n </>\n )}\n\n <RoomAudioRenderer />\n </div>\n );\n\n // Всегда один и тот же корень (DndContext), иначе при hideOverlay React размонтирует\n // container и всё дерево доски (YjsProvider пересоздаётся → белый экран).\n return (\n <DndContext sensors={sensors} onDragEnd={handleDragEnd} modifiers={[restrictToWindowEdges]}>\n {container}\n </DndContext>\n );\n};\n\nconst CompactViewInner = ({ children }: CompactViewPropsT) => {\n const { mode, token } = useCallStore();\n const { room } = useRoom();\n const pip = usePiP();\n const isPiPActive = !!pip?.isPiPActive;\n\n // Синхронизация состояния при подключении новых участников (работает и в compact mode)\n useParticipantJoinSync();\n useParticipantSounds();\n\n const navigation = useCallsNavigation();\n const { updateStore: updateChatStore } = useChatStore();\n\n useEffect(() => {\n const { activeClassroom } = useCallStore.getState();\n const isOnBoardPage = navigation.pathnameIncludes('/board');\n\n if ((!room || !token) && navigation.search.call && !isOnBoardPage && !activeClassroom) {\n navigation.clearCallSearchParam();\n\n // Очищаем все состояния интерфейса при отключении\n const { clearAllRaisedHands, updateStore: updateCallStore } = useCallStore.getState();\n // Очищаем поднятые руки\n clearAllRaisedHands();\n\n // Очищаем чат\n updateChatStore('isChatOpen', false);\n updateChatStore('chatMessages', []);\n updateChatStore('unreadMessagesCount', 0);\n\n // Очищаем информацию о доске при отключении\n updateCallStore('activeBoardId', undefined);\n updateCallStore('activeClassroom', undefined);\n\n updateCallStore('mode', 'full');\n }\n }, [room, token, navigation, updateChatStore]);\n\n const contentWrapper = (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"min-h-0 flex-1\">{children}</div>\n </div>\n );\n\n if (!room || !token) {\n return (\n <>\n {contentWrapper}\n <PermissionsDialog />\n </>\n );\n }\n\n if (mode === 'full') {\n return (\n <>\n {contentWrapper}\n <PermissionsDialog />\n </>\n );\n }\n\n // Всегда один и тот же Compact — при PiP только скрываем оверлей (hideOverlay).\n return (\n <>\n <Compact hideOverlay={isPiPActive}>{children}</Compact>\n <PermissionsDialog />\n </>\n );\n};\n\nexport const CompactView = ({ children }: CompactViewPropsT) => (\n <PiPProvider>\n <CompactViewInner>{children}</CompactViewInner>\n </PiPProvider>\n);\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n useLocalParticipant,\n usePersistentUserChoices,\n useTrackToggle,\n} from '@livekit/components-react';\nimport { Track, LocalAudioTrack, LocalVideoTrack, RemoteAudioTrack } from 'livekit-client';\nimport { Account, SoundTwo, Users } from '@xipkg/icons';\nimport { Button } from '@xipkg/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@xipkg/tooltip';\nimport { cn } from '@xipkg/utils';\nimport { useCallStore, type CompactViewModeT } from '@xipkg/calls-store';\nimport { useCompactNavigation } from '../hooks/useCompactNavigation';\nimport { ParticipantTile, DevicesBar, DisconnectButton, ScreenShareButton } from '@xipkg/calls-ui';\nimport { RaiseHandButton } from '@xipkg/calls-risehand';\nimport { CompactNavigationControls } from './CompactNavigationControls';\nimport { CompactMultiViewControls } from './CompactMultiViewControls';\nimport { CompactCallCollapsedBar } from './CompactCallCollapsedBar';\nimport {\n PIP_RESERVED_HEIGHT_PX,\n PIP_TILE_HEIGHT_16_9_PX,\n TILE_GAP_PX,\n getNextCompactViewMode,\n} from '../constants';\n\n/**\n * Минимальная высота окна PiP, необходимая для отображения n полных плиток\n * вместе с панелью управления и всеми отступами.\n */\nfunction requiredPipHeight(n: number): number {\n return PIP_RESERVED_HEIGHT_PX + n * PIP_TILE_HEIGHT_16_9_PX + Math.max(0, n - 1) * TILE_GAP_PX;\n}\n\ntype PiPCompactCallPropsT = {\n pipWindow: Window;\n};\n\nexport function PiPCompactCall({ pipWindow }: PiPCompactCallPropsT) {\n const compactViewMode = useCallStore((s) => s.compactViewMode);\n const updateStore = useCallStore((s) => s.updateStore);\n const setViewMode = useCallback(\n (mode: CompactViewModeT) => updateStore('compactViewMode', mode),\n [updateStore],\n );\n const nextViewMode = getNextCompactViewMode(compactViewMode);\n const viewModeToggleMeta = {\n expanded: { Icon: Users, label: 'Развёрнутый вид (несколько участников)' },\n audio: { Icon: SoundTwo, label: 'Только аудио' },\n basic: { Icon: Account, label: 'Один участник' },\n }[nextViewMode];\n const ViewModeIcon = viewModeToggleMeta.Icon;\n const [multiScrollIndex, setMultiScrollIndex] = useState(0);\n const [pipSize, setPipSize] = useState({\n width: pipWindow.innerWidth,\n height: pipWindow.innerHeight,\n });\n\n const { saveAudioInputEnabled, saveVideoInputEnabled } = usePersistentUserChoices();\n const { isMicrophoneEnabled, isCameraEnabled, microphoneTrack, cameraTrack } =\n useLocalParticipant();\n\n const microphoneToggle = useTrackToggle({\n source: Track.Source.Microphone,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveAudioInputEnabled(enabled);\n },\n });\n const cameraToggle = useTrackToggle({\n source: Track.Source.Camera,\n onChange: (enabled: boolean, isUserInitiated: boolean) => {\n if (isUserInitiated) saveVideoInputEnabled(enabled);\n },\n });\n\n const handleMicrophoneToggle = useCallback(() => microphoneToggle.toggle(), [microphoneToggle]);\n const handleCameraToggle = useCallback(() => cameraToggle.toggle(), [cameraToggle]);\n\n const {\n currentParticipant,\n participants,\n currentIndex,\n totalParticipants,\n canGoNext,\n canGoPrev,\n goToNext,\n goToPrev,\n } = useCompactNavigation();\n\n // Размер окна PiP:\n useEffect(() => {\n const updateSize = () =>\n setPipSize({ width: pipWindow.innerWidth, height: pipWindow.innerHeight });\n updateSize();\n pipWindow.addEventListener('resize', updateSize);\n return () => pipWindow.removeEventListener('resize', updateSize);\n }, [pipWindow]);\n\n // Сколько полных плиток (16:9) помещается при текущей высоте окна.\n // Плитка добавляется, только когда есть полное место; убирается сразу, как перестаёт влезать.\n const multiVisibleCount = useMemo(() => {\n let n = 1;\n while (n < totalParticipants && requiredPipHeight(n + 1) <= pipSize.height) {\n n++;\n }\n return n;\n }, [pipSize.height, totalParticipants]);\n\n const multiVisibleParticipants = useMemo(\n () => participants.slice(multiScrollIndex, multiScrollIndex + multiVisibleCount),\n [participants, multiScrollIndex, multiVisibleCount],\n );\n const multiCanPrev = multiScrollIndex > 0;\n const multiCanNext = multiScrollIndex + multiVisibleCount < totalParticipants;\n\n const currentAudioTrack = currentParticipant?.participant?.getTrackPublication(\n Track.Source.Microphone,\n )?.track as LocalAudioTrack | RemoteAudioTrack | undefined;\n\n useEffect(() => {\n if (multiScrollIndex + multiVisibleCount > totalParticipants && totalParticipants > 0) {\n setMultiScrollIndex(Math.max(0, totalParticipants - multiVisibleCount));\n }\n }, [totalParticipants, multiVisibleCount, multiScrollIndex]);\n\n const emptyState = (\n <div className=\"bg-gray-40 flex h-full w-full items-center justify-center rounded-2xl text-gray-100\">\n <span className=\"text-sm\">Нет участников</span>\n </div>\n );\n\n const barCn = cn(\n 'bg-gray-0 border-gray-20 flex items-center justify-center rounded-2xl border p-0.5',\n );\n\n return (\n <div className=\"flex h-full flex-col gap-1 p-1\">\n <div className=\"group relative min-h-0 flex-1 overflow-hidden rounded-2xl\">\n {compactViewMode === 'audio' ? (\n <CompactCallCollapsedBar\n participant={currentParticipant?.participant ?? null}\n audioTrack={currentAudioTrack ?? null}\n onExpand={() => setViewMode('basic')}\n className=\"h-full w-full\"\n />\n ) : compactViewMode === 'expanded' ? (\n <div\n className=\"relative flex h-full flex-col overflow-hidden rounded-2xl p-0.5\"\n style={{ gap: TILE_GAP_PX }}\n >\n {multiVisibleParticipants.length === 0\n ? emptyState\n : multiVisibleParticipants.map((trackRef) => (\n <div\n key={`${trackRef.participant.identity}-${trackRef.source}`}\n className=\"aspect-video w-full shrink-0 overflow-hidden rounded-xl\"\n style={{ minHeight: PIP_TILE_HEIGHT_16_9_PX }}\n >\n <ParticipantTile\n trackRef={trackRef}\n participant={trackRef.participant}\n className=\"h-full w-full [&_video]:object-cover\"\n isFocusToggleDisable\n />\n </div>\n ))}\n <CompactMultiViewControls\n canPrev={multiCanPrev}\n canNext={multiCanNext}\n onPrev={() => setMultiScrollIndex((i) => Math.max(0, i - 1))}\n onNext={() =>\n setMultiScrollIndex((i) => Math.min(totalParticipants - multiVisibleCount, i + 1))\n }\n />\n </div>\n ) : currentParticipant ? (\n <>\n <ParticipantTile\n trackRef={currentParticipant}\n participant={currentParticipant.participant}\n className=\"h-full w-full\"\n isFocusToggleDisable\n />\n {totalParticipants > 1 && (\n <CompactNavigationControls\n canPrev={canGoPrev}\n canNext={canGoNext}\n onPrev={goToPrev}\n onNext={goToNext}\n currentIndex={currentIndex}\n totalParticipants={totalParticipants}\n />\n )}\n </>\n ) : (\n emptyState\n )}\n </div>\n\n <div className=\"flex h-12 shrink-0 items-center gap-0.5\">\n <div className={barCn}>\n <DevicesBar\n className=\"h-[28px] w-[28px]\"\n microTrack={microphoneTrack?.track as LocalAudioTrack}\n microEnabled={isMicrophoneEnabled}\n microTrackToggle={{\n showIcon: true,\n source: Track.Source.Microphone,\n onChange: handleMicrophoneToggle,\n }}\n videoTrack={cameraTrack?.track as unknown as LocalVideoTrack}\n videoEnabled={isCameraEnabled}\n videoTrackToggle={{\n showIcon: true,\n source: Track.Source.Camera,\n onChange: handleCameraToggle,\n }}\n />\n </div>\n\n <div className={barCn}>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"none\"\n onClick={() => setViewMode(getNextCompactViewMode(compactViewMode))}\n className=\"hover:bg-gray-5 h-[28px] w-[28px] rounded-xl p-0 text-gray-100\"\n aria-label={viewModeToggleMeta.label}\n >\n <ViewModeIcon className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{viewModeToggleMeta.label}</TooltipContent>\n </Tooltip>\n </div>\n\n <div className={cn(barCn, 'ml-auto')}>\n <ScreenShareButton className=\"h-[28px] w-[28px]\" />\n <RaiseHandButton className=\"h-[28px] w-[28px]\" />\n </div>\n\n <div className={barCn}>\n <DisconnectButton className=\"h-[28px] w-[28px] rounded-xl\" />\n </div>\n </div>\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xipkg/calls-compactview",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -18,19 +18,20 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@xipkg/scrollarea": "2.2.0",
|
|
21
|
-
"@xipkg/userprofile": "4.0
|
|
21
|
+
"@xipkg/userprofile": "4.1.0",
|
|
22
22
|
"@xipkg/icons": "^3.0.15",
|
|
23
|
-
"@xipkg/textarea": "1.
|
|
23
|
+
"@xipkg/textarea": "1.2.0",
|
|
24
24
|
"@xipkg/button": "4.1.0",
|
|
25
|
-
"@xipkg/calls-ui": "^0.0.
|
|
26
|
-
"@xipkg/calls-utils": "^0.0.
|
|
27
|
-
"@xipkg/calls-types": "^0.0.
|
|
28
|
-
"@xipkg/calls-config": "^0.0.
|
|
29
|
-
"@xipkg/calls-providers": "^0.0.
|
|
30
|
-
"@xipkg/calls-store": "^0.0.
|
|
31
|
-
"@xipkg/calls-hooks": "^0.0.
|
|
32
|
-
"@xipkg/calls-chat": "^0.0.
|
|
33
|
-
"@xipkg/calls-risehand": "^0.0.
|
|
25
|
+
"@xipkg/calls-ui": "^0.0.5",
|
|
26
|
+
"@xipkg/calls-utils": "^0.0.5",
|
|
27
|
+
"@xipkg/calls-types": "^0.0.5",
|
|
28
|
+
"@xipkg/calls-config": "^0.0.5",
|
|
29
|
+
"@xipkg/calls-providers": "^0.0.5",
|
|
30
|
+
"@xipkg/calls-store": "^0.0.5",
|
|
31
|
+
"@xipkg/calls-hooks": "^0.0.5",
|
|
32
|
+
"@xipkg/calls-chat": "^0.0.5",
|
|
33
|
+
"@xipkg/calls-risehand": "^0.0.5",
|
|
34
|
+
"@xipkg/utils": "^1.8.0"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@tanstack/react-query-devtools": "5.73.3",
|
|
@@ -39,8 +40,8 @@
|
|
|
39
40
|
"@types/node": "^20.3.1",
|
|
40
41
|
"@types/react": "^19.0.2",
|
|
41
42
|
"@types/react-dom": "^19.0.2",
|
|
42
|
-
"@xipkg/eslint": "
|
|
43
|
-
"@xipkg/typescript": "
|
|
43
|
+
"@xipkg/eslint": "4.6.0",
|
|
44
|
+
"@xipkg/typescript": "0.2.0",
|
|
44
45
|
"common.eslint": "*",
|
|
45
46
|
"eslint": "^9.19.0",
|
|
46
47
|
"eslint-plugin-react-hooks": "^5.0.0",
|