kasunk99-livestream-core 0.2.4 → 0.2.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/components/LiveStreamViewerItem.js +5 -5
- package/dist/hooks/useViewerSocket.d.ts +2 -0
- package/dist/hooks/useViewerSocket.d.ts.map +1 -1
- package/dist/hooks/useViewerSocket.js +11 -1
- package/dist/services/livestream.service.d.ts.map +1 -1
- package/dist/services/livestream.service.js +6 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -17,10 +17,10 @@ catch {
|
|
|
17
17
|
*/
|
|
18
18
|
export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream, isActive, index, }) {
|
|
19
19
|
const roomId = isActive ? stream.roomId : null;
|
|
20
|
-
const { joined, joining, error, producerList, roomState, remoteStream, remoteVideoStream, webrtcUnavailable, consumeError, socket, } = useViewerSocket(roomId);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const { joined, joining, error, producerList, roomState, remoteStream, remoteVideoStream, webrtcUnavailable, consumeError, socket, viewerCount: liveViewerCount, } = useViewerSocket(roomId);
|
|
21
|
+
// Prefer real-time socket count (updated on every join/leave event);
|
|
22
|
+
// fall back to the HTTP-polled value from the feed for the initial render.
|
|
23
|
+
const viewerCount = liveViewerCount > 0 ? liveViewerCount : stream.viewerCount;
|
|
24
24
|
const hasVideo = producerList.some((p) => p.kind === 'video');
|
|
25
25
|
const streamObj = remoteStream;
|
|
26
26
|
const hasVideoTrack = streamObj &&
|
|
@@ -147,7 +147,7 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
|
|
|
147
147
|
}
|
|
148
148
|
});
|
|
149
149
|
};
|
|
150
|
-
return (_jsxs(View, { style: styles.container, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: styles.rtcView, objectFit: "contain", mirror: false }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: styles.videoPlaceholder, children: [joining && _jsx(Text, { style: styles.placeholderText, children: "Joining..." }), error && _jsx(Text, { style: [styles.placeholderText, styles.errorText], children: error }), joined && !joining && !error && (_jsxs(_Fragment, { children: [_jsx(Text, { style: styles.liveBadge, children: "LIVE" }), _jsx(Text, { style: styles.placeholderText, children: stream.roomId }), hasVideo && webrtcUnavailable && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Video needs a development build.", '\n', "Run: npx expo run:android"] })), hasVideo && consumeError && (_jsx(Text, { style: [styles.hintText, styles.errorText], children: consumeError })), hasVideo && !remoteStream && !webrtcUnavailable && !consumeError && (_jsx(Text, { style: styles.hintText, children: "Loading video..." })), !hasVideo && joined && producerList.length === 0 && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Host has not started camera yet.", '\n', "Use a web client to stream, or wait for host to produce."] })), hasVideo && remoteStream && !RTCViewComponent && (_jsx(Text, { style: styles.hintText, children: "Video received (use dev build to see it)" })), hasVideo && remoteStream && RTCViewComponent && !hasVideoTrack && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Audio only (no video track yet)" })), hasVideo && remoteStream && hasVideoTrack && !streamURL && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Video track received but cannot display (need dev build with react-native-webrtc)" }))] }))] })), _jsxs(View, { style: styles.overlay, children: [_jsxs(View, { style: styles.topMeta, children: [_jsx(View, { style: styles.row, children: _jsxs(Text, { style: styles.roomId, numberOfLines: 1, children: ["LIVE \u00B7 ", stream.roomId] }) }), _jsxs(View, { style: styles.stats, children: [_jsxs(Text, { style: styles.statsText, children: ["\uD83D\uDC41 ", viewerCount] }), _jsxs(Text, { style: [styles.statsText, styles.statsTextSpacer], children: ["\u00B7 ", stream.producerCount, " track(s)"] })] })] }), _jsx(View, { style: styles.chatPanel, pointerEvents: "box-none", children: _jsx(KeyboardAvoidingView, { style: styles.chatKeyboardAvoider, behavior: Platform.OS === 'ios' ? 'padding' : 'height', keyboardVerticalOffset: 0, children: _jsxs(View, { style: styles.chatStack, children: [_jsx(View, { style: styles.chatListWrapper, children: _jsx(ScrollView, { ref: chatListRef, contentContainerStyle: styles.chatListContent, showsVerticalScrollIndicator: false, keyboardDismissMode: "on-drag", keyboardShouldPersistTaps: "always", nestedScrollEnabled: true, children: chatData.map((item) => (_jsxs(Text, { style: styles.chatLine, numberOfLines: 2, children: [_jsx(Text, { style: [styles.chatName, { color: getNameColor(item.displayName) }], children: item.displayName }), _jsxs(Text, { style: styles.chatText, children: [" ", item.text] })] }, item.id))) }) }), _jsxs(View, { style: styles.chatInputRow, children: [_jsx(TextInput, { style: styles.chatInput, value: chatInput, onChangeText: setChatInput, placeholder: joined ? 'Say something...' : 'Connecting...', placeholderTextColor: "#9ca3af", editable: joined && !joining && !error, onSubmitEditing: sendChat, returnKeyType: "send" }), _jsx(TouchableOpacity, { onPress: sendChat, disabled: !joined || joining || !!error || !chatInput.trim(), style: [
|
|
150
|
+
return (_jsxs(View, { style: styles.container, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: styles.rtcView, objectFit: "contain", mirror: false }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: styles.videoPlaceholder, children: [joining && _jsx(Text, { style: styles.placeholderText, children: "Joining..." }), error && _jsx(Text, { style: [styles.placeholderText, styles.errorText], children: error }), joined && !joining && !error && (_jsxs(_Fragment, { children: [_jsx(Text, { style: styles.liveBadge, children: "LIVE" }), _jsx(Text, { style: styles.placeholderText, children: stream.roomId }), hasVideo && webrtcUnavailable && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Video needs a development build.", '\n', "Run: npx expo run:android"] })), hasVideo && consumeError && (_jsx(Text, { style: [styles.hintText, styles.errorText], children: consumeError })), hasVideo && !remoteStream && !webrtcUnavailable && !consumeError && (_jsx(Text, { style: styles.hintText, children: "Loading video..." })), !hasVideo && joined && producerList.length === 0 && (_jsxs(Text, { style: [styles.hintText, styles.warnText], children: ["Host has not started camera yet.", '\n', "Use a web client to stream, or wait for host to produce."] })), hasVideo && remoteStream && !RTCViewComponent && (_jsx(Text, { style: styles.hintText, children: "Video received (use dev build to see it)" })), hasVideo && remoteStream && RTCViewComponent && !hasVideoTrack && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Audio only (no video track yet)" })), hasVideo && remoteStream && hasVideoTrack && !streamURL && (_jsx(Text, { style: [styles.hintText, styles.warnText], children: "Video track received but cannot display (need dev build with react-native-webrtc)" }))] }))] })), _jsxs(View, { style: styles.overlay, children: [_jsxs(View, { style: styles.topMeta, children: [_jsx(View, { style: styles.row, children: _jsxs(Text, { style: styles.roomId, numberOfLines: 1, children: ["LIVE \u00B7 ", stream.hostDisplayName || stream.title || stream.roomId] }) }), _jsxs(View, { style: styles.stats, children: [_jsxs(Text, { style: styles.statsText, children: ["\uD83D\uDC41 ", viewerCount] }), _jsxs(Text, { style: [styles.statsText, styles.statsTextSpacer], children: ["\u00B7 ", stream.producerCount, " track(s)"] })] })] }), _jsx(View, { style: styles.chatPanel, pointerEvents: "box-none", children: _jsx(KeyboardAvoidingView, { style: styles.chatKeyboardAvoider, behavior: Platform.OS === 'ios' ? 'padding' : 'height', keyboardVerticalOffset: 0, children: _jsxs(View, { style: styles.chatStack, children: [_jsx(View, { style: styles.chatListWrapper, children: _jsx(ScrollView, { ref: chatListRef, contentContainerStyle: styles.chatListContent, showsVerticalScrollIndicator: false, keyboardDismissMode: "on-drag", keyboardShouldPersistTaps: "always", nestedScrollEnabled: true, children: chatData.map((item) => (_jsxs(Text, { style: styles.chatLine, numberOfLines: 2, children: [_jsx(Text, { style: [styles.chatName, { color: getNameColor(item.displayName) }], children: item.displayName }), _jsxs(Text, { style: styles.chatText, children: [" ", item.text] })] }, item.id))) }) }), _jsxs(View, { style: styles.chatInputRow, children: [_jsx(TextInput, { style: styles.chatInput, value: chatInput, onChangeText: setChatInput, placeholder: joined ? 'Say something...' : 'Connecting...', placeholderTextColor: "#9ca3af", editable: joined && !joining && !error, onSubmitEditing: sendChat, returnKeyType: "send" }), _jsx(TouchableOpacity, { onPress: sendChat, disabled: !joined || joining || !!error || !chatInput.trim(), style: [
|
|
151
151
|
styles.chatSendButton,
|
|
152
152
|
(!joined || joining || !!error || !chatInput.trim()) && styles.chatSendButtonDisabled,
|
|
153
153
|
], children: _jsx(Text, { style: styles.chatSendText, children: "\u27A4" }) })] })] }) }) })] })] }));
|
|
@@ -13,6 +13,8 @@ type ViewerSocketState = {
|
|
|
13
13
|
consumeError: string | null;
|
|
14
14
|
/** Incremented to trigger one auto-retry when recv transport fails (ICE). */
|
|
15
15
|
consumeRetryKey: number;
|
|
16
|
+
/** Real-time viewer count, updated via viewer-count-updated socket event. */
|
|
17
|
+
viewerCount: number;
|
|
16
18
|
};
|
|
17
19
|
/**
|
|
18
20
|
* Connects to the livestream signaling server and joins a room as viewer.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useViewerSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewerSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"useViewerSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewerSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CA2dpG"}
|
|
@@ -20,6 +20,7 @@ export function useViewerSocket(roomId) {
|
|
|
20
20
|
webrtcUnavailable: false,
|
|
21
21
|
consumeError: null,
|
|
22
22
|
consumeRetryKey: 0,
|
|
23
|
+
viewerCount: 0,
|
|
23
24
|
});
|
|
24
25
|
const socketRef = useRef(null);
|
|
25
26
|
const roomIdRef = useRef(roomId);
|
|
@@ -61,6 +62,7 @@ export function useViewerSocket(roomId) {
|
|
|
61
62
|
webrtcUnavailable: false,
|
|
62
63
|
consumeError: null,
|
|
63
64
|
consumeRetryKey: 0,
|
|
65
|
+
viewerCount: 0,
|
|
64
66
|
});
|
|
65
67
|
consumeRetryCountRef.current = 0;
|
|
66
68
|
}, []);
|
|
@@ -156,14 +158,17 @@ export function useViewerSocket(roomId) {
|
|
|
156
158
|
if (Array.isArray(iceFromJoin) && iceFromJoin.length > 0) {
|
|
157
159
|
iceServersRef.current = iceFromJoin;
|
|
158
160
|
}
|
|
161
|
+
const roomState = res.roomState ?? null;
|
|
162
|
+
const initialViewerCount = typeof roomState?.viewerCount === 'number' ? roomState.viewerCount : 0;
|
|
159
163
|
setState((prev) => ({
|
|
160
164
|
...prev,
|
|
161
165
|
joining: false,
|
|
162
166
|
joined: true,
|
|
163
167
|
producerList: res.producerList ?? [],
|
|
164
|
-
roomState
|
|
168
|
+
roomState,
|
|
165
169
|
rtpCapabilities: res.rtpCapabilities ?? null,
|
|
166
170
|
error: null,
|
|
171
|
+
viewerCount: initialViewerCount,
|
|
167
172
|
}));
|
|
168
173
|
});
|
|
169
174
|
});
|
|
@@ -191,6 +196,11 @@ export function useViewerSocket(roomId) {
|
|
|
191
196
|
}
|
|
192
197
|
});
|
|
193
198
|
});
|
|
199
|
+
socket.on('viewer-count-updated', (payload) => {
|
|
200
|
+
if (typeof payload?.viewerCount === 'number') {
|
|
201
|
+
setState((prev) => ({ ...prev, viewerCount: payload.viewerCount }));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
194
204
|
})();
|
|
195
205
|
return () => {
|
|
196
206
|
clearTimeout(joinTimeout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livestream.service.d.ts","sourceRoot":"","sources":["../../src/services/livestream.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC5C;IAAE,OAAO,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"livestream.service.d.ts","sourceRoot":"","sources":["../../src/services/livestream.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC5C;IAAE,OAAO,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAiBnC,MAAM,MAAM,qBAAqB,GAC7B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAChC;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/F;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CA+BtE;AAED,wBAAsB,YAAY,CAAC,MAAM,CAAC,EAAE;IAC1C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsC9B;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAyBjC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
|
@@ -8,7 +8,12 @@ function normalizeStreamRow(row) {
|
|
|
8
8
|
return null;
|
|
9
9
|
const viewerCount = typeof row?.viewerCount === 'number' ? row.viewerCount : typeof row?.viewer_count === 'number' ? row.viewer_count : 0;
|
|
10
10
|
const producerCount = typeof row?.producerCount === 'number' ? row.producerCount : typeof row?.producer_count === 'number' ? row.producer_count : 0;
|
|
11
|
-
|
|
11
|
+
const title = typeof row?.title === 'string' ? row.title : null;
|
|
12
|
+
const hostDisplayName = typeof row?.hostDisplayName === 'string' ? row.hostDisplayName :
|
|
13
|
+
typeof row?.host_display_name === 'string' ? row.host_display_name : null;
|
|
14
|
+
const hostUserId = typeof row?.hostUserId === 'string' ? row.hostUserId :
|
|
15
|
+
typeof row?.host_user_id === 'string' ? row.host_user_id : null;
|
|
16
|
+
return { roomId, viewerCount, producerCount, title, hostDisplayName, hostUserId };
|
|
12
17
|
}
|
|
13
18
|
export async function fetchActiveStreams() {
|
|
14
19
|
const base = getBaseUrl();
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export type LiveStreamInfo = {
|
|
|
6
6
|
roomId: string;
|
|
7
7
|
viewerCount: number;
|
|
8
8
|
producerCount: number;
|
|
9
|
+
title?: string | null;
|
|
10
|
+
hostDisplayName?: string | null;
|
|
11
|
+
hostUserId?: string | null;
|
|
9
12
|
};
|
|
10
13
|
export type ProducerInfo = {
|
|
11
14
|
id: string;
|
|
@@ -27,6 +30,8 @@ export type RoomState = {
|
|
|
27
30
|
chat?: unknown[];
|
|
28
31
|
likes?: number;
|
|
29
32
|
viewerCount?: number;
|
|
33
|
+
cards?: unknown[];
|
|
34
|
+
shares?: number;
|
|
30
35
|
[key: string]: unknown;
|
|
31
36
|
};
|
|
32
37
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC"}
|
package/package.json
CHANGED