@colyseus/sdk 0.17.42 → 0.18.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/build/3rd_party/discord.cjs +1 -1
- package/build/3rd_party/discord.mjs +1 -1
- package/build/Auth.cjs +16 -2
- package/build/Auth.cjs.map +1 -1
- package/build/Auth.mjs +16 -2
- package/build/Auth.mjs.map +1 -1
- package/build/Client.cjs +1 -1
- package/build/Client.mjs +1 -1
- package/build/Connection.cjs +1 -1
- package/build/Connection.mjs +1 -1
- package/build/HTTP.cjs +1 -1
- package/build/HTTP.mjs +1 -1
- package/build/Room.cjs +231 -46
- package/build/Room.cjs.map +1 -1
- package/build/Room.d.ts +62 -2
- package/build/Room.mjs +229 -44
- package/build/Room.mjs.map +1 -1
- package/build/Storage.cjs +1 -1
- package/build/Storage.mjs +1 -1
- package/build/core/nanoevents.cjs +1 -1
- package/build/core/nanoevents.mjs +1 -1
- package/build/core/signal.cjs +1 -1
- package/build/core/signal.cjs.map +1 -1
- package/build/core/signal.mjs +1 -1
- package/build/core/signal.mjs.map +1 -1
- package/build/core/utils.cjs +1 -1
- package/build/core/utils.mjs +1 -1
- package/build/debug.cjs +1 -1
- package/build/debug.cjs.map +1 -1
- package/build/debug.mjs +1 -1
- package/build/debug.mjs.map +1 -1
- package/build/errors/Errors.cjs +1 -1
- package/build/errors/Errors.mjs +1 -1
- package/build/fetchXHR.cjs +1 -1
- package/build/fetchXHR.mjs +1 -1
- package/build/index.cjs +1 -1
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.mjs +1 -1
- package/build/index.mjs.map +1 -1
- package/build/input/InputHandle.cjs +47 -0
- package/build/input/InputHandle.cjs.map +1 -0
- package/build/input/InputHandle.d.ts +79 -0
- package/build/input/InputHandle.mjs +48 -0
- package/build/input/InputHandle.mjs.map +1 -0
- package/build/legacy.cjs +1 -1
- package/build/legacy.mjs +1 -1
- package/build/serializer/NoneSerializer.cjs +1 -1
- package/build/serializer/NoneSerializer.mjs +1 -1
- package/build/serializer/SchemaSerializer.cjs +1 -1
- package/build/serializer/SchemaSerializer.mjs +1 -1
- package/build/serializer/Serializer.cjs +1 -1
- package/build/serializer/Serializer.mjs +1 -1
- package/build/transport/H3Transport.cjs +21 -70
- package/build/transport/H3Transport.cjs.map +1 -1
- package/build/transport/H3Transport.d.ts +0 -16
- package/build/transport/H3Transport.mjs +23 -69
- package/build/transport/H3Transport.mjs.map +1 -1
- package/build/transport/WebSocketTransport.cjs +1 -1
- package/build/transport/WebSocketTransport.mjs +1 -1
- package/dist/colyseus.js +13172 -1953
- package/dist/colyseus.js.map +1 -1
- package/dist/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/package.json +11 -8
- package/src/Auth.ts +11 -1
- package/src/Room.ts +294 -48
- package/src/core/signal.ts +1 -1
- package/src/debug.ts +8 -8
- package/src/index.ts +1 -1
- package/src/input/InputHandle.ts +115 -0
- package/src/transport/H3Transport.ts +26 -76
- package/build/serializer/FossilDeltaSerializer.d.ts +0 -0
- package/src/serializer/FossilDeltaSerializer.ts +0 -39
|
@@ -3,65 +3,9 @@
|
|
|
3
3
|
// This software is released under the MIT License.
|
|
4
4
|
// https://opensource.org/license/MIT
|
|
5
5
|
//
|
|
6
|
-
// colyseus.js@0.
|
|
7
|
-
import {
|
|
6
|
+
// colyseus.js@0.18.0
|
|
7
|
+
import { encode, decode } from '@colyseus/schema';
|
|
8
8
|
|
|
9
|
-
// 9 bytes is the maximum length of a variable-length integer prefix
|
|
10
|
-
const MAX_LENGTH_PREFIX_BYTES = 9;
|
|
11
|
-
/**
|
|
12
|
-
* Reassembles length-prefixed frames from arbitrary byte chunks.
|
|
13
|
-
*
|
|
14
|
-
* A single WebTransport `reader.read()` may:
|
|
15
|
-
* - deliver multiple whole frames in one chunk
|
|
16
|
-
* - split a frame (or its length prefix) across multiple chunks
|
|
17
|
-
*
|
|
18
|
-
* This reassembler buffers partial data across reads so each dispatched
|
|
19
|
-
* frame is exactly one complete message.
|
|
20
|
-
*/
|
|
21
|
-
class FrameReassembler {
|
|
22
|
-
pending = new Uint8Array(0);
|
|
23
|
-
push(chunk) {
|
|
24
|
-
if (!chunk || chunk.byteLength === 0) {
|
|
25
|
-
return [];
|
|
26
|
-
}
|
|
27
|
-
const bytes = (this.pending.byteLength === 0)
|
|
28
|
-
? chunk
|
|
29
|
-
: concatBytes(this.pending, chunk);
|
|
30
|
-
const frames = [];
|
|
31
|
-
let offset = 0;
|
|
32
|
-
while (offset < bytes.byteLength) {
|
|
33
|
-
const it = { offset };
|
|
34
|
-
let length;
|
|
35
|
-
try {
|
|
36
|
-
length = decode.number(bytes, it);
|
|
37
|
-
}
|
|
38
|
-
catch (e) {
|
|
39
|
-
// length prefix is incomplete — wait for more bytes
|
|
40
|
-
if (bytes.byteLength - offset <= MAX_LENGTH_PREFIX_BYTES) {
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
throw e;
|
|
44
|
-
}
|
|
45
|
-
const frameEnd = it.offset + length;
|
|
46
|
-
if (frameEnd > bytes.byteLength) {
|
|
47
|
-
// payload is incomplete — wait for more bytes
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
frames.push(bytes.subarray(it.offset, frameEnd));
|
|
51
|
-
offset = frameEnd;
|
|
52
|
-
}
|
|
53
|
-
this.pending = (offset < bytes.byteLength)
|
|
54
|
-
? bytes.slice(offset)
|
|
55
|
-
: new Uint8Array(0);
|
|
56
|
-
return frames;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function concatBytes(a, b) {
|
|
60
|
-
const out = new Uint8Array(a.byteLength + b.byteLength);
|
|
61
|
-
out.set(a, 0);
|
|
62
|
-
out.set(b, a.byteLength);
|
|
63
|
-
return out;
|
|
64
|
-
}
|
|
65
9
|
class H3TransportTransport {
|
|
66
10
|
wt;
|
|
67
11
|
isOpen = false;
|
|
@@ -71,8 +15,6 @@ class H3TransportTransport {
|
|
|
71
15
|
unreliableReader;
|
|
72
16
|
unreliableWriter;
|
|
73
17
|
lengthPrefixBuffer = new Uint8Array(9); // 9 bytes is the maximum length of a length prefix
|
|
74
|
-
reliableReassembler = new FrameReassembler();
|
|
75
|
-
unreliableReassembler = new FrameReassembler();
|
|
76
18
|
constructor(events) {
|
|
77
19
|
this.events = events;
|
|
78
20
|
}
|
|
@@ -152,11 +94,17 @@ class H3TransportTransport {
|
|
|
152
94
|
//
|
|
153
95
|
// a single read may contain multiple messages
|
|
154
96
|
// each message is prefixed with its length
|
|
155
|
-
// a read may also deliver a partial frame; buffer across reads
|
|
156
97
|
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
98
|
+
const messages = result.value;
|
|
99
|
+
const it = { offset: 0 };
|
|
100
|
+
do {
|
|
101
|
+
//
|
|
102
|
+
// QUESTION: should we buffer the message in case it's not fully read?
|
|
103
|
+
//
|
|
104
|
+
const length = decode.number(messages, it);
|
|
105
|
+
this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });
|
|
106
|
+
it.offset += length;
|
|
107
|
+
} while (it.offset < messages.length);
|
|
160
108
|
}
|
|
161
109
|
catch (e) {
|
|
162
110
|
if (e.message.indexOf("session is closed") === -1) {
|
|
@@ -177,11 +125,17 @@ class H3TransportTransport {
|
|
|
177
125
|
//
|
|
178
126
|
// a single read may contain multiple messages
|
|
179
127
|
// each message is prefixed with its length
|
|
180
|
-
// a read may also deliver a partial frame; buffer across reads
|
|
181
128
|
//
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
129
|
+
const messages = result.value;
|
|
130
|
+
const it = { offset: 0 };
|
|
131
|
+
do {
|
|
132
|
+
//
|
|
133
|
+
// QUESTION: should we buffer the message in case it's not fully read?
|
|
134
|
+
//
|
|
135
|
+
const length = decode.number(messages, it);
|
|
136
|
+
this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });
|
|
137
|
+
it.offset += length;
|
|
138
|
+
} while (it.offset < messages.length);
|
|
185
139
|
}
|
|
186
140
|
catch (e) {
|
|
187
141
|
if (e.message.indexOf("session is closed") === -1) {
|
|
@@ -212,5 +166,5 @@ class H3TransportTransport {
|
|
|
212
166
|
}
|
|
213
167
|
}
|
|
214
168
|
|
|
215
|
-
export {
|
|
169
|
+
export { H3TransportTransport };
|
|
216
170
|
//# sourceMappingURL=H3Transport.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"H3Transport.mjs","sources":["../../src/transport/H3Transport.ts"],"sourcesContent":["import { encode, decode, type Iterator } from '@colyseus/schema';\nimport type { ITransport, ITransportEventMap } from \"./ITransport.ts\";\n\n// 9 bytes is the maximum length of a variable-length integer prefix\nconst MAX_LENGTH_PREFIX_BYTES = 9;\n\n/**\n * Reassembles length-prefixed frames from arbitrary byte chunks.\n *\n * A single WebTransport `reader.read()` may:\n * - deliver multiple whole frames in one chunk\n * - split a frame (or its length prefix) across multiple chunks\n *\n * This reassembler buffers partial data across reads so each dispatched\n * frame is exactly one complete message.\n */\nexport class FrameReassembler {\n private pending: Uint8Array = new Uint8Array(0);\n\n push(chunk: Uint8Array | undefined): Uint8Array[] {\n if (!chunk || chunk.byteLength === 0) { return []; }\n\n const bytes = (this.pending.byteLength === 0)\n ? chunk\n : concatBytes(this.pending, chunk);\n\n const frames: Uint8Array[] = [];\n let offset = 0;\n\n while (offset < bytes.byteLength) {\n const it: Iterator = { offset };\n let length: number;\n\n try {\n length = decode.number(bytes as any, it);\n } catch (e) {\n // length prefix is incomplete — wait for more bytes\n if (bytes.byteLength - offset <= MAX_LENGTH_PREFIX_BYTES) { break; }\n throw e;\n }\n\n const frameEnd = it.offset + length;\n if (frameEnd > bytes.byteLength) {\n // payload is incomplete — wait for more bytes\n break;\n }\n\n frames.push(bytes.subarray(it.offset, frameEnd));\n offset = frameEnd;\n }\n\n this.pending = (offset < bytes.byteLength)\n ? bytes.slice(offset)\n : new Uint8Array(0);\n\n return frames;\n }\n}\n\nfunction concatBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.byteLength + b.byteLength);\n out.set(a, 0);\n out.set(b, a.byteLength);\n return out;\n}\n\nexport class H3TransportTransport implements ITransport {\n wt: WebTransport;\n isOpen: boolean = false;\n events: ITransportEventMap;\n\n reader: ReadableStreamDefaultReader;\n writer: WritableStreamDefaultWriter;\n\n unreliableReader: ReadableStreamDefaultReader<Uint8Array>;\n unreliableWriter: WritableStreamDefaultWriter<Uint8Array>;\n\n private lengthPrefixBuffer = new Uint8Array(9); // 9 bytes is the maximum length of a length prefix\n\n private reliableReassembler = new FrameReassembler();\n private unreliableReassembler = new FrameReassembler();\n\n constructor(events: ITransportEventMap) {\n this.events = events;\n }\n\n public connect(url: string, options: any = {}) {\n const wtOpts: WebTransportOptions = options.fingerprint && ({\n // requireUnreliable: true,\n // congestionControl: \"default\", // \"low-latency\" || \"throughput\"\n\n serverCertificateHashes: [{\n algorithm: 'sha-256',\n value: new Uint8Array(options.fingerprint).buffer\n }]\n }) || undefined;\n\n this.wt = new WebTransport(url, wtOpts);\n\n this.wt.ready.then((e) => {\n console.log(\"WebTransport ready!\", e)\n this.isOpen = true;\n\n this.unreliableReader = this.wt.datagrams.readable.getReader();\n this.unreliableWriter = this.wt.datagrams.writable.getWriter();\n\n const incomingBidi = this.wt.incomingBidirectionalStreams.getReader();\n incomingBidi.read().then((stream) => {\n this.reader = stream.value.readable.getReader();\n this.writer = stream.value.writable.getWriter();\n\n // immediately write room/sessionId for establishing the room connection\n this.sendSeatReservation(options.roomId, options.sessionId, options.reconnectionToken, options.skipHandshake);\n\n // start reading incoming data\n this.readIncomingData();\n this.readIncomingUnreliableData();\n\n }).catch((e) => {\n console.error(\"failed to read incoming stream\", e);\n console.error(\"TODO: close the connection\");\n });\n\n // this.events.onopen(e);\n }).catch((e: WebTransportCloseInfo) => {\n // this.events.onerror(e);\n // this.events.onclose({ code: e.closeCode, reason: e.reason });\n console.log(\"WebTransport not ready!\", e)\n this._close();\n });\n\n this.wt.closed.then((e: WebTransportCloseInfo) => {\n console.log(\"WebTransport closed w/ success\", e)\n this.events.onclose({ code: e.closeCode, reason: e.reason });\n\n }).catch((e: WebTransportCloseInfo) => {\n console.log(\"WebTransport closed w/ error\", e)\n this.events.onerror(e);\n this.events.onclose({ code: e.closeCode, reason: e.reason });\n }).finally(() => {\n this._close();\n });\n }\n\n public send(data: Buffer | Uint8Array): void {\n const prefixLength = encode.number(this.lengthPrefixBuffer as any, data.length, { offset: 0 });\n const dataWithPrefixedLength = new Uint8Array(prefixLength + data.length);\n dataWithPrefixedLength.set(this.lengthPrefixBuffer.subarray(0, prefixLength), 0);\n dataWithPrefixedLength.set(data, prefixLength);\n this.writer.write(dataWithPrefixedLength);\n }\n\n public sendUnreliable(data: Buffer | Uint8Array): void {\n const prefixLength = encode.number(this.lengthPrefixBuffer as any, data.length, { offset: 0 });\n const dataWithPrefixedLength = new Uint8Array(prefixLength + data.length);\n dataWithPrefixedLength.set(this.lengthPrefixBuffer.subarray(0, prefixLength), 0);\n dataWithPrefixedLength.set(data, prefixLength);\n this.unreliableWriter.write(dataWithPrefixedLength);\n }\n\n public close(code?: number, reason?: string) {\n try {\n this.wt.close({ closeCode: code, reason: reason });\n } catch (e) {\n console.error(e);\n }\n }\n\n protected async readIncomingData() {\n let result: ReadableStreamReadResult<Uint8Array>;\n\n while (this.isOpen) {\n try {\n result = await this.reader.read();\n\n //\n // a single read may contain multiple messages\n // each message is prefixed with its length\n // a read may also deliver a partial frame; buffer across reads\n //\n for (const frame of this.reliableReassembler.push(result.value)) {\n this.events.onmessage({ data: frame });\n }\n\n } catch (e) {\n if (e.message.indexOf(\"session is closed\") === -1) {\n console.error(\"H3Transport: failed to read incoming data\", e);\n }\n break;\n }\n\n if (result.done) {\n break;\n }\n }\n }\n\n protected async readIncomingUnreliableData() {\n let result: ReadableStreamReadResult<Uint8Array>;\n\n while (this.isOpen) {\n try {\n result = await this.unreliableReader.read();\n\n //\n // a single read may contain multiple messages\n // each message is prefixed with its length\n // a read may also deliver a partial frame; buffer across reads\n //\n for (const frame of this.unreliableReassembler.push(result.value)) {\n this.events.onmessage({ data: frame });\n }\n\n } catch (e) {\n if (e.message.indexOf(\"session is closed\") === -1) {\n console.error(\"H3Transport: failed to read incoming data\", e);\n }\n break;\n }\n\n if (result.done) {\n break;\n }\n }\n }\n\n protected sendSeatReservation (roomId: string, sessionId: string, reconnectionToken?: string, skipHandshake?: boolean) {\n const it: Iterator = { offset: 0 };\n const bytes: number[] = [];\n\n encode.string(bytes, roomId, it);\n encode.string(bytes, sessionId, it);\n\n if (reconnectionToken) {\n encode.string(bytes, reconnectionToken, it);\n }\n\n if (skipHandshake) {\n encode.boolean(bytes, 1, it);\n }\n\n this.writer.write(new Uint8Array(bytes).buffer);\n }\n\n protected _close() {\n this.isOpen = false;\n }\n\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"H3Transport.mjs","sources":["../../src/transport/H3Transport.ts"],"sourcesContent":["import { encode, decode, type Iterator } from '@colyseus/schema';\nimport type { ITransport, ITransportEventMap } from \"./ITransport.ts\";\n\nexport class H3TransportTransport implements ITransport {\n wt: WebTransport;\n isOpen: boolean = false;\n events: ITransportEventMap;\n\n reader: ReadableStreamDefaultReader;\n writer: WritableStreamDefaultWriter;\n\n unreliableReader: ReadableStreamDefaultReader<Uint8Array>;\n unreliableWriter: WritableStreamDefaultWriter<Uint8Array>;\n\n private lengthPrefixBuffer = new Uint8Array(9); // 9 bytes is the maximum length of a length prefix\n\n constructor(events: ITransportEventMap) {\n this.events = events;\n }\n\n public connect(url: string, options: any = {}) {\n const wtOpts: WebTransportOptions = options.fingerprint && ({\n // requireUnreliable: true,\n // congestionControl: \"default\", // \"low-latency\" || \"throughput\"\n\n serverCertificateHashes: [{\n algorithm: 'sha-256',\n value: new Uint8Array(options.fingerprint).buffer\n }]\n }) || undefined;\n\n this.wt = new WebTransport(url, wtOpts);\n\n this.wt.ready.then((e) => {\n console.log(\"WebTransport ready!\", e)\n this.isOpen = true;\n\n this.unreliableReader = this.wt.datagrams.readable.getReader();\n this.unreliableWriter = this.wt.datagrams.writable.getWriter();\n\n const incomingBidi = this.wt.incomingBidirectionalStreams.getReader();\n incomingBidi.read().then((stream) => {\n this.reader = stream.value.readable.getReader();\n this.writer = stream.value.writable.getWriter();\n\n // immediately write room/sessionId for establishing the room connection\n this.sendSeatReservation(options.roomId, options.sessionId, options.reconnectionToken, options.skipHandshake);\n\n // start reading incoming data\n this.readIncomingData();\n this.readIncomingUnreliableData();\n\n }).catch((e) => {\n console.error(\"failed to read incoming stream\", e);\n console.error(\"TODO: close the connection\");\n });\n\n // this.events.onopen(e);\n }).catch((e: WebTransportCloseInfo) => {\n // this.events.onerror(e);\n // this.events.onclose({ code: e.closeCode, reason: e.reason });\n console.log(\"WebTransport not ready!\", e)\n this._close();\n });\n\n this.wt.closed.then((e: WebTransportCloseInfo) => {\n console.log(\"WebTransport closed w/ success\", e)\n this.events.onclose({ code: e.closeCode, reason: e.reason });\n\n }).catch((e: WebTransportCloseInfo) => {\n console.log(\"WebTransport closed w/ error\", e)\n this.events.onerror(e);\n this.events.onclose({ code: e.closeCode, reason: e.reason });\n }).finally(() => {\n this._close();\n });\n }\n\n public send(data: Buffer | Uint8Array): void {\n const prefixLength = encode.number(this.lengthPrefixBuffer as any, data.length, { offset: 0 });\n const dataWithPrefixedLength = new Uint8Array(prefixLength + data.length);\n dataWithPrefixedLength.set(this.lengthPrefixBuffer.subarray(0, prefixLength), 0);\n dataWithPrefixedLength.set(data, prefixLength);\n this.writer.write(dataWithPrefixedLength);\n }\n\n public sendUnreliable(data: Buffer | Uint8Array): void {\n const prefixLength = encode.number(this.lengthPrefixBuffer as any, data.length, { offset: 0 });\n const dataWithPrefixedLength = new Uint8Array(prefixLength + data.length);\n dataWithPrefixedLength.set(this.lengthPrefixBuffer.subarray(0, prefixLength), 0);\n dataWithPrefixedLength.set(data, prefixLength);\n this.unreliableWriter.write(dataWithPrefixedLength);\n }\n\n public close(code?: number, reason?: string) {\n try {\n this.wt.close({ closeCode: code, reason: reason });\n } catch (e) {\n console.error(e);\n }\n }\n\n protected async readIncomingData() {\n let result: ReadableStreamReadResult<Uint8Array>;\n\n while (this.isOpen) {\n try {\n result = await this.reader.read();\n\n //\n // a single read may contain multiple messages\n // each message is prefixed with its length\n //\n\n const messages = result.value;\n const it: Iterator = { offset: 0 };\n do {\n //\n // QUESTION: should we buffer the message in case it's not fully read?\n //\n\n const length = decode.number(messages as any, it);\n this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });\n it.offset += length;\n } while (it.offset < messages.length);\n\n } catch (e: any) {\n if (e.message.indexOf(\"session is closed\") === -1) {\n console.error(\"H3Transport: failed to read incoming data\", e);\n }\n break;\n }\n\n if (result.done) {\n break;\n }\n }\n }\n\n protected async readIncomingUnreliableData() {\n let result: ReadableStreamReadResult<Uint8Array>;\n\n while (this.isOpen) {\n try {\n result = await this.unreliableReader.read();\n\n //\n // a single read may contain multiple messages\n // each message is prefixed with its length\n //\n\n const messages = result.value;\n const it: Iterator = { offset: 0 };\n do {\n //\n // QUESTION: should we buffer the message in case it's not fully read?\n //\n\n const length = decode.number(messages as any, it);\n this.events.onmessage({ data: messages.subarray(it.offset, it.offset + length) });\n it.offset += length;\n } while (it.offset < messages.length);\n\n } catch (e: any) {\n if (e.message.indexOf(\"session is closed\") === -1) {\n console.error(\"H3Transport: failed to read incoming data\", e);\n }\n break;\n }\n\n if (result.done) {\n break;\n }\n }\n }\n\n protected sendSeatReservation (roomId: string, sessionId: string, reconnectionToken?: string, skipHandshake?: boolean) {\n const it: Iterator = { offset: 0 };\n const bytes: number[] = [];\n\n encode.string(bytes, roomId, it);\n encode.string(bytes, sessionId, it);\n\n if (reconnectionToken) {\n encode.string(bytes, reconnectionToken, it);\n }\n\n if (skipHandshake) {\n encode.boolean(bytes, 1, it);\n }\n\n this.writer.write(new Uint8Array(bytes).buffer);\n }\n\n protected _close() {\n this.isOpen = false;\n }\n\n}\n"],"names":[],"mappings":"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"}
|