@signalwire/js 3.6.0 → 3.7.1-dev.202201180939.d2ef427.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/src/BaseComponent.d.ts +5 -25
- package/dist/core/src/BaseComponent.d.ts.map +1 -1
- package/dist/core/src/BaseSession.d.ts +4 -2
- package/dist/core/src/BaseSession.d.ts.map +1 -1
- package/dist/core/src/chat/BaseChat.d.ts +4 -4
- package/dist/core/src/chat/BaseChat.d.ts.map +1 -1
- package/dist/core/src/chat/ChatMember.d.ts +9 -0
- package/dist/core/src/chat/ChatMember.d.ts.map +1 -0
- package/dist/core/src/chat/ChatMessage.d.ts +4 -4
- package/dist/core/src/chat/ChatMessage.d.ts.map +1 -1
- package/dist/core/src/chat/methods.d.ts +14 -0
- package/dist/core/src/chat/methods.d.ts.map +1 -1
- package/dist/core/src/chat/utils/index.d.ts +3 -0
- package/dist/core/src/chat/utils/index.d.ts.map +1 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.d.ts +3 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.d.ts.map +1 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.test.d.ts +2 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.test.d.ts.map +1 -0
- package/dist/core/src/chat/workers.d.ts.map +1 -1
- package/dist/core/src/internal/BaseBackendSession.d.ts.map +1 -1
- package/dist/core/src/internal/InternalRPC.d.ts +7 -7
- package/dist/core/src/internal/InternalRPC.d.ts.map +1 -1
- package/dist/core/src/redux/actions.d.ts +14 -14
- package/dist/core/src/redux/actions.d.ts.map +1 -1
- package/dist/core/src/redux/connect.d.ts.map +1 -1
- package/dist/core/src/redux/features/component/componentSaga.d.ts +4 -0
- package/dist/core/src/redux/features/component/componentSaga.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSaga.test.d.ts +2 -0
- package/dist/core/src/redux/features/component/componentSaga.test.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSelectors.d.ts +6 -2
- package/dist/core/src/redux/features/component/componentSelectors.d.ts.map +1 -1
- package/dist/core/src/redux/features/component/componentSelectors.test.d.ts +2 -0
- package/dist/core/src/redux/features/component/componentSelectors.test.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSlice.d.ts +3955 -9
- package/dist/core/src/redux/features/component/componentSlice.d.ts.map +1 -1
- package/dist/core/src/redux/features/executeQueue/executeQueueSlice.d.ts +44 -7
- package/dist/core/src/redux/features/executeQueue/executeQueueSlice.d.ts.map +1 -1
- package/dist/core/src/redux/features/session/sessionSaga.d.ts.map +1 -1
- package/dist/core/src/redux/features/session/sessionSlice.d.ts +74 -8
- package/dist/core/src/redux/features/session/sessionSlice.d.ts.map +1 -1
- package/dist/core/src/redux/index.d.ts +6 -25
- package/dist/core/src/redux/index.d.ts.map +1 -1
- package/dist/core/src/redux/interfaces.d.ts +2 -1
- package/dist/core/src/redux/interfaces.d.ts.map +1 -1
- package/dist/core/src/redux/rootReducer.d.ts +417 -3
- package/dist/core/src/redux/rootReducer.d.ts.map +1 -1
- package/dist/core/src/redux/rootSaga.d.ts +1 -1
- package/dist/core/src/redux/rootSaga.d.ts.map +1 -1
- package/dist/core/src/redux/toolkit/configureStore.d.ts +77 -0
- package/dist/core/src/redux/toolkit/configureStore.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createAction.d.ts +180 -0
- package/dist/core/src/redux/toolkit/createAction.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createReducer.d.ts +42 -0
- package/dist/core/src/redux/toolkit/createReducer.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createSlice.d.ts +142 -0
- package/dist/core/src/redux/toolkit/createSlice.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/devtoolsExtension.d.ts +185 -0
- package/dist/core/src/redux/toolkit/devtoolsExtension.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/getDefaultMiddleware.d.ts +12 -0
- package/dist/core/src/redux/toolkit/getDefaultMiddleware.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/index.d.ts +13 -0
- package/dist/core/src/redux/toolkit/index.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/isPlainObject.d.ts +12 -0
- package/dist/core/src/redux/toolkit/isPlainObject.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/mapBuilders.d.ts +38 -0
- package/dist/core/src/redux/toolkit/mapBuilders.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/tsHelpers.d.ts +51 -0
- package/dist/core/src/redux/toolkit/tsHelpers.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/utils.d.ts +11 -0
- package/dist/core/src/redux/toolkit/utils.d.ts.map +1 -0
- package/dist/core/src/redux/utils/createDestroyableSlice.d.ts +3 -2
- package/dist/core/src/redux/utils/createDestroyableSlice.d.ts.map +1 -1
- package/dist/core/src/testUtils.d.ts +6 -25
- package/dist/core/src/testUtils.d.ts.map +1 -1
- package/dist/core/src/types/chat.d.ts +94 -18
- package/dist/core/src/types/chat.d.ts.map +1 -1
- package/dist/core/src/types/index.d.ts +2 -0
- package/dist/core/src/types/index.d.ts.map +1 -1
- package/dist/core/src/types/utils.d.ts +15 -4
- package/dist/core/src/types/utils.d.ts.map +1 -1
- package/dist/core/src/types/videoRoomSession.d.ts +4 -1
- package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
- package/dist/core/src/utils/eventTransformUtils.d.ts.map +1 -1
- package/dist/core/src/utils/index.d.ts +4 -1
- package/dist/core/src/utils/index.d.ts.map +1 -1
- package/dist/core/src/utils/proxyUtils.d.ts +10 -0
- package/dist/core/src/utils/proxyUtils.d.ts.map +1 -0
- package/dist/index.esm.js +14 -14
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +44 -41
- package/dist/index.js.map +3 -3
- package/dist/index.umd.js +3 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/js/src/Client.d.ts +2 -2
- package/dist/js/src/Client.d.ts.map +1 -1
- package/dist/js/src/JWTSession.d.ts.map +1 -1
- package/dist/js/src/RoomSession.docs.d.ts +5 -0
- package/dist/js/src/RoomSession.docs.d.ts.map +1 -1
- package/dist/js/src/RoomSessionDevice.docs.d.ts +2 -0
- package/dist/js/src/RoomSessionDevice.docs.d.ts.map +1 -1
- package/dist/js/src/RoomSessionScreenShare.docs.d.ts +2 -0
- package/dist/js/src/RoomSessionScreenShare.docs.d.ts.map +1 -1
- package/dist/js/src/chat/Client.d.ts +16 -0
- package/dist/js/src/chat/Client.d.ts.map +1 -0
- package/dist/js/src/chat/index.d.ts +2 -0
- package/dist/js/src/chat/index.d.ts.map +1 -0
- package/dist/js/src/createClient.d.ts +1 -21
- package/dist/js/src/createClient.d.ts.map +1 -1
- package/dist/js/src/features/actions.d.ts +1 -1
- package/dist/js/src/features/actions.d.ts.map +1 -1
- package/dist/js/src/index.d.ts +1 -1
- package/dist/js/src/index.d.ts.map +1 -1
- package/dist/js/src/testUtils.d.ts +8 -48
- package/dist/js/src/testUtils.d.ts.map +1 -1
- package/dist/js/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webrtc/src/BaseConnection.d.ts +3 -0
- package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
- package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
- package/dist/webrtc/src/utils/webrtcHelpers.native.d.ts +2 -2
- package/dist/webrtc/src/utils/webrtcHelpers.native.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Client.ts +3 -3
- package/src/RoomSession.docs.ts +6 -0
- package/src/RoomSessionDevice.docs.ts +3 -0
- package/src/RoomSessionScreenShare.docs.ts +3 -0
- package/src/chat/Client.test.ts +652 -0
- package/src/chat/{Chat.ts → Client.ts} +14 -14
- package/src/chat/index.ts +1 -0
- package/src/createClient.ts +1 -21
- package/src/index.ts +1 -1
- package/src/utils/constants.ts +1 -1
- package/dist/js/src/chat/Chat.d.ts +0 -16
- package/dist/js/src/chat/Chat.d.ts.map +0 -1
- package/src/chat/Chat.test.ts +0 -219
package/src/createClient.ts
CHANGED
|
@@ -16,30 +16,10 @@ import { JWTSession } from './JWTSession'
|
|
|
16
16
|
* Create a client
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
|
-
* With autoConnect true the client is ready to be used.
|
|
20
19
|
* ```js
|
|
21
20
|
* try {
|
|
22
|
-
* const client =
|
|
23
|
-
* token: '<YourToken>',
|
|
24
|
-
* })
|
|
25
|
-
*
|
|
26
|
-
* // Your client is already connected..
|
|
27
|
-
* } catch (error) {
|
|
28
|
-
* console.error('Auth Error', error)
|
|
29
|
-
* }
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* With autoConnect false you can attach additional handlers.
|
|
34
|
-
* ```js
|
|
35
|
-
* try {
|
|
36
|
-
* const client = await Video.createClient({
|
|
21
|
+
* const client = Video.createClient({
|
|
37
22
|
* token: '<YourJWT>',
|
|
38
|
-
* autoConnect: false,
|
|
39
|
-
* })
|
|
40
|
-
*
|
|
41
|
-
* client.on('socket.closed', () => {
|
|
42
|
-
* // The WebSocket connection is closed
|
|
43
23
|
* })
|
|
44
24
|
*
|
|
45
25
|
* await client.connect()
|
package/src/index.ts
CHANGED
package/src/utils/constants.ts
CHANGED
|
@@ -10,8 +10,8 @@ export const ROOM_COMPONENT_LISTENERS = {
|
|
|
10
10
|
|
|
11
11
|
export const SCREENSHARE_AUDIO_CONSTRAINTS: MediaTrackConstraints = {
|
|
12
12
|
echoCancellation: false,
|
|
13
|
-
// @ts-expect-error
|
|
14
13
|
noiseSuppression: false,
|
|
15
14
|
autoGainControl: false,
|
|
15
|
+
// @ts-expect-error
|
|
16
16
|
googAutoGainControl: false,
|
|
17
17
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { AssertSameType, ChatContract, ConsumerContract, UserOptions, Chat as ChatNamespace } from '@signalwire/core';
|
|
2
|
-
export interface ChatApiEvents extends ChatNamespace.BaseChatApiEvents {
|
|
3
|
-
}
|
|
4
|
-
export interface ChatFullState extends Chat {
|
|
5
|
-
}
|
|
6
|
-
interface ChatMain extends ChatContract, Omit<ConsumerContract<ChatApiEvents, ChatFullState>, 'subscribe'> {
|
|
7
|
-
}
|
|
8
|
-
interface ChatDocs extends ChatMain {
|
|
9
|
-
}
|
|
10
|
-
export interface Chat extends AssertSameType<ChatMain, ChatDocs> {
|
|
11
|
-
}
|
|
12
|
-
export interface ChatOptions extends UserOptions {
|
|
13
|
-
}
|
|
14
|
-
export declare const Chat: new (chatOptions: ChatOptions) => Chat;
|
|
15
|
-
export {};
|
|
16
|
-
//# sourceMappingURL=Chat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../../src/chat/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,IAAI,IAAI,aAAa,EACtB,MAAM,kBAAkB,CAAA;AAIzB,MAAM,WAAW,aAAc,SAAQ,aAAa,CAAC,iBAAiB;CAAG;AAEzE,MAAM,WAAW,aAAc,SAAQ,IAAI;CAAG;AAC9C,UAAU,QACR,SAAQ,YAAY,EAClB,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,WAAW,CAAC;CAAG;AAExE,UAAU,QAAS,SAAQ,QAAQ;CAAG;AAEtC,MAAM,WAAW,IAAK,SAAQ,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAAG;AAEnE,MAAM,WAAW,WAAY,SAAQ,WAAW;CAAG;AAEnD,eAAO,MAAM,IAAI,oBA+BmB,WAAW,KAAG,IAAM,CAAA"}
|
package/src/chat/Chat.test.ts
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import WS from 'jest-websocket-mock'
|
|
2
|
-
import { Chat } from './Chat'
|
|
3
|
-
|
|
4
|
-
describe('Chat Object', () => {
|
|
5
|
-
const host = 'ws://localhost:1234'
|
|
6
|
-
const token = '<jwt>'
|
|
7
|
-
|
|
8
|
-
let server: WS
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
server = new WS(host)
|
|
11
|
-
server.on('connection', (socket) => {
|
|
12
|
-
socket.on('message', (data: any) => {
|
|
13
|
-
const parsedData = JSON.parse(data)
|
|
14
|
-
|
|
15
|
-
socket.send(
|
|
16
|
-
JSON.stringify({
|
|
17
|
-
jsonrpc: '2.0',
|
|
18
|
-
id: parsedData.id,
|
|
19
|
-
result: {},
|
|
20
|
-
})
|
|
21
|
-
)
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
afterEach(() => {
|
|
27
|
-
WS.clean()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should automatically connect when calling either .subscribe() or .publish()', async () => {
|
|
31
|
-
const chat = new Chat({
|
|
32
|
-
host,
|
|
33
|
-
token,
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
chat.on('message', () => {})
|
|
37
|
-
await chat.subscribe(['test'])
|
|
38
|
-
await chat.publish({
|
|
39
|
-
channel: 'test',
|
|
40
|
-
message: 'test',
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
const connectMsg = JSON.parse(server.messages[0].toString())
|
|
44
|
-
expect(connectMsg.method).toBe('signalwire.connect')
|
|
45
|
-
expect(server.messages.length).toBe(3)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('should emit a single "signalwire.connect" at most when subscribing/publishing at the same time', async () => {
|
|
49
|
-
const chat = new Chat({
|
|
50
|
-
host,
|
|
51
|
-
token,
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
chat.on('message', () => {})
|
|
55
|
-
await Promise.all([
|
|
56
|
-
chat.subscribe(['test']),
|
|
57
|
-
chat.publish({
|
|
58
|
-
channel: 'test',
|
|
59
|
-
message: 'test',
|
|
60
|
-
}),
|
|
61
|
-
])
|
|
62
|
-
|
|
63
|
-
const connectMsg = JSON.parse(server.messages[0].toString())
|
|
64
|
-
expect(connectMsg.method).toBe('signalwire.connect')
|
|
65
|
-
expect(
|
|
66
|
-
server.messages.filter((message) => {
|
|
67
|
-
const parsedMessage = JSON.parse(message.toString())
|
|
68
|
-
|
|
69
|
-
return parsedMessage.method === 'signalwire.connect'
|
|
70
|
-
}).length
|
|
71
|
-
).toBe(1)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
describe('Subscribe', () => {
|
|
75
|
-
it('should convert channels into the internal channel notation when calling .subscribe()', async () => {
|
|
76
|
-
const chat = new Chat({
|
|
77
|
-
host,
|
|
78
|
-
token,
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
chat.on('message', () => {})
|
|
82
|
-
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
83
|
-
|
|
84
|
-
const subscribeMsg = JSON.parse(server.messages[1].toString())
|
|
85
|
-
expect(subscribeMsg.params.channels).toStrictEqual([
|
|
86
|
-
{ name: 'test1' },
|
|
87
|
-
{ name: 'test2' },
|
|
88
|
-
{ name: 'test3' },
|
|
89
|
-
])
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
describe('Publish', () => {
|
|
94
|
-
it('should support publishing-only mode', async () => {
|
|
95
|
-
const chat = new Chat({
|
|
96
|
-
host,
|
|
97
|
-
token,
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
const params = {
|
|
101
|
-
channel: 'test',
|
|
102
|
-
message: 'test',
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
await chat.publish(params)
|
|
106
|
-
|
|
107
|
-
server.messages.forEach((message, i) => {
|
|
108
|
-
const parsedMessage = JSON.parse(message.toString())
|
|
109
|
-
|
|
110
|
-
if (i === 0) {
|
|
111
|
-
expect(parsedMessage.method).toBe('signalwire.connect')
|
|
112
|
-
} else {
|
|
113
|
-
expect(parsedMessage.method).toBe('chat.publish')
|
|
114
|
-
expect(parsedMessage.params).toStrictEqual(params)
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
describe('Unsubscribe', () => {
|
|
121
|
-
it('should convert channels into the internal channel notation when calling .unsubscribe()', async () => {
|
|
122
|
-
const chat = new Chat({
|
|
123
|
-
host,
|
|
124
|
-
token,
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
chat.on('message', () => {})
|
|
128
|
-
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
129
|
-
await chat.unsubscribe(['test1', 'test2', 'test3'])
|
|
130
|
-
|
|
131
|
-
const unsubscribeMsg = JSON.parse(server.messages[1].toString())
|
|
132
|
-
expect(unsubscribeMsg.params.channels).toStrictEqual([
|
|
133
|
-
{ name: 'test1' },
|
|
134
|
-
{ name: 'test2' },
|
|
135
|
-
{ name: 'test3' },
|
|
136
|
-
])
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
it('should allow the user to .unsubscribe() from any subgroup of subscribed channels', async () => {
|
|
140
|
-
expect.assertions(4)
|
|
141
|
-
const chat = new Chat({
|
|
142
|
-
host,
|
|
143
|
-
token,
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
chat.on('message', () => {})
|
|
147
|
-
|
|
148
|
-
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
149
|
-
expect(await chat.unsubscribe(['test1', 'test3'])).toBeUndefined()
|
|
150
|
-
expect(await chat.unsubscribe(['test1', 'test2'])).toBeUndefined()
|
|
151
|
-
expect(await chat.unsubscribe(['test2', 'test3'])).toBeUndefined()
|
|
152
|
-
expect(
|
|
153
|
-
await chat.unsubscribe(['test1', 'test2', 'test3'])
|
|
154
|
-
).toBeUndefined()
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it('should throw if the user calls .unsubscribe() before the session is authorized', async () => {
|
|
158
|
-
expect.assertions(1)
|
|
159
|
-
const chat = new Chat({
|
|
160
|
-
host,
|
|
161
|
-
token,
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
chat.on('message', () => {})
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
await chat.unsubscribe(['test1'])
|
|
168
|
-
} catch (err) {
|
|
169
|
-
expect(err.message).toBe(
|
|
170
|
-
'You must be authenticated to unsubscribe from a channel'
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
it('should throw if the user calls .unsubscribe() without being subscribed to channels', async () => {
|
|
176
|
-
expect.assertions(1)
|
|
177
|
-
const chat = new Chat({
|
|
178
|
-
host,
|
|
179
|
-
token,
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
chat.on('message', () => {})
|
|
183
|
-
|
|
184
|
-
// This is to force the session to be connected when
|
|
185
|
-
// calling unsubscribe()
|
|
186
|
-
await chat.publish({
|
|
187
|
-
channel: 'test',
|
|
188
|
-
message: 'test',
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
await chat.unsubscribe(['test1'])
|
|
193
|
-
} catch (err) {
|
|
194
|
-
expect(err.message).toBe(
|
|
195
|
-
'You must subscribe to at least one channel before calling unsubscribe()'
|
|
196
|
-
)
|
|
197
|
-
}
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it('should throw if the user calls .unsubscribe() with channels different than the ones they are subscribed to', async () => {
|
|
201
|
-
expect.assertions(1)
|
|
202
|
-
const chat = new Chat({
|
|
203
|
-
host,
|
|
204
|
-
token,
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
chat.on('message', () => {})
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
await chat.subscribe(['test1', 'test2', 'test3', 'test4'])
|
|
211
|
-
await chat.unsubscribe(['test1', 'test5'])
|
|
212
|
-
} catch (err) {
|
|
213
|
-
expect(err.message).toBe(
|
|
214
|
-
`You can't unsubscribe from a channel that you didn't subscribe to. You're subscribed to the following channels: test1, test2, test3, test4 but tried to unsubscribe from: test1, test5`
|
|
215
|
-
)
|
|
216
|
-
}
|
|
217
|
-
})
|
|
218
|
-
})
|
|
219
|
-
})
|