@dcl/sdk 7.20.2-22169778016.commit-030cbfe → 7.20.2-22231111352.commit-d2f6f0a

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.
Files changed (63) hide show
  1. package/network/binary-message-bus.d.ts +3 -6
  2. package/network/binary-message-bus.js +5 -9
  3. package/network/index.d.ts +2 -8
  4. package/network/index.js +3 -16
  5. package/network/message-bus-sync.d.ts +1 -14
  6. package/network/message-bus-sync.js +103 -166
  7. package/network/state.js +5 -3
  8. package/package.json +6 -6
  9. package/src/network/binary-message-bus.ts +4 -9
  10. package/src/network/index.ts +3 -40
  11. package/src/network/message-bus-sync.ts +110 -180
  12. package/src/network/state.ts +4 -3
  13. package/atom.d.ts +0 -19
  14. package/atom.js +0 -83
  15. package/future.d.ts +0 -8
  16. package/future.js +0 -26
  17. package/network/chunking.d.ts +0 -5
  18. package/network/chunking.js +0 -38
  19. package/network/events/implementation.d.ts +0 -93
  20. package/network/events/implementation.js +0 -230
  21. package/network/events/index.d.ts +0 -42
  22. package/network/events/index.js +0 -43
  23. package/network/events/protocol.d.ts +0 -27
  24. package/network/events/protocol.js +0 -66
  25. package/network/events/registry.d.ts +0 -8
  26. package/network/events/registry.js +0 -3
  27. package/network/server/index.d.ts +0 -14
  28. package/network/server/index.js +0 -219
  29. package/network/server/utils.d.ts +0 -18
  30. package/network/server/utils.js +0 -135
  31. package/server/env-var.d.ts +0 -15
  32. package/server/env-var.js +0 -31
  33. package/server/index.d.ts +0 -2
  34. package/server/index.js +0 -3
  35. package/server/storage/constants.d.ts +0 -23
  36. package/server/storage/constants.js +0 -2
  37. package/server/storage/index.d.ts +0 -22
  38. package/server/storage/index.js +0 -29
  39. package/server/storage/player.d.ts +0 -43
  40. package/server/storage/player.js +0 -92
  41. package/server/storage/scene.d.ts +0 -38
  42. package/server/storage/scene.js +0 -90
  43. package/server/storage-url.d.ts +0 -10
  44. package/server/storage-url.js +0 -29
  45. package/server/utils.d.ts +0 -35
  46. package/server/utils.js +0 -56
  47. package/src/atom.ts +0 -98
  48. package/src/future.ts +0 -38
  49. package/src/network/chunking.ts +0 -45
  50. package/src/network/events/implementation.ts +0 -286
  51. package/src/network/events/index.ts +0 -48
  52. package/src/network/events/protocol.ts +0 -94
  53. package/src/network/events/registry.ts +0 -18
  54. package/src/network/server/index.ts +0 -301
  55. package/src/network/server/utils.ts +0 -189
  56. package/src/server/env-var.ts +0 -36
  57. package/src/server/index.ts +0 -2
  58. package/src/server/storage/constants.ts +0 -22
  59. package/src/server/storage/index.ts +0 -44
  60. package/src/server/storage/player.ts +0 -156
  61. package/src/server/storage/scene.ts +0 -149
  62. package/src/server/storage-url.ts +0 -34
  63. package/src/server/utils.ts +0 -73
@@ -1,10 +1,7 @@
1
1
  export declare enum CommsMessage {
2
- CRDT = 7,
3
- REQ_CRDT_STATE = 8,
4
- RES_CRDT_STATE = 9,
5
- CRDT_SERVER = 4,
6
- CRDT_AUTHORITATIVE = 5,
7
- CUSTOM_EVENT = 6
2
+ CRDT = 1,
3
+ REQ_CRDT_STATE = 2,
4
+ RES_CRDT_STATE = 3
8
5
  }
9
6
  export declare function BinaryMessageBus<T extends CommsMessage>(send: (message: Uint8Array, toPeerAddress?: string[]) => void): {
10
7
  on: <K extends T>(message: K, callback: (value: Uint8Array, sender: string) => void) => void;
@@ -1,12 +1,9 @@
1
1
  import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer';
2
2
  export var CommsMessage;
3
3
  (function (CommsMessage) {
4
- CommsMessage[CommsMessage["CRDT"] = 7] = "CRDT";
5
- CommsMessage[CommsMessage["REQ_CRDT_STATE"] = 8] = "REQ_CRDT_STATE";
6
- CommsMessage[CommsMessage["RES_CRDT_STATE"] = 9] = "RES_CRDT_STATE";
7
- CommsMessage[CommsMessage["CRDT_SERVER"] = 4] = "CRDT_SERVER";
8
- CommsMessage[CommsMessage["CRDT_AUTHORITATIVE"] = 5] = "CRDT_AUTHORITATIVE";
9
- CommsMessage[CommsMessage["CUSTOM_EVENT"] = 6] = "CUSTOM_EVENT";
4
+ CommsMessage[CommsMessage["CRDT"] = 1] = "CRDT";
5
+ CommsMessage[CommsMessage["REQ_CRDT_STATE"] = 2] = "REQ_CRDT_STATE";
6
+ CommsMessage[CommsMessage["RES_CRDT_STATE"] = 3] = "RES_CRDT_STATE";
10
7
  })(CommsMessage || (CommsMessage = {}));
11
8
  export function BinaryMessageBus(send) {
12
9
  const mapping = new Map();
@@ -20,9 +17,8 @@ export function BinaryMessageBus(send) {
20
17
  __processMessages: (messages) => {
21
18
  for (const message of messages) {
22
19
  const commsMsg = decodeCommsMessage(message);
23
- if (!commsMsg) {
20
+ if (!commsMsg)
24
21
  continue;
25
- }
26
22
  const { sender, messageType, data } = commsMsg;
27
23
  const fn = mapping.get(messageType);
28
24
  if (fn)
@@ -69,4 +65,4 @@ export function encodeString(s) {
69
65
  buffer.writeUtf8String(s);
70
66
  return buffer.readBuffer();
71
67
  }
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluYXJ5LW1lc3NhZ2UtYnVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldHdvcmsvYmluYXJ5LW1lc3NhZ2UtYnVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFBO0FBRTVFLE1BQU0sQ0FBTixJQUFZLFlBT1g7QUFQRCxXQUFZLFlBQVk7SUFDdEIsK0NBQVEsQ0FBQTtJQUNSLG1FQUFrQixDQUFBO0lBQ2xCLG1FQUFrQixDQUFBO0lBQ2xCLDZEQUFlLENBQUE7SUFDZiwyRUFBc0IsQ0FBQTtJQUN0QiwrREFBZ0IsQ0FBQTtBQUNsQixDQUFDLEVBUFcsWUFBWSxLQUFaLFlBQVksUUFPdkI7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLElBQTZEO0lBRTdELE1BQU0sT0FBTyxHQUF3RCxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBQzlFLE9BQU87UUFDTCxFQUFFLEVBQUUsQ0FBYyxPQUFVLEVBQUUsUUFBcUQsRUFBRSxFQUFFO1lBQ3JGLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ2hDLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBYyxPQUFVLEVBQUUsS0FBaUIsRUFBRSxhQUF3QixFQUFFLEVBQUU7WUFDN0UsSUFBSSxDQUFDLGlCQUFpQixDQUFJLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQTtRQUMzRCxDQUFDO1FBQ0QsaUJBQWlCLEVBQUUsQ0FBQyxRQUFzQixFQUFFLEVBQUU7WUFDNUMsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUU7Z0JBQzlCLE1BQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFJLE9BQU8sQ0FBQyxDQUFBO2dCQUMvQyxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNiLFNBQVE7aUJBQ1Q7Z0JBQ0QsTUFBTSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFBO2dCQUM5QyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO2dCQUNuQyxJQUFJLEVBQUU7b0JBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQTthQUN6QjtRQUNILENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBeUIsV0FBYyxFQUFFLE9BQW1CO0lBQzNGLE1BQU0sR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7SUFDdEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDbkIsT0FBTyxHQUFHLENBQUE7QUFDWixDQUFDO0FBRUQsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxJQUFnQjtJQUVoQixJQUFJO1FBQ0YsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFBO1FBQ2QsTUFBTSxDQUFDLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ25DLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDMUMsTUFBTSxJQUFJLENBQUMsQ0FBQTtRQUNYLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUMvRCxNQUFNLElBQUksWUFBWSxDQUFBO1FBQ3RCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFNLENBQUE7UUFDOUMsTUFBTSxJQUFJLENBQUMsQ0FBQTtRQUNYLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFbEMsT0FBTztZQUNMLE1BQU07WUFDTixXQUFXO1lBQ1gsSUFBSSxFQUFFLE9BQU87U0FDZCxDQUFBO0tBQ0Y7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUE7S0FDMUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUFnQjtJQUMzQyxNQUFNLE1BQU0sR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUE7SUFDeEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDOUIsT0FBTyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUE7QUFDaEMsQ0FBQztBQUVELE1BQU0sVUFBVSxZQUFZLENBQUMsQ0FBUztJQUNwQyxNQUFNLE1BQU0sR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUE7SUFDeEMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN6QixPQUFPLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtBQUM1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVhZFdyaXRlQnl0ZUJ1ZmZlciB9IGZyb20gJ0BkY2wvZWNzL2Rpc3Qvc2VyaWFsaXphdGlvbi9CeXRlQnVmZmVyJ1xuXG5leHBvcnQgZW51bSBDb21tc01lc3NhZ2Uge1xuICBDUkRUID0gNyxcbiAgUkVRX0NSRFRfU1RBVEUgPSA4LFxuICBSRVNfQ1JEVF9TVEFURSA9IDksXG4gIENSRFRfU0VSVkVSID0gNCxcbiAgQ1JEVF9BVVRIT1JJVEFUSVZFID0gNSxcbiAgQ1VTVE9NX0VWRU5UID0gNlxufVxuXG5leHBvcnQgZnVuY3Rpb24gQmluYXJ5TWVzc2FnZUJ1czxUIGV4dGVuZHMgQ29tbXNNZXNzYWdlPihcbiAgc2VuZDogKG1lc3NhZ2U6IFVpbnQ4QXJyYXksIHRvUGVlckFkZHJlc3M/OiBzdHJpbmdbXSkgPT4gdm9pZFxuKSB7XG4gIGNvbnN0IG1hcHBpbmc6IE1hcDxULCAodmFsdWU6IFVpbnQ4QXJyYXksIHNlbmRlcjogc3RyaW5nKSA9PiB2b2lkPiA9IG5ldyBNYXAoKVxuICByZXR1cm4ge1xuICAgIG9uOiA8SyBleHRlbmRzIFQ+KG1lc3NhZ2U6IEssIGNhbGxiYWNrOiAodmFsdWU6IFVpbnQ4QXJyYXksIHNlbmRlcjogc3RyaW5nKSA9PiB2b2lkKSA9PiB7XG4gICAgICBtYXBwaW5nLnNldChtZXNzYWdlLCBjYWxsYmFjaylcbiAgICB9LFxuICAgIGVtaXQ6IDxLIGV4dGVuZHMgVD4obWVzc2FnZTogSywgdmFsdWU6IFVpbnQ4QXJyYXksIHRvUGVlckFkZHJlc3M/OiBzdHJpbmdbXSkgPT4ge1xuICAgICAgc2VuZChjcmFmdENvbW1zTWVzc2FnZTxUPihtZXNzYWdlLCB2YWx1ZSksIHRvUGVlckFkZHJlc3MpXG4gICAgfSxcbiAgICBfX3Byb2Nlc3NNZXNzYWdlczogKG1lc3NhZ2VzOiBVaW50OEFycmF5W10pID0+IHtcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBtZXNzYWdlcykge1xuICAgICAgICBjb25zdCBjb21tc01zZyA9IGRlY29kZUNvbW1zTWVzc2FnZTxUPihtZXNzYWdlKVxuICAgICAgICBpZiAoIWNvbW1zTXNnKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHNlbmRlciwgbWVzc2FnZVR5cGUsIGRhdGEgfSA9IGNvbW1zTXNnXG4gICAgICAgIGNvbnN0IGZuID0gbWFwcGluZy5nZXQobWVzc2FnZVR5cGUpXG4gICAgICAgIGlmIChmbikgZm4oZGF0YSwgc2VuZGVyKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JhZnRDb21tc01lc3NhZ2U8VCBleHRlbmRzIENvbW1zTWVzc2FnZT4obWVzc2FnZVR5cGU6IFQsIHBheWxvYWQ6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5IHtcbiAgY29uc3QgbXNnID0gbmV3IFVpbnQ4QXJyYXkocGF5bG9hZC5ieXRlTGVuZ3RoICsgMSlcbiAgbXNnLnNldChbbWVzc2FnZVR5cGVdKVxuICBtc2cuc2V0KHBheWxvYWQsIDEpXG4gIHJldHVybiBtc2dcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUNvbW1zTWVzc2FnZTxUIGV4dGVuZHMgQ29tbXNNZXNzYWdlPihcbiAgZGF0YTogVWludDhBcnJheVxuKTogeyBzZW5kZXI6IHN0cmluZzsgbWVzc2FnZVR5cGU6IFQ7IGRhdGE6IFVpbnQ4QXJyYXkgfSB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgbGV0IG9mZnNldCA9IDBcbiAgICBjb25zdCByID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSlcbiAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KHIuYnVmZmVyKVxuICAgIGNvbnN0IHNlbmRlckxlbmd0aCA9IHZpZXcuZ2V0VWludDgob2Zmc2V0KVxuICAgIG9mZnNldCArPSAxXG4gICAgY29uc3Qgc2VuZGVyID0gZGVjb2RlU3RyaW5nKGRhdGEuc3ViYXJyYXkoMSwgc2VuZGVyTGVuZ3RoICsgMSkpXG4gICAgb2Zmc2V0ICs9IHNlbmRlckxlbmd0aFxuICAgIGNvbnN0IG1lc3NhZ2VUeXBlID0gdmlldy5nZXRVaW50OChvZmZzZXQpIGFzIFRcbiAgICBvZmZzZXQgKz0gMVxuICAgIGNvbnN0IG1lc3NhZ2UgPSByLnN1YmFycmF5KG9mZnNldClcblxuICAgIHJldHVybiB7XG4gICAgICBzZW5kZXIsXG4gICAgICBtZXNzYWdlVHlwZSxcbiAgICAgIGRhdGE6IG1lc3NhZ2VcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIENvbW1zIG1lc3NhZ2UnLCBlKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVTdHJpbmcoZGF0YTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIGNvbnN0IGJ1ZmZlciA9IG5ldyBSZWFkV3JpdGVCeXRlQnVmZmVyKClcbiAgYnVmZmVyLndyaXRlQnVmZmVyKGRhdGEsIHRydWUpXG4gIHJldHVybiBidWZmZXIucmVhZFV0ZjhTdHJpbmcoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU3RyaW5nKHM6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBidWZmZXIgPSBuZXcgUmVhZFdyaXRlQnl0ZUJ1ZmZlcigpXG4gIGJ1ZmZlci53cml0ZVV0ZjhTdHJpbmcocylcbiAgcmV0dXJuIGJ1ZmZlci5yZWFkQnVmZmVyKClcbn1cbiJdfQ==
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluYXJ5LW1lc3NhZ2UtYnVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldHdvcmsvYmluYXJ5LW1lc3NhZ2UtYnVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFBO0FBRTVFLE1BQU0sQ0FBTixJQUFZLFlBSVg7QUFKRCxXQUFZLFlBQVk7SUFDdEIsK0NBQVEsQ0FBQTtJQUNSLG1FQUFrQixDQUFBO0lBQ2xCLG1FQUFrQixDQUFBO0FBQ3BCLENBQUMsRUFKVyxZQUFZLEtBQVosWUFBWSxRQUl2QjtBQUVELE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsSUFBNkQ7SUFFN0QsTUFBTSxPQUFPLEdBQXdELElBQUksR0FBRyxFQUFFLENBQUE7SUFDOUUsT0FBTztRQUNMLEVBQUUsRUFBRSxDQUFjLE9BQVUsRUFBRSxRQUFxRCxFQUFFLEVBQUU7WUFDckYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDaEMsQ0FBQztRQUNELElBQUksRUFBRSxDQUFjLE9BQVUsRUFBRSxLQUFpQixFQUFFLGFBQXdCLEVBQUUsRUFBRTtZQUM3RSxJQUFJLENBQUMsaUJBQWlCLENBQUksT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFBO1FBQzNELENBQUM7UUFDRCxpQkFBaUIsRUFBRSxDQUFDLFFBQXNCLEVBQUUsRUFBRTtZQUM1QyxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRTtnQkFDOUIsTUFBTSxRQUFRLEdBQUcsa0JBQWtCLENBQUksT0FBTyxDQUFDLENBQUE7Z0JBQy9DLElBQUksQ0FBQyxRQUFRO29CQUFFLFNBQVE7Z0JBQ3ZCLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQTtnQkFDOUMsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQTtnQkFDbkMsSUFBSSxFQUFFO29CQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7YUFDekI7UUFDSCxDQUFDO0tBQ0YsQ0FBQTtBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsaUJBQWlCLENBQXlCLFdBQWMsRUFBRSxPQUFtQjtJQUMzRixNQUFNLEdBQUcsR0FBRyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQ2xELEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFBO0lBQ3RCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ25CLE9BQU8sR0FBRyxDQUFBO0FBQ1osQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsSUFBZ0I7SUFFaEIsSUFBSTtRQUNGLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQTtRQUNkLE1BQU0sQ0FBQyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLE1BQU0sSUFBSSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNuQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQzFDLE1BQU0sSUFBSSxDQUFDLENBQUE7UUFDWCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDL0QsTUFBTSxJQUFJLFlBQVksQ0FBQTtRQUN0QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBTSxDQUFBO1FBQzlDLE1BQU0sSUFBSSxDQUFDLENBQUE7UUFDWCxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBRWxDLE9BQU87WUFDTCxNQUFNO1lBQ04sV0FBVztZQUNYLElBQUksRUFBRSxPQUFPO1NBQ2QsQ0FBQTtLQUNGO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLENBQUMsQ0FBQyxDQUFBO0tBQzFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBZ0I7SUFDM0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBbUIsRUFBRSxDQUFBO0lBQ3hDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO0lBQzlCLE9BQU8sTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFBO0FBQ2hDLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLENBQVM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBbUIsRUFBRSxDQUFBO0lBQ3hDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDekIsT0FBTyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUE7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlYWRXcml0ZUJ5dGVCdWZmZXIgfSBmcm9tICdAZGNsL2Vjcy9kaXN0L3NlcmlhbGl6YXRpb24vQnl0ZUJ1ZmZlcidcblxuZXhwb3J0IGVudW0gQ29tbXNNZXNzYWdlIHtcbiAgQ1JEVCA9IDEsXG4gIFJFUV9DUkRUX1NUQVRFID0gMixcbiAgUkVTX0NSRFRfU1RBVEUgPSAzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBCaW5hcnlNZXNzYWdlQnVzPFQgZXh0ZW5kcyBDb21tc01lc3NhZ2U+KFxuICBzZW5kOiAobWVzc2FnZTogVWludDhBcnJheSwgdG9QZWVyQWRkcmVzcz86IHN0cmluZ1tdKSA9PiB2b2lkXG4pIHtcbiAgY29uc3QgbWFwcGluZzogTWFwPFQsICh2YWx1ZTogVWludDhBcnJheSwgc2VuZGVyOiBzdHJpbmcpID0+IHZvaWQ+ID0gbmV3IE1hcCgpXG4gIHJldHVybiB7XG4gICAgb246IDxLIGV4dGVuZHMgVD4obWVzc2FnZTogSywgY2FsbGJhY2s6ICh2YWx1ZTogVWludDhBcnJheSwgc2VuZGVyOiBzdHJpbmcpID0+IHZvaWQpID0+IHtcbiAgICAgIG1hcHBpbmcuc2V0KG1lc3NhZ2UsIGNhbGxiYWNrKVxuICAgIH0sXG4gICAgZW1pdDogPEsgZXh0ZW5kcyBUPihtZXNzYWdlOiBLLCB2YWx1ZTogVWludDhBcnJheSwgdG9QZWVyQWRkcmVzcz86IHN0cmluZ1tdKSA9PiB7XG4gICAgICBzZW5kKGNyYWZ0Q29tbXNNZXNzYWdlPFQ+KG1lc3NhZ2UsIHZhbHVlKSwgdG9QZWVyQWRkcmVzcylcbiAgICB9LFxuICAgIF9fcHJvY2Vzc01lc3NhZ2VzOiAobWVzc2FnZXM6IFVpbnQ4QXJyYXlbXSkgPT4ge1xuICAgICAgZm9yIChjb25zdCBtZXNzYWdlIG9mIG1lc3NhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGNvbW1zTXNnID0gZGVjb2RlQ29tbXNNZXNzYWdlPFQ+KG1lc3NhZ2UpXG4gICAgICAgIGlmICghY29tbXNNc2cpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IHsgc2VuZGVyLCBtZXNzYWdlVHlwZSwgZGF0YSB9ID0gY29tbXNNc2dcbiAgICAgICAgY29uc3QgZm4gPSBtYXBwaW5nLmdldChtZXNzYWdlVHlwZSlcbiAgICAgICAgaWYgKGZuKSBmbihkYXRhLCBzZW5kZXIpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmFmdENvbW1zTWVzc2FnZTxUIGV4dGVuZHMgQ29tbXNNZXNzYWdlPihtZXNzYWdlVHlwZTogVCwgcGF5bG9hZDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBtc2cgPSBuZXcgVWludDhBcnJheShwYXlsb2FkLmJ5dGVMZW5ndGggKyAxKVxuICBtc2cuc2V0KFttZXNzYWdlVHlwZV0pXG4gIG1zZy5zZXQocGF5bG9hZCwgMSlcbiAgcmV0dXJuIG1zZ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlQ29tbXNNZXNzYWdlPFQgZXh0ZW5kcyBDb21tc01lc3NhZ2U+KFxuICBkYXRhOiBVaW50OEFycmF5XG4pOiB7IHNlbmRlcjogc3RyaW5nOyBtZXNzYWdlVHlwZTogVDsgZGF0YTogVWludDhBcnJheSB9IHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBsZXQgb2Zmc2V0ID0gMFxuICAgIGNvbnN0IHIgPSBuZXcgVWludDhBcnJheShkYXRhKVxuICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoci5idWZmZXIpXG4gICAgY29uc3Qgc2VuZGVyTGVuZ3RoID0gdmlldy5nZXRVaW50OChvZmZzZXQpXG4gICAgb2Zmc2V0ICs9IDFcbiAgICBjb25zdCBzZW5kZXIgPSBkZWNvZGVTdHJpbmcoZGF0YS5zdWJhcnJheSgxLCBzZW5kZXJMZW5ndGggKyAxKSlcbiAgICBvZmZzZXQgKz0gc2VuZGVyTGVuZ3RoXG4gICAgY29uc3QgbWVzc2FnZVR5cGUgPSB2aWV3LmdldFVpbnQ4KG9mZnNldCkgYXMgVFxuICAgIG9mZnNldCArPSAxXG4gICAgY29uc3QgbWVzc2FnZSA9IHIuc3ViYXJyYXkob2Zmc2V0KVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNlbmRlcixcbiAgICAgIG1lc3NhZ2VUeXBlLFxuICAgICAgZGF0YTogbWVzc2FnZVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgQ29tbXMgbWVzc2FnZScsIGUpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVN0cmluZyhkYXRhOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgY29uc3QgYnVmZmVyID0gbmV3IFJlYWRXcml0ZUJ5dGVCdWZmZXIoKVxuICBidWZmZXIud3JpdGVCdWZmZXIoZGF0YSwgdHJ1ZSlcbiAgcmV0dXJuIGJ1ZmZlci5yZWFkVXRmOFN0cmluZygpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTdHJpbmcoczogc3RyaW5nKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGJ1ZmZlciA9IG5ldyBSZWFkV3JpdGVCeXRlQnVmZmVyKClcbiAgYnVmZmVyLndyaXRlVXRmOFN0cmluZyhzKVxuICByZXR1cm4gYnVmZmVyLnJlYWRCdWZmZXIoKVxufVxuIl19
@@ -1,8 +1,2 @@
1
- export declare function isServer(): boolean;
2
- declare const getChildren: (parent: import("@dcl/ecs").Entity) => Iterable<import("@dcl/ecs").Entity>, syncEntity: (entityId: import("@dcl/ecs").Entity, componentIds: number[], entityEnumId?: number | undefined) => void, parentEntity: (entity: import("@dcl/ecs").Entity, parent: import("@dcl/ecs").Entity) => void, getParent: (child: import("@dcl/ecs").Entity) => import("@dcl/ecs").Entity | undefined, myProfile: import("./message-bus-sync").IProfile, removeParent: (entity: import("@dcl/ecs").Entity) => void, getFirstChild: (entity: import("@dcl/ecs").Entity) => import("@dcl/ecs").Entity, isStateSyncronized: () => boolean, binaryMessageBus: {
3
- on: <K extends import("./binary-message-bus").CommsMessage>(message: K, callback: (value: Uint8Array, sender: string) => void) => void;
4
- emit: <K_1 extends import("./binary-message-bus").CommsMessage>(message: K_1, value: Uint8Array, toPeerAddress?: string[] | undefined) => void;
5
- __processMessages: (messages: Uint8Array[]) => void;
6
- }, eventBus: import("./events/implementation").Room<import("./events").EventSchemaRegistry>;
7
- export { registerMessages, getRoom } from './events';
8
- export { getFirstChild, getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, isStateSyncronized, binaryMessageBus, eventBus };
1
+ declare const getChildren: (parent: import("@dcl/ecs").Entity) => Iterable<import("@dcl/ecs").Entity>, syncEntity: (entityId: import("@dcl/ecs").Entity, componentIds: number[], entityEnumId?: number | undefined) => void, parentEntity: (entity: import("@dcl/ecs").Entity, parent: import("@dcl/ecs").Entity) => void, getParent: (child: import("@dcl/ecs").Entity) => import("@dcl/ecs").Entity | undefined, myProfile: import("./message-bus-sync").IProfile, removeParent: (entity: import("@dcl/ecs").Entity) => void, getFirstChild: (entity: import("@dcl/ecs").Entity) => import("@dcl/ecs").Entity, isStateSyncronized: () => boolean;
2
+ export { getFirstChild, getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, isStateSyncronized };
package/network/index.js CHANGED
@@ -2,20 +2,7 @@ import { sendBinary } from '~system/CommunicationsController';
2
2
  import { engine } from '@dcl/ecs';
3
3
  import { addSyncTransport } from './message-bus-sync';
4
4
  import { getUserData } from '~system/UserIdentity';
5
- import { isServer as isServerApi } from '~system/EngineApi';
6
- import { Atom } from '../atom';
7
- // Create isServer atom for consistent state
8
- const isServerAtom = Atom(false);
9
- void isServerApi({}).then((response) => {
10
- isServerAtom.swap(!!response.isServer);
11
- });
12
- // Helper function to check if running on server
13
- export function isServer() {
14
- return isServerAtom.getOrNull() ?? false;
15
- }
16
5
  // initialize sync transport for sdk engine
17
- const { getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, getFirstChild, isStateSyncronized, binaryMessageBus, eventBus } = addSyncTransport(engine, sendBinary, getUserData, isServerApi, 'network');
18
- // Re-export the room messaging system
19
- export { registerMessages, getRoom } from './events';
20
- export { getFirstChild, getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, isStateSyncronized, binaryMessageBus, eventBus };
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0NBQWtDLENBQUE7QUFDN0QsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDbEQsT0FBTyxFQUFFLFFBQVEsSUFBSSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUMzRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBRTlCLDRDQUE0QztBQUM1QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQVUsS0FBSyxDQUFDLENBQUE7QUFDekMsS0FBSyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7SUFDckMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ3hDLENBQUMsQ0FBQyxDQUFBO0FBRUYsZ0RBQWdEO0FBQ2hELE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE9BQU8sWUFBWSxDQUFDLFNBQVMsRUFBRSxJQUFJLEtBQUssQ0FBQTtBQUMxQyxDQUFDO0FBRUQsMkNBQTJDO0FBQzNDLE1BQU0sRUFDSixXQUFXLEVBQ1gsVUFBVSxFQUNWLFlBQVksRUFDWixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixhQUFhLEVBQ2Isa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNoQixRQUFRLEVBQ1QsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFFN0Usc0NBQXNDO0FBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFcEQsT0FBTyxFQUNMLGFBQWEsRUFDYixXQUFXLEVBQ1gsVUFBVSxFQUNWLFlBQVksRUFDWixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixrQkFBa0IsRUFDbEIsZ0JBQWdCLEVBQ2hCLFFBQVEsRUFDVCxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2VuZEJpbmFyeSB9IGZyb20gJ35zeXN0ZW0vQ29tbXVuaWNhdGlvbnNDb250cm9sbGVyJ1xuaW1wb3J0IHsgZW5naW5lIH0gZnJvbSAnQGRjbC9lY3MnXG5pbXBvcnQgeyBhZGRTeW5jVHJhbnNwb3J0IH0gZnJvbSAnLi9tZXNzYWdlLWJ1cy1zeW5jJ1xuaW1wb3J0IHsgZ2V0VXNlckRhdGEgfSBmcm9tICd+c3lzdGVtL1VzZXJJZGVudGl0eSdcbmltcG9ydCB7IGlzU2VydmVyIGFzIGlzU2VydmVyQXBpIH0gZnJvbSAnfnN5c3RlbS9FbmdpbmVBcGknXG5pbXBvcnQgeyBBdG9tIH0gZnJvbSAnLi4vYXRvbSdcblxuLy8gQ3JlYXRlIGlzU2VydmVyIGF0b20gZm9yIGNvbnNpc3RlbnQgc3RhdGVcbmNvbnN0IGlzU2VydmVyQXRvbSA9IEF0b208Ym9vbGVhbj4oZmFsc2UpXG52b2lkIGlzU2VydmVyQXBpKHt9KS50aGVuKChyZXNwb25zZSkgPT4ge1xuICBpc1NlcnZlckF0b20uc3dhcCghIXJlc3BvbnNlLmlzU2VydmVyKVxufSlcblxuLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHJ1bm5pbmcgb24gc2VydmVyXG5leHBvcnQgZnVuY3Rpb24gaXNTZXJ2ZXIoKTogYm9vbGVhbiB7XG4gIHJldHVybiBpc1NlcnZlckF0b20uZ2V0T3JOdWxsKCkgPz8gZmFsc2Vcbn1cblxuLy8gaW5pdGlhbGl6ZSBzeW5jIHRyYW5zcG9ydCBmb3Igc2RrIGVuZ2luZVxuY29uc3Qge1xuICBnZXRDaGlsZHJlbixcbiAgc3luY0VudGl0eSxcbiAgcGFyZW50RW50aXR5LFxuICBnZXRQYXJlbnQsXG4gIG15UHJvZmlsZSxcbiAgcmVtb3ZlUGFyZW50LFxuICBnZXRGaXJzdENoaWxkLFxuICBpc1N0YXRlU3luY3Jvbml6ZWQsXG4gIGJpbmFyeU1lc3NhZ2VCdXMsXG4gIGV2ZW50QnVzXG59ID0gYWRkU3luY1RyYW5zcG9ydChlbmdpbmUsIHNlbmRCaW5hcnksIGdldFVzZXJEYXRhLCBpc1NlcnZlckFwaSwgJ25ldHdvcmsnKVxuXG4vLyBSZS1leHBvcnQgdGhlIHJvb20gbWVzc2FnaW5nIHN5c3RlbVxuZXhwb3J0IHsgcmVnaXN0ZXJNZXNzYWdlcywgZ2V0Um9vbSB9IGZyb20gJy4vZXZlbnRzJ1xuXG5leHBvcnQge1xuICBnZXRGaXJzdENoaWxkLFxuICBnZXRDaGlsZHJlbixcbiAgc3luY0VudGl0eSxcbiAgcGFyZW50RW50aXR5LFxuICBnZXRQYXJlbnQsXG4gIG15UHJvZmlsZSxcbiAgcmVtb3ZlUGFyZW50LFxuICBpc1N0YXRlU3luY3Jvbml6ZWQsXG4gIGJpbmFyeU1lc3NhZ2VCdXMsXG4gIGV2ZW50QnVzXG59XG4iXX0=
6
+ const { getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, getFirstChild, isStateSyncronized } = addSyncTransport(engine, sendBinary, getUserData);
7
+ export { getFirstChild, getChildren, syncEntity, parentEntity, getParent, myProfile, removeParent, isStateSyncronized };
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0NBQWtDLENBQUE7QUFDN0QsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFFbEQsMkNBQTJDO0FBQzNDLE1BQU0sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsR0FDcEgsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQTtBQUVuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzZW5kQmluYXJ5IH0gZnJvbSAnfnN5c3RlbS9Db21tdW5pY2F0aW9uc0NvbnRyb2xsZXInXG5pbXBvcnQgeyBlbmdpbmUgfSBmcm9tICdAZGNsL2VjcydcbmltcG9ydCB7IGFkZFN5bmNUcmFuc3BvcnQgfSBmcm9tICcuL21lc3NhZ2UtYnVzLXN5bmMnXG5pbXBvcnQgeyBnZXRVc2VyRGF0YSB9IGZyb20gJ35zeXN0ZW0vVXNlcklkZW50aXR5J1xuXG4vLyBpbml0aWFsaXplIHN5bmMgdHJhbnNwb3J0IGZvciBzZGsgZW5naW5lXG5jb25zdCB7IGdldENoaWxkcmVuLCBzeW5jRW50aXR5LCBwYXJlbnRFbnRpdHksIGdldFBhcmVudCwgbXlQcm9maWxlLCByZW1vdmVQYXJlbnQsIGdldEZpcnN0Q2hpbGQsIGlzU3RhdGVTeW5jcm9uaXplZCB9ID1cbiAgYWRkU3luY1RyYW5zcG9ydChlbmdpbmUsIHNlbmRCaW5hcnksIGdldFVzZXJEYXRhKVxuXG5leHBvcnQgeyBnZXRGaXJzdENoaWxkLCBnZXRDaGlsZHJlbiwgc3luY0VudGl0eSwgcGFyZW50RW50aXR5LCBnZXRQYXJlbnQsIG15UHJvZmlsZSwgcmVtb3ZlUGFyZW50LCBpc1N0YXRlU3luY3Jvbml6ZWQgfVxuIl19
@@ -1,27 +1,14 @@
1
1
  /// <reference types="@dcl/js-runtime" />
2
2
  import { IEngine } from '@dcl/ecs';
3
3
  import { type SendBinaryRequest, type SendBinaryResponse } from '~system/CommunicationsController';
4
- import { CommsMessage } from './binary-message-bus';
5
4
  import { GetUserDataRequest, GetUserDataResponse } from '~system/UserIdentity';
6
- import { IsServerRequest, IsServerResponse } from '~system/EngineApi';
7
- import { Atom } from '../atom';
8
- import { Room } from './events/implementation';
9
5
  export type IProfile = {
10
6
  networkId: number;
11
7
  userId: string;
12
8
  };
13
- export declare const AUTH_SERVER_PEER_ID = "authoritative-server";
14
- export declare const DEBUG_NETWORK_MESSAGES: () => any;
15
- export declare function addSyncTransport(engine: IEngine, sendBinary: (msg: SendBinaryRequest) => Promise<SendBinaryResponse>, getUserData: (value: GetUserDataRequest) => Promise<GetUserDataResponse>, isServerFn: (request: IsServerRequest) => Promise<IsServerResponse>, name: string): {
9
+ export declare function addSyncTransport(engine: IEngine, sendBinary: (msg: SendBinaryRequest) => Promise<SendBinaryResponse>, getUserData: (value: GetUserDataRequest) => Promise<GetUserDataResponse>): {
16
10
  myProfile: IProfile;
17
11
  isStateSyncronized: () => boolean;
18
- binaryMessageBus: {
19
- on: <K extends CommsMessage>(message: K, callback: (value: Uint8Array, sender: string) => void) => void;
20
- emit: <K_1 extends CommsMessage>(message: K_1, value: Uint8Array, toPeerAddress?: string[] | undefined) => void;
21
- __processMessages: (messages: Uint8Array[]) => void;
22
- };
23
- eventBus: Room<import("./events").EventSchemaRegistry>;
24
- isRoomReadyAtom: Atom<boolean>;
25
12
  syncEntity: (entityId: import("@dcl/ecs").Entity, componentIds: number[], entityEnumId?: number | undefined) => void;
26
13
  getChildren: (parent: import("@dcl/ecs").Entity) => Iterable<import("@dcl/ecs").Entity>;
27
14
  getParent: (child: import("@dcl/ecs").Entity) => import("@dcl/ecs").Entity | undefined;
@@ -1,38 +1,17 @@
1
- import { RealmInfo } from '@dcl/ecs';
1
+ import { RealmInfo, PlayerIdentityData } from '@dcl/ecs';
2
2
  import { syncFilter } from './filter';
3
3
  import { engineToCrdt } from './state';
4
- import { BinaryMessageBus, CommsMessage } from './binary-message-bus';
4
+ import { BinaryMessageBus, CommsMessage, decodeString, encodeString } from './binary-message-bus';
5
5
  import { fetchProfile } from './utils';
6
6
  import { entityUtils } from './entities';
7
- import { createServerValidator } from './server';
8
7
  import { definePlayerHelper } from '../players';
9
8
  import { serializeCrdtMessages } from '../internal/transports/logger';
10
- import { Atom } from '../atom';
11
- import { setGlobalRoom, Room } from './events/implementation';
12
9
  // user that we asked for the inital crdt state
13
- export const AUTH_SERVER_PEER_ID = 'authoritative-server';
14
- export const DEBUG_NETWORK_MESSAGES = () => globalThis.DEBUG_NETWORK_MESSAGES ?? false;
15
- // Test environment detection without 'as any'
16
- const isTestEnvironment = () => {
17
- try {
18
- if (typeof globalThis === 'undefined')
19
- return false;
20
- const globalWithProcess = globalThis;
21
- return globalWithProcess.process?.env?.NODE_ENV === 'test';
22
- }
23
- catch {
24
- return false;
25
- }
26
- };
27
- export function addSyncTransport(engine, sendBinary, getUserData, isServerFn, name) {
10
+ export function addSyncTransport(engine, sendBinary, getUserData) {
11
+ const DEBUG_NETWORK_MESSAGES = () => globalThis.DEBUG_NETWORK_MESSAGES ?? false;
28
12
  // Profile Info
29
13
  const myProfile = {};
30
14
  fetchProfile(myProfile, getUserData);
31
- const isServerAtom = Atom();
32
- const isRoomReadyAtom = Atom(false);
33
- void isServerFn({}).then(($) => {
34
- return isServerAtom.swap(!!$.isServer);
35
- });
36
15
  // Entity utils
37
16
  const entityDefinitions = entityUtils(engine, myProfile);
38
17
  // List of MessageBuss messsages to be sent on every frame to comms
@@ -47,176 +26,95 @@ export function addSyncTransport(engine, sendBinary, getUserData, isServerFn, na
47
26
  }
48
27
  const players = definePlayerHelper(engine);
49
28
  let stateIsSyncronized = false;
50
- /**
51
- * We need to wait till 2 ticks that is when the engine is ready to send new messages.
52
- * The first tick is for the client engine processing the CRDT messages,
53
- * and the second one are the messages created by the main() function.
54
- * So to avoid sending those messages, that all the clients have, through the network we put this validation here.
55
- */
56
- let tick = 0;
57
- const TRANSPORT_INITIALIZED_NUMBER = isTestEnvironment() ? 0 : 2;
29
+ let transportInitialzed = false;
58
30
  // Add Sync Transport
59
31
  const transport = {
60
32
  filter: syncFilter(engine),
61
33
  send: async (messages) => {
62
- if (tick <= TRANSPORT_INITIALIZED_NUMBER)
63
- tick++;
64
- for (const message of tick > TRANSPORT_INITIALIZED_NUMBER ? [messages].flat() : []) {
65
- if (message.byteLength) {
34
+ for (const message of [messages].flat()) {
35
+ if (message.byteLength && transportInitialzed) {
66
36
  DEBUG_NETWORK_MESSAGES() &&
67
37
  console.log(...Array.from(serializeCrdtMessages('[NetworkMessage sent]:', message, engine)));
68
- // Convert regular messages to network messages for broadcasting with chunking
69
- for (const chunk of serverValidator.convertRegularToNetworkMessage(message)) {
70
- binaryMessageBus.emit(CommsMessage.CRDT, chunk);
71
- }
38
+ binaryMessageBus.emit(CommsMessage.CRDT, message);
72
39
  }
73
40
  }
74
41
  const peerMessages = getMessagesToSend();
42
+ let totalSize = 0;
43
+ for (const message of peerMessages) {
44
+ for (const data of message.data) {
45
+ totalSize += data.byteLength;
46
+ }
47
+ }
48
+ if (totalSize) {
49
+ DEBUG_NETWORK_MESSAGES() && console.log('Sending network messages: ', totalSize / 1024, 'KB');
50
+ }
75
51
  const response = await sendBinary({ data: [], peerData: peerMessages });
76
52
  binaryMessageBus.__processMessages(response.data);
53
+ transportInitialzed = true;
77
54
  },
78
- type: name
55
+ type: 'network'
79
56
  };
80
- // Server validation setup
81
- const serverValidator = createServerValidator({
82
- engine,
83
- binaryMessageBus
84
- });
85
- // Initialize Event Bus with registered schemas
86
- const eventBus = new Room(engine, binaryMessageBus, isServerAtom, isRoomReadyAtom);
87
- // Set global eventBus instance
88
- setGlobalRoom(eventBus);
89
57
  engine.addTransport(transport);
90
58
  // End add sync transport
91
59
  // Receive & Process CRDT_STATE
92
- binaryMessageBus.on(CommsMessage.REQ_CRDT_STATE, async (data, sender) => {
93
- DEBUG_NETWORK_MESSAGES() && console.log('[REQ_CRDT_STATE]', sender, Date.now());
94
- for (const chunk of engineToCrdt(engine)) {
95
- DEBUG_NETWORK_MESSAGES() && console.log('[Emiting:]', sender, Date.now());
96
- binaryMessageBus.emit(CommsMessage.RES_CRDT_STATE, chunk, [sender]);
97
- }
98
- });
99
- binaryMessageBus.on(CommsMessage.RES_CRDT_STATE, async (data, sender) => {
100
- requestingState = false;
101
- elapsedTimeSinceRequest = 0;
102
- if (isServerAtom.getOrNull() || sender !== AUTH_SERVER_PEER_ID)
60
+ binaryMessageBus.on(CommsMessage.RES_CRDT_STATE, (value) => {
61
+ const { sender, data } = decodeCRDTState(value);
62
+ if (sender !== myProfile.userId)
103
63
  return;
104
64
  DEBUG_NETWORK_MESSAGES() && console.log('[Processing CRDT State]', data.byteLength / 1024, 'KB');
105
- transport.onmessage(serverValidator.processClientMessages(data, sender));
65
+ transport.onmessage(data);
106
66
  stateIsSyncronized = true;
107
- // IMPORTANT: Only mark room as ready AFTER state is synchronized
108
- // This ensures comms is truly connected and working
109
- const realmInfo = RealmInfo.getOrNull(engine.RootEntity);
110
- if (realmInfo && checkRoomReady(realmInfo)) {
111
- DEBUG_NETWORK_MESSAGES() && console.log('[isRoomReady] Marking room as ready after state sync');
112
- isRoomReadyAtom.swap(true);
67
+ });
68
+ // Answer to REQ_CRDT_STATE
69
+ binaryMessageBus.on(CommsMessage.REQ_CRDT_STATE, async (_, userId) => {
70
+ DEBUG_NETWORK_MESSAGES() && console.log(`Sending CRDT State to: ${userId}`);
71
+ for (const chunk of engineToCrdt(engine)) {
72
+ binaryMessageBus.emit(CommsMessage.RES_CRDT_STATE, encodeCRDTState(userId, chunk), [userId]);
113
73
  }
114
74
  });
115
- // received message from the network
116
- binaryMessageBus.on(CommsMessage.CRDT, (value, sender) => {
117
- const isServer = isServerAtom.getOrNull();
75
+ // Process CRDT messages here
76
+ binaryMessageBus.on(CommsMessage.CRDT, (value) => {
118
77
  DEBUG_NETWORK_MESSAGES() &&
119
- console.log(transport.type, ...Array.from(serializeCrdtMessages('[NetworkMessage received]:', value, engine)), isServer);
120
- if (isServer) {
121
- transport.onmessage(serverValidator.processServerMessages(value, sender));
122
- }
123
- else if (sender === AUTH_SERVER_PEER_ID) {
124
- // Process network messages from server and convert to regular messages
125
- transport.onmessage(serverValidator.processClientMessages(value, sender));
126
- }
78
+ console.log(Array.from(serializeCrdtMessages('[NetworkMessage received]:', value, engine)));
79
+ transport.onmessage(value);
127
80
  });
128
- // received authoritative message from server - force apply to fix invalid local state
129
- binaryMessageBus.on(CommsMessage.CRDT_AUTHORITATIVE, (value, sender) => {
130
- // Only accept authoritative messages from authoritative server
131
- if (sender !== AUTH_SERVER_PEER_ID)
81
+ async function requestState(retryCount = 1) {
82
+ let players = Array.from(engine.getEntitiesWith(PlayerIdentityData));
83
+ DEBUG_NETWORK_MESSAGES() && console.log(`Requesting state. Players connected: ${players.length - 1}`);
84
+ if (!RealmInfo.getOrNull(engine.RootEntity)?.isConnectedSceneRoom) {
85
+ DEBUG_NETWORK_MESSAGES() && console.log(`Aborting Requesting state?. Disconnected`);
132
86
  return;
133
- // DEBUG_NETWORK_MESSAGES() &&
134
- console.log('[AUTHORITATIVE] Received authoritative message from server:', value.byteLength, 'bytes');
135
- // Process authoritative messages by forcing them through normal CRDT processing
136
- // but with a timestamp that's guaranteed to be accepted
137
- const authoritativeBuffer = serverValidator.processClientMessages(value, sender, true);
138
- if (authoritativeBuffer.byteLength > 0) {
139
- // Apply authoritative message through normal transport, but the server's messages
140
- // should be processed as authoritative with special timestamp handling
141
- transport.onmessage(authoritativeBuffer);
142
- DEBUG_NETWORK_MESSAGES() && console.log('[AUTHORITATIVE] Applied server authoritative message to local state');
143
87
  }
144
- });
88
+ binaryMessageBus.emit(CommsMessage.REQ_CRDT_STATE, new Uint8Array());
89
+ // Wait ~5s for the response.
90
+ await sleep(5000);
91
+ players = Array.from(engine.getEntitiesWith(PlayerIdentityData));
92
+ if (!stateIsSyncronized) {
93
+ if (players.length > 1 && retryCount <= 2) {
94
+ DEBUG_NETWORK_MESSAGES() &&
95
+ console.log(`Requesting state again ${retryCount} (no response). Players connected: ${players.length - 1}`);
96
+ void requestState(retryCount + 1);
97
+ }
98
+ else {
99
+ DEBUG_NETWORK_MESSAGES() && console.log('No active players. State syncronized');
100
+ stateIsSyncronized = true;
101
+ }
102
+ }
103
+ }
145
104
  players.onEnterScene((player) => {
146
105
  DEBUG_NETWORK_MESSAGES() && console.log('[onEnterScene]', player.userId);
147
- if (!isServerAtom.getOrNull() && myProfile.userId === player.userId) {
148
- requestState();
149
- }
150
106
  });
151
- // Helper to check room ready conditions
152
- function checkRoomReady(realmInfo) {
153
- if (!realmInfo)
154
- return false;
155
- try {
156
- // Check if room instance exists
157
- if (!eventBus)
158
- return false;
159
- return !!(realmInfo.commsAdapter && realmInfo.isConnectedSceneRoom && realmInfo.room);
160
- }
161
- catch {
162
- return false;
163
- }
164
- }
165
107
  // Asks for the REQ_CRDT_STATE when its connected to comms
166
108
  RealmInfo.onChange(engine.RootEntity, (value) => {
167
- const isServer = isServerAtom.getOrNull();
168
109
  if (!value?.isConnectedSceneRoom) {
169
- // Only react when actually transitioning from ready to not ready
170
- if (isRoomReadyAtom.getOrNull() === true) {
171
- DEBUG_NETWORK_MESSAGES() && console.log('Disconnected from comms');
172
- isRoomReadyAtom.swap(false);
173
- if (!isServer) {
174
- stateIsSyncronized = false;
175
- }
176
- }
110
+ DEBUG_NETWORK_MESSAGES() && console.log('Disconnected from comms');
111
+ stateIsSyncronized = false;
177
112
  }
178
113
  if (value?.isConnectedSceneRoom) {
179
- requestState();
180
- // For servers, mark as ready immediately when connected
181
- // (servers don't need to sync state from anyone)
182
- if (isServer && checkRoomReady(value) && isRoomReadyAtom.getOrNull() === false) {
183
- DEBUG_NETWORK_MESSAGES() && console.log('[isRoomReady] Server marking room as ready');
184
- isRoomReadyAtom.swap(true);
185
- }
186
- // For clients, room will be marked ready after receiving CRDT state (above)
187
- }
188
- });
189
- let requestingState = false;
190
- let elapsedTimeSinceRequest = 0;
191
- const STATE_REQUEST_RETRY_INTERVAL = 2.0; // seconds
192
- /**
193
- * Why we have to request the state if we have a server that can send us the state when we joined?
194
- * The thing is that when the server detects a new JOIN_PARTICIPANT on livekit room, it sends automatically the state to that peer.
195
- * But in unity, it takes more time, so that message is not being delivered to the client.
196
- * So instead, when we are finally connected to the room, we request the state, and then the server answers with the state :)
197
- *
198
- * If no response is received within 2 seconds, the request is automatically retried.
199
- */
200
- function requestState() {
201
- if (isServerAtom.getOrNull())
202
- return;
203
- if (RealmInfo.getOrNull(engine.RootEntity)?.isConnectedSceneRoom && !requestingState) {
204
- requestingState = true;
205
- elapsedTimeSinceRequest = 0;
206
- DEBUG_NETWORK_MESSAGES() && console.log('Requesting state...');
207
- binaryMessageBus.emit(CommsMessage.REQ_CRDT_STATE, new Uint8Array());
114
+ DEBUG_NETWORK_MESSAGES() && console.log('Connected to comms');
208
115
  }
209
- }
210
- // System to retry state request if no response is received within the retry interval
211
- engine.addSystem((dt) => {
212
- if (requestingState && !stateIsSyncronized) {
213
- elapsedTimeSinceRequest += dt;
214
- if (elapsedTimeSinceRequest >= STATE_REQUEST_RETRY_INTERVAL) {
215
- DEBUG_NETWORK_MESSAGES() && console.log('State request timed out, retrying...');
216
- elapsedTimeSinceRequest = 0;
217
- requestingState = false;
218
- requestState();
219
- }
116
+ if (value?.isConnectedSceneRoom && !stateIsSyncronized) {
117
+ void requestState();
220
118
  }
221
119
  });
222
120
  players.onLeaveScene((userId) => {
@@ -225,13 +123,52 @@ export function addSyncTransport(engine, sendBinary, getUserData, isServerFn, na
225
123
  function isStateSyncronized() {
226
124
  return stateIsSyncronized;
227
125
  }
126
+ function sleep(ms) {
127
+ return new Promise((resolve) => {
128
+ let timer = 0;
129
+ function sleepSystem(dt) {
130
+ timer += dt;
131
+ if (timer * 1000 >= ms) {
132
+ engine.removeSystem(sleepSystem);
133
+ resolve();
134
+ }
135
+ }
136
+ engine.addSystem(sleepSystem);
137
+ });
138
+ }
228
139
  return {
229
140
  ...entityDefinitions,
230
141
  myProfile,
231
- isStateSyncronized,
232
- binaryMessageBus,
233
- eventBus,
234
- isRoomReadyAtom
142
+ isStateSyncronized
235
143
  };
236
144
  }
237
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZS1idXMtc3luYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXR3b3JrL21lc3NhZ2UtYnVzLXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFzQixTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFHeEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUNyRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRWhELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUMvQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQTtBQUVyRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzlCLE9BQU8sRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFHN0QsK0NBQStDO0FBQy9DLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLHNCQUFzQixDQUFBO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLEdBQUcsRUFBRSxDQUFFLFVBQWtCLENBQUMsc0JBQXNCLElBQUksS0FBSyxDQUFBO0FBRS9GLDhDQUE4QztBQUM5QyxNQUFNLGlCQUFpQixHQUFHLEdBQVksRUFBRTtJQUN0QyxJQUFJO1FBQ0YsSUFBSSxPQUFPLFVBQVUsS0FBSyxXQUFXO1lBQUUsT0FBTyxLQUFLLENBQUE7UUFDbkQsTUFBTSxpQkFBaUIsR0FBRyxVQUFzRSxDQUFBO1FBQ2hH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QTRCLEVBQUU7Z0JBQzNELHNCQUFzQixFQUFFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFBO2dCQUMvRSx1QkFBdUIsR0FBRyxDQUFDLENBQUE7Z0JBQzNCLGVBQWUsR0FBRyxLQUFLLENBQUE7Z0JBQ3ZCLFlBQVksRUFBRSxDQUFBO2FBQ2Y7U0FDRjtJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQzlCLHNCQUFzQixFQUFFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNuRSxDQUFDLENBQUMsQ0FBQTtJQUVGLFNBQVMsa0JBQWtCO1FBQ3pCLE9BQU8sa0JBQWtCLENBQUE7SUFDM0IsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLGlCQUFpQjtRQUNwQixTQUFTO1FBQ1Qsa0JBQWtCO1FBQ2xCLGdCQUFnQjtRQUNoQixRQUFRO1FBQ1IsZUFBZTtLQUNoQixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElFbmdpbmUsIFRyYW5zcG9ydCwgUmVhbG1JbmZvIH0gZnJvbSAnQGRjbC9lY3MnXG5pbXBvcnQgeyB0eXBlIFNlbmRCaW5hcnlSZXF1ZXN0LCB0eXBlIFNlbmRCaW5hcnlSZXNwb25zZSB9IGZyb20gJ35zeXN0ZW0vQ29tbXVuaWNhdGlvbnNDb250cm9sbGVyJ1xuXG5pbXBvcnQgeyBzeW5jRmlsdGVyIH0gZnJvbSAnLi9maWx0ZXInXG5pbXBvcnQgeyBlbmdpbmVUb0NyZHQgfSBmcm9tICcuL3N0YXRlJ1xuaW1wb3J0IHsgQmluYXJ5TWVzc2FnZUJ1cywgQ29tbXNNZXNzYWdlIH0gZnJvbSAnLi9iaW5hcnktbWVzc2FnZS1idXMnXG5pbXBvcnQgeyBmZXRjaFByb2ZpbGUgfSBmcm9tICcuL3V0aWxzJ1xuaW1wb3J0IHsgZW50aXR5VXRpbHMgfSBmcm9tICcuL2VudGl0aWVzJ1xuaW1wb3J0IHsgY3JlYXRlU2VydmVyVmFsaWRhdG9yIH0gZnJvbSAnLi9zZXJ2ZXInXG5pbXBvcnQgeyBHZXRVc2VyRGF0YVJlcXVlc3QsIEdldFVzZXJEYXRhUmVzcG9uc2UgfSBmcm9tICd+c3lzdGVtL1VzZXJJZGVudGl0eSdcbmltcG9ydCB7IGRlZmluZVBsYXllckhlbHBlciB9IGZyb20gJy4uL3BsYXllcnMnXG5pbXBvcnQgeyBzZXJpYWxpemVDcmR0TWVzc2FnZXMgfSBmcm9tICcuLi9pbnRlcm5hbC90cmFuc3BvcnRzL2xvZ2dlcidcbmltcG9ydCB7IElzU2VydmVyUmVxdWVzdCwgSXNTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ35zeXN0ZW0vRW5naW5lQXBpJ1xuaW1wb3J0IHsgQXRvbSB9IGZyb20gJy4uL2F0b20nXG5pbXBvcnQgeyBzZXRHbG9iYWxSb29tLCBSb29tIH0gZnJvbSAnLi9ldmVudHMvaW1wbGVtZW50YXRpb24nXG5cbmV4cG9ydCB0eXBlIElQcm9maWxlID0geyBuZXR3b3JrSWQ6IG51bWJlcjsgdXNlcklkOiBzdHJpbmcgfVxuLy8gdXNlciB0aGF0IHdlIGFza2VkIGZvciB0aGUgaW5pdGFsIGNyZHQgc3RhdGVcbmV4cG9ydCBjb25zdCBBVVRIX1NFUlZFUl9QRUVSX0lEID0gJ2F1dGhvcml0YXRpdmUtc2VydmVyJ1xuZXhwb3J0IGNvbnN0IERFQlVHX05FVFdPUktfTUVTU0FHRVMgPSAoKSA9PiAoZ2xvYmFsVGhpcyBhcyBhbnkpLkRFQlVHX05FVFdPUktfTUVTU0FHRVMgPz8gZmFsc2VcblxuLy8gVGVzdCBlbnZpcm9ubWVudCBkZXRlY3Rpb24gd2l0aG91dCAnYXMgYW55J1xuY29uc3QgaXNUZXN0RW52aXJvbm1lbnQgPSAoKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAndW5kZWZpbmVkJykgcmV0dXJuIGZhbHNlXG4gICAgY29uc3QgZ2xvYmFsV2l0aFByb2Nlc3MgPSBnbG9iYWxUaGlzIGFzIHVua25vd24gYXMgeyBwcm9jZXNzPzogeyBlbnY/OiB7IE5PREVfRU5WPzogc3RyaW5nIH0gfSB9XG4gICAgcmV0dXJuIGdsb2JhbFdpdGhQcm9jZXNzLnByb2Nlc3M/LmVudj8uTk9ERV9FTlYgPT09ICd0ZXN0J1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkU3luY1RyYW5zcG9ydChcbiAgZW5naW5lOiBJRW5naW5lLFxuICBzZW5kQmluYXJ5OiAobXNnOiBTZW5kQmluYXJ5UmVxdWVzdCkgPT4gUHJvbWlzZTxTZW5kQmluYXJ5UmVzcG9uc2U+LFxuICBnZXRVc2VyRGF0YTogKHZhbHVlOiBHZXRVc2VyRGF0YVJlcXVlc3QpID0+IFByb21pc2U8R2V0VXNlckRhdGFSZXNwb25zZT4sXG4gIGlzU2VydmVyRm46IChyZXF1ZXN0OiBJc1NlcnZlclJlcXVlc3QpID0+IFByb21pc2U8SXNTZXJ2ZXJSZXNwb25zZT4sXG4gIG5hbWU6IHN0cmluZ1xuKSB7XG4gIC8vIFByb2ZpbGUgSW5mb1xuICBjb25zdCBteVByb2ZpbGU6IElQcm9maWxlID0ge30gYXMgSVByb2ZpbGVcbiAgZmV0Y2hQcm9maWxlKG15UHJvZmlsZSEsIGdldFVzZXJEYXRhKVxuXG4gIGNvbnN0IGlzU2VydmVyQXRvbSA9IEF0b208Ym9vbGVhbj4oKVxuICBjb25zdCBpc1Jvb21SZWFkeUF0b20gPSBBdG9tPGJvb2xlYW4+KGZhbHNlKVxuXG4gIHZvaWQgaXNTZXJ2ZXJGbih7fSkudGhlbigoJDogSXNTZXJ2ZXJSZXNwb25zZSkgPT4ge1xuICAgIHJldHVybiBpc1NlcnZlckF0b20uc3dhcCghISQuaXNTZXJ2ZXIpXG4gIH0pXG5cbiAgLy8gRW50aXR5IHV0aWxzXG4gIGNvbnN0IGVudGl0eURlZmluaXRpb25zID0gZW50aXR5VXRpbHMoZW5naW5lLCBteVByb2ZpbGUpXG5cbiAgLy8gTGlzdCBvZiBNZXNzYWdlQnVzcyBtZXNzc2FnZXMgdG8gYmUgc2VudCBvbiBldmVyeSBmcmFtZSB0byBjb21tc1xuICBjb25zdCBwZW5kaW5nTWVzc2FnZUJ1c01lc3NhZ2VzVG9TZW5kOiB7IGRhdGE6IFVpbnQ4QXJyYXlbXTsgYWRkcmVzczogc3RyaW5nW10gfVtdID0gW11cblxuICBjb25zdCBiaW5hcnlNZXNzYWdlQnVzID0gQmluYXJ5TWVzc2FnZUJ1cygoZGF0YSwgYWRkcmVzcykgPT4ge1xuICAgIHBlbmRpbmdNZXNzYWdlQnVzTWVzc2FnZXNUb1NlbmQucHVzaCh7IGRhdGE6IFtkYXRhXSwgYWRkcmVzczogYWRkcmVzcyA/PyBbXSB9KVxuICB9KVxuXG4gIGZ1bmN0aW9uIGdldE1lc3NhZ2VzVG9TZW5kKCk6IHR5cGVvZiBwZW5kaW5nTWVzc2FnZUJ1c01lc3NhZ2VzVG9TZW5kIHtcbiAgICBjb25zdCBtZXNzYWdlcyA9IFsuLi5wZW5kaW5nTWVzc2FnZUJ1c01lc3NhZ2VzVG9TZW5kXVxuICAgIHBlbmRpbmdNZXNzYWdlQnVzTWVzc2FnZXNUb1NlbmQubGVuZ3RoID0gMFxuICAgIHJldHVybiBtZXNzYWdlc1xuICB9XG4gIGNvbnN0IHBsYXllcnMgPSBkZWZpbmVQbGF5ZXJIZWxwZXIoZW5naW5lKVxuXG4gIGxldCBzdGF0ZUlzU3luY3Jvbml6ZWQgPSBmYWxzZVxuXG4gIC8qKlxuICAgKiBXZSBuZWVkIHRvIHdhaXQgdGlsbCAyIHRpY2tzIHRoYXQgaXMgd2hlbiB0aGUgZW5naW5lIGlzIHJlYWR5IHRvIHNlbmQgbmV3IG1lc3NhZ2VzLlxuICAgKiBUaGUgZmlyc3QgdGljayBpcyBmb3IgdGhlIGNsaWVudCBlbmdpbmUgcHJvY2Vzc2luZyB0aGUgQ1JEVCBtZXNzYWdlcyxcbiAgICogYW5kIHRoZSBzZWNvbmQgb25lIGFyZSB0aGUgbWVzc2FnZXMgY3JlYXRlZCBieSB0aGUgbWFpbigpIGZ1bmN0aW9uLlxuICAgKiBTbyB0byBhdm9pZCBzZW5kaW5nIHRob3NlIG1lc3NhZ2VzLCB0aGF0IGFsbCB0aGUgY2xpZW50cyBoYXZlLCB0aHJvdWdoIHRoZSBuZXR3b3JrIHdlIHB1dCB0aGlzIHZhbGlkYXRpb24gaGVyZS5cbiAgICovXG4gIGxldCB0aWNrID0gMFxuICBjb25zdCBUUkFOU1BPUlRfSU5JVElBTElaRURfTlVNQkVSID0gaXNUZXN0RW52aXJvbm1lbnQoKSA/IDAgOiAyXG4gIC8vIEFkZCBTeW5jIFRyYW5zcG9ydFxuICBjb25zdCB0cmFuc3BvcnQ6IFRyYW5zcG9ydCA9IHtcbiAgICBmaWx0ZXI6IHN5bmNGaWx0ZXIoZW5naW5lKSxcbiAgICBzZW5kOiBhc3luYyAobWVzc2FnZXMpID0+IHtcbiAgICAgIGlmICh0aWNrIDw9IFRSQU5TUE9SVF9JTklUSUFMSVpFRF9OVU1CRVIpIHRpY2srK1xuICAgICAgZm9yIChjb25zdCBtZXNzYWdlIG9mIHRpY2sgPiBUUkFOU1BPUlRfSU5JVElBTElaRURfTlVNQkVSID8gW21lc3NhZ2VzXS5mbGF0KCkgOiBbXSkge1xuICAgICAgICBpZiAobWVzc2FnZS5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyguLi5BcnJheS5mcm9tKHNlcmlhbGl6ZUNyZHRNZXNzYWdlcygnW05ldHdvcmtNZXNzYWdlIHNlbnRdOicsIG1lc3NhZ2UsIGVuZ2luZSkpKVxuXG4gICAgICAgICAgLy8gQ29udmVydCByZWd1bGFyIG1lc3NhZ2VzIHRvIG5ldHdvcmsgbWVzc2FnZXMgZm9yIGJyb2FkY2FzdGluZyB3aXRoIGNodW5raW5nXG4gICAgICAgICAgZm9yIChjb25zdCBjaHVuayBvZiBzZXJ2ZXJWYWxpZGF0b3IuY29udmVydFJlZ3VsYXJUb05ldHdvcmtNZXNzYWdlKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICBiaW5hcnlNZXNzYWdlQnVzLmVtaXQoQ29tbXNNZXNzYWdlLkNSRFQsIGNodW5rKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgcGVlck1lc3NhZ2VzID0gZ2V0TWVzc2FnZXNUb1NlbmQoKVxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZW5kQmluYXJ5KHsgZGF0YTogW10sIHBlZXJEYXRhOiBwZWVyTWVzc2FnZXMgfSlcbiAgICAgIGJpbmFyeU1lc3NhZ2VCdXMuX19wcm9jZXNzTWVzc2FnZXMocmVzcG9uc2UuZGF0YSlcbiAgICB9LFxuICAgIHR5cGU6IG5hbWVcbiAgfVxuXG4gIC8vIFNlcnZlciB2YWxpZGF0aW9uIHNldHVwXG4gIGNvbnN0IHNlcnZlclZhbGlkYXRvciA9IGNyZWF0ZVNlcnZlclZhbGlkYXRvcih7XG4gICAgZW5naW5lLFxuICAgIGJpbmFyeU1lc3NhZ2VCdXNcbiAgfSlcblxuICAvLyBJbml0aWFsaXplIEV2ZW50IEJ1cyB3aXRoIHJlZ2lzdGVyZWQgc2NoZW1hc1xuICBjb25zdCBldmVudEJ1cyA9IG5ldyBSb29tKGVuZ2luZSwgYmluYXJ5TWVzc2FnZUJ1cywgaXNTZXJ2ZXJBdG9tLCBpc1Jvb21SZWFkeUF0b20pXG5cbiAgLy8gU2V0IGdsb2JhbCBldmVudEJ1cyBpbnN0YW5jZVxuICBzZXRHbG9iYWxSb29tKGV2ZW50QnVzKVxuXG4gIGVuZ2luZS5hZGRUcmFuc3BvcnQodHJhbnNwb3J0KVxuICAvLyBFbmQgYWRkIHN5bmMgdHJhbnNwb3J0XG5cbiAgLy8gUmVjZWl2ZSAmIFByb2Nlc3MgQ1JEVF9TVEFURVxuICBiaW5hcnlNZXNzYWdlQnVzLm9uKENvbW1zTWVzc2FnZS5SRVFfQ1JEVF9TVEFURSwgYXN5bmMgKGRhdGEsIHNlbmRlcikgPT4ge1xuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZygnW1JFUV9DUkRUX1NUQVRFXScsIHNlbmRlciwgRGF0ZS5ub3coKSlcbiAgICBmb3IgKGNvbnN0IGNodW5rIG9mIGVuZ2luZVRvQ3JkdChlbmdpbmUpKSB7XG4gICAgICBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiYgY29uc29sZS5sb2coJ1tFbWl0aW5nOl0nLCBzZW5kZXIsIERhdGUubm93KCkpXG4gICAgICBiaW5hcnlNZXNzYWdlQnVzLmVtaXQoQ29tbXNNZXNzYWdlLlJFU19DUkRUX1NUQVRFLCBjaHVuaywgW3NlbmRlcl0pXG4gICAgfVxuICB9KVxuICBiaW5hcnlNZXNzYWdlQnVzLm9uKENvbW1zTWVzc2FnZS5SRVNfQ1JEVF9TVEFURSwgYXN5bmMgKGRhdGEsIHNlbmRlcikgPT4ge1xuICAgIHJlcXVlc3RpbmdTdGF0ZSA9IGZhbHNlXG4gICAgZWxhcHNlZFRpbWVTaW5jZVJlcXVlc3QgPSAwXG4gICAgaWYgKGlzU2VydmVyQXRvbS5nZXRPck51bGwoKSB8fCBzZW5kZXIgIT09IEFVVEhfU0VSVkVSX1BFRVJfSUQpIHJldHVyblxuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZygnW1Byb2Nlc3NpbmcgQ1JEVCBTdGF0ZV0nLCBkYXRhLmJ5dGVMZW5ndGggLyAxMDI0LCAnS0InKVxuICAgIHRyYW5zcG9ydC5vbm1lc3NhZ2UhKHNlcnZlclZhbGlkYXRvci5wcm9jZXNzQ2xpZW50TWVzc2FnZXMoZGF0YSwgc2VuZGVyKSlcbiAgICBzdGF0ZUlzU3luY3Jvbml6ZWQgPSB0cnVlXG5cbiAgICAvLyBJTVBPUlRBTlQ6IE9ubHkgbWFyayByb29tIGFzIHJlYWR5IEFGVEVSIHN0YXRlIGlzIHN5bmNocm9uaXplZFxuICAgIC8vIFRoaXMgZW5zdXJlcyBjb21tcyBpcyB0cnVseSBjb25uZWN0ZWQgYW5kIHdvcmtpbmdcbiAgICBjb25zdCByZWFsbUluZm8gPSBSZWFsbUluZm8uZ2V0T3JOdWxsKGVuZ2luZS5Sb290RW50aXR5KVxuICAgIGlmIChyZWFsbUluZm8gJiYgY2hlY2tSb29tUmVhZHkocmVhbG1JbmZvKSkge1xuICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdbaXNSb29tUmVhZHldIE1hcmtpbmcgcm9vbSBhcyByZWFkeSBhZnRlciBzdGF0ZSBzeW5jJylcbiAgICAgIGlzUm9vbVJlYWR5QXRvbS5zd2FwKHRydWUpXG4gICAgfVxuICB9KVxuXG4gIC8vIHJlY2VpdmVkIG1lc3NhZ2UgZnJvbSB0aGUgbmV0d29ya1xuICBiaW5hcnlNZXNzYWdlQnVzLm9uKENvbW1zTWVzc2FnZS5DUkRULCAodmFsdWUsIHNlbmRlcikgPT4ge1xuICAgIGNvbnN0IGlzU2VydmVyID0gaXNTZXJ2ZXJBdG9tLmdldE9yTnVsbCgpXG4gICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmXG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgdHJhbnNwb3J0LnR5cGUsXG4gICAgICAgIC4uLkFycmF5LmZyb20oc2VyaWFsaXplQ3JkdE1lc3NhZ2VzKCdbTmV0d29ya01lc3NhZ2UgcmVjZWl2ZWRdOicsIHZhbHVlLCBlbmdpbmUpKSxcbiAgICAgICAgaXNTZXJ2ZXJcbiAgICAgIClcbiAgICBpZiAoaXNTZXJ2ZXIpIHtcbiAgICAgIHRyYW5zcG9ydC5vbm1lc3NhZ2UhKHNlcnZlclZhbGlkYXRvci5wcm9jZXNzU2VydmVyTWVzc2FnZXModmFsdWUsIHNlbmRlcikpXG4gICAgfSBlbHNlIGlmIChzZW5kZXIgPT09IEFVVEhfU0VSVkVSX1BFRVJfSUQpIHtcbiAgICAgIC8vIFByb2Nlc3MgbmV0d29yayBtZXNzYWdlcyBmcm9tIHNlcnZlciBhbmQgY29udmVydCB0byByZWd1bGFyIG1lc3NhZ2VzXG4gICAgICB0cmFuc3BvcnQub25tZXNzYWdlIShzZXJ2ZXJWYWxpZGF0b3IucHJvY2Vzc0NsaWVudE1lc3NhZ2VzKHZhbHVlLCBzZW5kZXIpKVxuICAgIH1cbiAgfSlcblxuICAvLyByZWNlaXZlZCBhdXRob3JpdGF0aXZlIG1lc3NhZ2UgZnJvbSBzZXJ2ZXIgLSBmb3JjZSBhcHBseSB0byBmaXggaW52YWxpZCBsb2NhbCBzdGF0ZVxuICBiaW5hcnlNZXNzYWdlQnVzLm9uKENvbW1zTWVzc2FnZS5DUkRUX0FVVEhPUklUQVRJVkUsICh2YWx1ZSwgc2VuZGVyKSA9PiB7XG4gICAgLy8gT25seSBhY2NlcHQgYXV0aG9yaXRhdGl2ZSBtZXNzYWdlcyBmcm9tIGF1dGhvcml0YXRpdmUgc2VydmVyXG4gICAgaWYgKHNlbmRlciAhPT0gQVVUSF9TRVJWRVJfUEVFUl9JRCkgcmV0dXJuXG5cbiAgICAvLyBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiZcbiAgICBjb25zb2xlLmxvZygnW0FVVEhPUklUQVRJVkVdIFJlY2VpdmVkIGF1dGhvcml0YXRpdmUgbWVzc2FnZSBmcm9tIHNlcnZlcjonLCB2YWx1ZS5ieXRlTGVuZ3RoLCAnYnl0ZXMnKVxuXG4gICAgLy8gUHJvY2VzcyBhdXRob3JpdGF0aXZlIG1lc3NhZ2VzIGJ5IGZvcmNpbmcgdGhlbSB0aHJvdWdoIG5vcm1hbCBDUkRUIHByb2Nlc3NpbmdcbiAgICAvLyBidXQgd2l0aCBhIHRpbWVzdGFtcCB0aGF0J3MgZ3VhcmFudGVlZCB0byBiZSBhY2NlcHRlZFxuICAgIGNvbnN0IGF1dGhvcml0YXRpdmVCdWZmZXIgPSBzZXJ2ZXJWYWxpZGF0b3IucHJvY2Vzc0NsaWVudE1lc3NhZ2VzKHZhbHVlLCBzZW5kZXIsIHRydWUpXG4gICAgaWYgKGF1dGhvcml0YXRpdmVCdWZmZXIuYnl0ZUxlbmd0aCA+IDApIHtcbiAgICAgIC8vIEFwcGx5IGF1dGhvcml0YXRpdmUgbWVzc2FnZSB0aHJvdWdoIG5vcm1hbCB0cmFuc3BvcnQsIGJ1dCB0aGUgc2VydmVyJ3MgbWVzc2FnZXNcbiAgICAgIC8vIHNob3VsZCBiZSBwcm9jZXNzZWQgYXMgYXV0aG9yaXRhdGl2ZSB3aXRoIHNwZWNpYWwgdGltZXN0YW1wIGhhbmRsaW5nXG4gICAgICB0cmFuc3BvcnQub25tZXNzYWdlIShhdXRob3JpdGF0aXZlQnVmZmVyKVxuXG4gICAgICBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiYgY29uc29sZS5sb2coJ1tBVVRIT1JJVEFUSVZFXSBBcHBsaWVkIHNlcnZlciBhdXRob3JpdGF0aXZlIG1lc3NhZ2UgdG8gbG9jYWwgc3RhdGUnKVxuICAgIH1cbiAgfSlcblxuICBwbGF5ZXJzLm9uRW50ZXJTY2VuZSgocGxheWVyKSA9PiB7XG4gICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdbb25FbnRlclNjZW5lXScsIHBsYXllci51c2VySWQpXG4gICAgaWYgKCFpc1NlcnZlckF0b20uZ2V0T3JOdWxsKCkgJiYgbXlQcm9maWxlLnVzZXJJZCA9PT0gcGxheWVyLnVzZXJJZCkge1xuICAgICAgcmVxdWVzdFN0YXRlKClcbiAgICB9XG4gIH0pXG5cbiAgLy8gSGVscGVyIHRvIGNoZWNrIHJvb20gcmVhZHkgY29uZGl0aW9uc1xuICBmdW5jdGlvbiBjaGVja1Jvb21SZWFkeShyZWFsbUluZm86IFJldHVyblR5cGU8dHlwZW9mIFJlYWxtSW5mby5nZXRPck51bGw+KTogYm9vbGVhbiB7XG4gICAgaWYgKCFyZWFsbUluZm8pIHJldHVybiBmYWxzZVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIHJvb20gaW5zdGFuY2UgZXhpc3RzXG4gICAgICBpZiAoIWV2ZW50QnVzKSByZXR1cm4gZmFsc2VcblxuICAgICAgcmV0dXJuICEhKHJlYWxtSW5mby5jb21tc0FkYXB0ZXIgJiYgcmVhbG1JbmZvLmlzQ29ubmVjdGVkU2NlbmVSb29tICYmIHJlYWxtSW5mby5yb29tKVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgLy8gQXNrcyBmb3IgdGhlIFJFUV9DUkRUX1NUQVRFIHdoZW4gaXRzIGNvbm5lY3RlZCB0byBjb21tc1xuICBSZWFsbUluZm8ub25DaGFuZ2UoZW5naW5lLlJvb3RFbnRpdHksICh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IGlzU2VydmVyID0gaXNTZXJ2ZXJBdG9tLmdldE9yTnVsbCgpXG5cbiAgICBpZiAoIXZhbHVlPy5pc0Nvbm5lY3RlZFNjZW5lUm9vbSkge1xuICAgICAgLy8gT25seSByZWFjdCB3aGVuIGFjdHVhbGx5IHRyYW5zaXRpb25pbmcgZnJvbSByZWFkeSB0byBub3QgcmVhZHlcbiAgICAgIGlmIChpc1Jvb21SZWFkeUF0b20uZ2V0T3JOdWxsKCkgPT09IHRydWUpIHtcbiAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdEaXNjb25uZWN0ZWQgZnJvbSBjb21tcycpXG4gICAgICAgIGlzUm9vbVJlYWR5QXRvbS5zd2FwKGZhbHNlKVxuICAgICAgICBpZiAoIWlzU2VydmVyKSB7XG4gICAgICAgICAgc3RhdGVJc1N5bmNyb25pemVkID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh2YWx1ZT8uaXNDb25uZWN0ZWRTY2VuZVJvb20pIHtcbiAgICAgIHJlcXVlc3RTdGF0ZSgpXG5cbiAgICAgIC8vIEZvciBzZXJ2ZXJzLCBtYXJrIGFzIHJlYWR5IGltbWVkaWF0ZWx5IHdoZW4gY29ubmVjdGVkXG4gICAgICAvLyAoc2VydmVycyBkb24ndCBuZWVkIHRvIHN5bmMgc3RhdGUgZnJvbSBhbnlvbmUpXG4gICAgICBpZiAoaXNTZXJ2ZXIgJiYgY2hlY2tSb29tUmVhZHkodmFsdWUpICYmIGlzUm9vbVJlYWR5QXRvbS5nZXRPck51bGwoKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdbaXNSb29tUmVhZHldIFNlcnZlciBtYXJraW5nIHJvb20gYXMgcmVhZHknKVxuICAgICAgICBpc1Jvb21SZWFkeUF0b20uc3dhcCh0cnVlKVxuICAgICAgfVxuICAgICAgLy8gRm9yIGNsaWVudHMsIHJvb20gd2lsbCBiZSBtYXJrZWQgcmVhZHkgYWZ0ZXIgcmVjZWl2aW5nIENSRFQgc3RhdGUgKGFib3ZlKVxuICAgIH1cbiAgfSlcblxuICBsZXQgcmVxdWVzdGluZ1N0YXRlID0gZmFsc2VcbiAgbGV0IGVsYXBzZWRUaW1lU2luY2VSZXF1ZXN0ID0gMFxuICBjb25zdCBTVEFURV9SRVFVRVNUX1JFVFJZX0lOVEVSVkFMID0gMi4wIC8vIHNlY29uZHNcblxuICAvKipcbiAgICogV2h5IHdlIGhhdmUgdG8gcmVxdWVzdCB0aGUgc3RhdGUgaWYgd2UgaGF2ZSBhIHNlcnZlciB0aGF0IGNhbiBzZW5kIHVzIHRoZSBzdGF0ZSB3aGVuIHdlIGpvaW5lZD9cbiAgICogVGhlIHRoaW5nIGlzIHRoYXQgd2hlbiB0aGUgc2VydmVyIGRldGVjdHMgYSBuZXcgSk9JTl9QQVJUSUNJUEFOVCBvbiBsaXZla2l0IHJvb20sIGl0IHNlbmRzIGF1dG9tYXRpY2FsbHkgdGhlIHN0YXRlIHRvIHRoYXQgcGVlci5cbiAgICogQnV0IGluIHVuaXR5LCBpdCB0YWtlcyBtb3JlIHRpbWUsIHNvIHRoYXQgbWVzc2FnZSBpcyBub3QgYmVpbmcgZGVsaXZlcmVkIHRvIHRoZSBjbGllbnQuXG4gICAqIFNvIGluc3RlYWQsIHdoZW4gd2UgYXJlIGZpbmFsbHkgY29ubmVjdGVkIHRvIHRoZSByb29tLCB3ZSByZXF1ZXN0IHRoZSBzdGF0ZSwgYW5kIHRoZW4gdGhlIHNlcnZlciBhbnN3ZXJzIHdpdGggdGhlIHN0YXRlIDopXG4gICAqXG4gICAqIElmIG5vIHJlc3BvbnNlIGlzIHJlY2VpdmVkIHdpdGhpbiAyIHNlY29uZHMsIHRoZSByZXF1ZXN0IGlzIGF1dG9tYXRpY2FsbHkgcmV0cmllZC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlcXVlc3RTdGF0ZSgpIHtcbiAgICBpZiAoaXNTZXJ2ZXJBdG9tLmdldE9yTnVsbCgpKSByZXR1cm5cbiAgICBpZiAoUmVhbG1JbmZvLmdldE9yTnVsbChlbmdpbmUuUm9vdEVudGl0eSk/LmlzQ29ubmVjdGVkU2NlbmVSb29tICYmICFyZXF1ZXN0aW5nU3RhdGUpIHtcbiAgICAgIHJlcXVlc3RpbmdTdGF0ZSA9IHRydWVcbiAgICAgIGVsYXBzZWRUaW1lU2luY2VSZXF1ZXN0ID0gMFxuICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdSZXF1ZXN0aW5nIHN0YXRlLi4uJylcbiAgICAgIGJpbmFyeU1lc3NhZ2VCdXMuZW1pdChDb21tc01lc3NhZ2UuUkVRX0NSRFRfU1RBVEUsIG5ldyBVaW50OEFycmF5KCkpXG4gICAgfVxuICB9XG5cbiAgLy8gU3lzdGVtIHRvIHJldHJ5IHN0YXRlIHJlcXVlc3QgaWYgbm8gcmVzcG9uc2UgaXMgcmVjZWl2ZWQgd2l0aGluIHRoZSByZXRyeSBpbnRlcnZhbFxuICBlbmdpbmUuYWRkU3lzdGVtKChkdDogbnVtYmVyKSA9PiB7XG4gICAgaWYgKHJlcXVlc3RpbmdTdGF0ZSAmJiAhc3RhdGVJc1N5bmNyb25pemVkKSB7XG4gICAgICBlbGFwc2VkVGltZVNpbmNlUmVxdWVzdCArPSBkdFxuICAgICAgaWYgKGVsYXBzZWRUaW1lU2luY2VSZXF1ZXN0ID49IFNUQVRFX1JFUVVFU1RfUkVUUllfSU5URVJWQUwpIHtcbiAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdTdGF0ZSByZXF1ZXN0IHRpbWVkIG91dCwgcmV0cnlpbmcuLi4nKVxuICAgICAgICBlbGFwc2VkVGltZVNpbmNlUmVxdWVzdCA9IDBcbiAgICAgICAgcmVxdWVzdGluZ1N0YXRlID0gZmFsc2VcbiAgICAgICAgcmVxdWVzdFN0YXRlKClcbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgcGxheWVycy5vbkxlYXZlU2NlbmUoKHVzZXJJZCkgPT4ge1xuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZygnW29uTGVhdmVTY2VuZV0nLCB1c2VySWQpXG4gIH0pXG5cbiAgZnVuY3Rpb24gaXNTdGF0ZVN5bmNyb25pemVkKCkge1xuICAgIHJldHVybiBzdGF0ZUlzU3luY3Jvbml6ZWRcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4uZW50aXR5RGVmaW5pdGlvbnMsXG4gICAgbXlQcm9maWxlLFxuICAgIGlzU3RhdGVTeW5jcm9uaXplZCxcbiAgICBiaW5hcnlNZXNzYWdlQnVzLFxuICAgIGV2ZW50QnVzLFxuICAgIGlzUm9vbVJlYWR5QXRvbVxuICB9XG59XG4iXX0=
145
+ /**
146
+ * Messages Protocol Encoding
147
+ *
148
+ * CRDT: Plain Uint8Array
149
+ *
150
+ * CRDT_STATE_RES { sender: string, data: Uint8Array}
151
+ */
152
+ function decodeCRDTState(data) {
153
+ let offset = 0;
154
+ const r = new Uint8Array(data);
155
+ const view = new DataView(r.buffer);
156
+ const senderLength = view.getUint8(offset);
157
+ offset += 1;
158
+ const sender = decodeString(data.subarray(1, senderLength + 1));
159
+ offset += senderLength;
160
+ const state = r.subarray(offset);
161
+ return { sender, data: state };
162
+ }
163
+ function encodeCRDTState(address, data) {
164
+ // address to uint8array
165
+ const addressBuffer = encodeString(address);
166
+ const addressOffset = 1;
167
+ const messageLength = addressOffset + addressBuffer.byteLength + data.byteLength;
168
+ const serializedMessage = new Uint8Array(messageLength);
169
+ serializedMessage.set(new Uint8Array([addressBuffer.byteLength]), 0);
170
+ serializedMessage.set(addressBuffer, 1);
171
+ serializedMessage.set(data, addressBuffer.byteLength + 1);
172
+ return serializedMessage;
173
+ }
174
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZS1idXMtc3luYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXR3b3JrL21lc3NhZ2UtYnVzLXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFzQixTQUFTLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFHNUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2pHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUV4QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDL0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sK0JBQStCLENBQUE7QUFHckUsK0NBQStDO0FBQy9DLE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsTUFBZSxFQUNmLFVBQW1FLEVBQ25FLFdBQXdFO0lBRXhFLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxFQUFFLENBQUUsVUFBa0IsQ0FBQyxzQkFBc0IsSUFBSSxLQUFLLENBQUE7SUFDeEYsZUFBZTtJQUNmLE1BQU0sU0FBUyxHQUFhLEVBQWMsQ0FBQTtJQUMxQyxZQUFZLENBQUMsU0FBVSxFQUFFLFdBQVcsQ0FBQyxDQUFBO0lBRXJDLGVBQWU7SUFDZixNQUFNLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFFeEQsbUVBQW1FO0lBQ25FLE1BQU0sK0JBQStCLEdBQWdELEVBQUUsQ0FBQTtJQUV2RixNQUFNLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLENBQUMsSUFBSSxFQUFFLE9B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LGFBQWEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDekQsT0FBTyxpQkFBaUIsQ0FBQTtBQUMxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUVuZ2luZSwgVHJhbnNwb3J0LCBSZWFsbUluZm8sIFBsYXllcklkZW50aXR5RGF0YSB9IGZyb20gJ0BkY2wvZWNzJ1xuaW1wb3J0IHsgdHlwZSBTZW5kQmluYXJ5UmVxdWVzdCwgdHlwZSBTZW5kQmluYXJ5UmVzcG9uc2UgfSBmcm9tICd+c3lzdGVtL0NvbW11bmljYXRpb25zQ29udHJvbGxlcidcblxuaW1wb3J0IHsgc3luY0ZpbHRlciB9IGZyb20gJy4vZmlsdGVyJ1xuaW1wb3J0IHsgZW5naW5lVG9DcmR0IH0gZnJvbSAnLi9zdGF0ZSdcbmltcG9ydCB7IEJpbmFyeU1lc3NhZ2VCdXMsIENvbW1zTWVzc2FnZSwgZGVjb2RlU3RyaW5nLCBlbmNvZGVTdHJpbmcgfSBmcm9tICcuL2JpbmFyeS1tZXNzYWdlLWJ1cydcbmltcG9ydCB7IGZldGNoUHJvZmlsZSB9IGZyb20gJy4vdXRpbHMnXG5pbXBvcnQgeyBlbnRpdHlVdGlscyB9IGZyb20gJy4vZW50aXRpZXMnXG5pbXBvcnQgeyBHZXRVc2VyRGF0YVJlcXVlc3QsIEdldFVzZXJEYXRhUmVzcG9uc2UgfSBmcm9tICd+c3lzdGVtL1VzZXJJZGVudGl0eSdcbmltcG9ydCB7IGRlZmluZVBsYXllckhlbHBlciB9IGZyb20gJy4uL3BsYXllcnMnXG5pbXBvcnQgeyBzZXJpYWxpemVDcmR0TWVzc2FnZXMgfSBmcm9tICcuLi9pbnRlcm5hbC90cmFuc3BvcnRzL2xvZ2dlcidcblxuZXhwb3J0IHR5cGUgSVByb2ZpbGUgPSB7IG5ldHdvcmtJZDogbnVtYmVyOyB1c2VySWQ6IHN0cmluZyB9XG4vLyB1c2VyIHRoYXQgd2UgYXNrZWQgZm9yIHRoZSBpbml0YWwgY3JkdCBzdGF0ZVxuZXhwb3J0IGZ1bmN0aW9uIGFkZFN5bmNUcmFuc3BvcnQoXG4gIGVuZ2luZTogSUVuZ2luZSxcbiAgc2VuZEJpbmFyeTogKG1zZzogU2VuZEJpbmFyeVJlcXVlc3QpID0+IFByb21pc2U8U2VuZEJpbmFyeVJlc3BvbnNlPixcbiAgZ2V0VXNlckRhdGE6ICh2YWx1ZTogR2V0VXNlckRhdGFSZXF1ZXN0KSA9PiBQcm9taXNlPEdldFVzZXJEYXRhUmVzcG9uc2U+XG4pIHtcbiAgY29uc3QgREVCVUdfTkVUV09SS19NRVNTQUdFUyA9ICgpID0+IChnbG9iYWxUaGlzIGFzIGFueSkuREVCVUdfTkVUV09SS19NRVNTQUdFUyA/PyBmYWxzZVxuICAvLyBQcm9maWxlIEluZm9cbiAgY29uc3QgbXlQcm9maWxlOiBJUHJvZmlsZSA9IHt9IGFzIElQcm9maWxlXG4gIGZldGNoUHJvZmlsZShteVByb2ZpbGUhLCBnZXRVc2VyRGF0YSlcblxuICAvLyBFbnRpdHkgdXRpbHNcbiAgY29uc3QgZW50aXR5RGVmaW5pdGlvbnMgPSBlbnRpdHlVdGlscyhlbmdpbmUsIG15UHJvZmlsZSlcblxuICAvLyBMaXN0IG9mIE1lc3NhZ2VCdXNzIG1lc3NzYWdlcyB0byBiZSBzZW50IG9uIGV2ZXJ5IGZyYW1lIHRvIGNvbW1zXG4gIGNvbnN0IHBlbmRpbmdNZXNzYWdlQnVzTWVzc2FnZXNUb1NlbmQ6IHsgZGF0YTogVWludDhBcnJheVtdOyBhZGRyZXNzOiBzdHJpbmdbXSB9W10gPSBbXVxuXG4gIGNvbnN0IGJpbmFyeU1lc3NhZ2VCdXMgPSBCaW5hcnlNZXNzYWdlQnVzKChkYXRhLCBhZGRyZXNzKSA9PiB7XG4gICAgcGVuZGluZ01lc3NhZ2VCdXNNZXNzYWdlc1RvU2VuZC5wdXNoKHsgZGF0YTogW2RhdGFdLCBhZGRyZXNzOiBhZGRyZXNzID8/IFtdIH0pXG4gIH0pXG5cbiAgZnVuY3Rpb24gZ2V0TWVzc2FnZXNUb1NlbmQoKTogdHlwZW9mIHBlbmRpbmdNZXNzYWdlQnVzTWVzc2FnZXNUb1NlbmQge1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gWy4uLnBlbmRpbmdNZXNzYWdlQnVzTWVzc2FnZXNUb1NlbmRdXG4gICAgcGVuZGluZ01lc3NhZ2VCdXNNZXNzYWdlc1RvU2VuZC5sZW5ndGggPSAwXG4gICAgcmV0dXJuIG1lc3NhZ2VzXG4gIH1cbiAgY29uc3QgcGxheWVycyA9IGRlZmluZVBsYXllckhlbHBlcihlbmdpbmUpXG5cbiAgbGV0IHN0YXRlSXNTeW5jcm9uaXplZCA9IGZhbHNlXG4gIGxldCB0cmFuc3BvcnRJbml0aWFsemVkID0gZmFsc2VcblxuICAvLyBBZGQgU3luYyBUcmFuc3BvcnRcbiAgY29uc3QgdHJhbnNwb3J0OiBUcmFuc3BvcnQgPSB7XG4gICAgZmlsdGVyOiBzeW5jRmlsdGVyKGVuZ2luZSksXG4gICAgc2VuZDogYXN5bmMgKG1lc3NhZ2VzKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgW21lc3NhZ2VzXS5mbGF0KCkpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2UuYnl0ZUxlbmd0aCAmJiB0cmFuc3BvcnRJbml0aWFsemVkKSB7XG4gICAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyguLi5BcnJheS5mcm9tKHNlcmlhbGl6ZUNyZHRNZXNzYWdlcygnW05ldHdvcmtNZXNzYWdlIHNlbnRdOicsIG1lc3NhZ2UsIGVuZ2luZSkpKVxuICAgICAgICAgIGJpbmFyeU1lc3NhZ2VCdXMuZW1pdChDb21tc01lc3NhZ2UuQ1JEVCwgbWVzc2FnZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgcGVlck1lc3NhZ2VzID0gZ2V0TWVzc2FnZXNUb1NlbmQoKVxuICAgICAgbGV0IHRvdGFsU2l6ZSA9IDBcbiAgICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiBwZWVyTWVzc2FnZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBkYXRhIG9mIG1lc3NhZ2UuZGF0YSkge1xuICAgICAgICAgIHRvdGFsU2l6ZSArPSBkYXRhLmJ5dGVMZW5ndGhcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRvdGFsU2l6ZSkge1xuICAgICAgICBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiYgY29uc29sZS5sb2coJ1NlbmRpbmcgbmV0d29yayBtZXNzYWdlczogJywgdG90YWxTaXplIC8gMTAyNCwgJ0tCJylcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VuZEJpbmFyeSh7IGRhdGE6IFtdLCBwZWVyRGF0YTogcGVlck1lc3NhZ2VzIH0pXG4gICAgICBiaW5hcnlNZXNzYWdlQnVzLl9fcHJvY2Vzc01lc3NhZ2VzKHJlc3BvbnNlLmRhdGEpXG4gICAgICB0cmFuc3BvcnRJbml0aWFsemVkID0gdHJ1ZVxuICAgIH0sXG4gICAgdHlwZTogJ25ldHdvcmsnXG4gIH1cbiAgZW5naW5lLmFkZFRyYW5zcG9ydCh0cmFuc3BvcnQpXG4gIC8vIEVuZCBhZGQgc3luYyB0cmFuc3BvcnRcblxuICAvLyBSZWNlaXZlICYgUHJvY2VzcyBDUkRUX1NUQVRFXG4gIGJpbmFyeU1lc3NhZ2VCdXMub24oQ29tbXNNZXNzYWdlLlJFU19DUkRUX1NUQVRFLCAodmFsdWUpID0+IHtcbiAgICBjb25zdCB7IHNlbmRlciwgZGF0YSB9ID0gZGVjb2RlQ1JEVFN0YXRlKHZhbHVlKVxuICAgIGlmIChzZW5kZXIgIT09IG15UHJvZmlsZS51c2VySWQpIHJldHVyblxuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZygnW1Byb2Nlc3NpbmcgQ1JEVCBTdGF0ZV0nLCBkYXRhLmJ5dGVMZW5ndGggLyAxMDI0LCAnS0InKVxuICAgIHRyYW5zcG9ydC5vbm1lc3NhZ2UhKGRhdGEpXG4gICAgc3RhdGVJc1N5bmNyb25pemVkID0gdHJ1ZVxuICB9KVxuXG4gIC8vIEFuc3dlciB0byBSRVFfQ1JEVF9TVEFURVxuICBiaW5hcnlNZXNzYWdlQnVzLm9uKENvbW1zTWVzc2FnZS5SRVFfQ1JEVF9TVEFURSwgYXN5bmMgKF8sIHVzZXJJZCkgPT4ge1xuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZyhgU2VuZGluZyBDUkRUIFN0YXRlIHRvOiAke3VzZXJJZH1gKVxuXG4gICAgZm9yIChjb25zdCBjaHVuayBvZiBlbmdpbmVUb0NyZHQoZW5naW5lKSkge1xuICAgICAgYmluYXJ5TWVzc2FnZUJ1cy5lbWl0KENvbW1zTWVzc2FnZS5SRVNfQ1JEVF9TVEFURSwgZW5jb2RlQ1JEVFN0YXRlKHVzZXJJZCwgY2h1bmspLCBbdXNlcklkXSlcbiAgICB9XG4gIH0pXG5cbiAgLy8gUHJvY2VzcyBDUkRUIG1lc3NhZ2VzIGhlcmVcbiAgYmluYXJ5TWVzc2FnZUJ1cy5vbihDb21tc01lc3NhZ2UuQ1JEVCwgKHZhbHVlKSA9PiB7XG4gICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmXG4gICAgICBjb25zb2xlLmxvZyhBcnJheS5mcm9tKHNlcmlhbGl6ZUNyZHRNZXNzYWdlcygnW05ldHdvcmtNZXNzYWdlIHJlY2VpdmVkXTonLCB2YWx1ZSwgZW5naW5lKSkpXG4gICAgdHJhbnNwb3J0Lm9ubWVzc2FnZSEodmFsdWUpXG4gIH0pXG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVxdWVzdFN0YXRlKHJldHJ5Q291bnQ6IG51bWJlciA9IDEpIHtcbiAgICBsZXQgcGxheWVycyA9IEFycmF5LmZyb20oZW5naW5lLmdldEVudGl0aWVzV2l0aChQbGF5ZXJJZGVudGl0eURhdGEpKVxuICAgIERFQlVHX05FVFdPUktfTUVTU0FHRVMoKSAmJiBjb25zb2xlLmxvZyhgUmVxdWVzdGluZyBzdGF0ZS4gUGxheWVycyBjb25uZWN0ZWQ6ICR7cGxheWVycy5sZW5ndGggLSAxfWApXG5cbiAgICBpZiAoIVJlYWxtSW5mby5nZXRPck51bGwoZW5naW5lLlJvb3RFbnRpdHkpPy5pc0Nvbm5lY3RlZFNjZW5lUm9vbSkge1xuICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKGBBYm9ydGluZyBSZXF1ZXN0aW5nIHN0YXRlPy4gRGlzY29ubmVjdGVkYClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGJpbmFyeU1lc3NhZ2VCdXMuZW1pdChDb21tc01lc3NhZ2UuUkVRX0NSRFRfU1RBVEUsIG5ldyBVaW50OEFycmF5KCkpXG5cbiAgICAvLyBXYWl0IH41cyBmb3IgdGhlIHJlc3BvbnNlLlxuICAgIGF3YWl0IHNsZWVwKDUwMDApXG5cbiAgICBwbGF5ZXJzID0gQXJyYXkuZnJvbShlbmdpbmUuZ2V0RW50aXRpZXNXaXRoKFBsYXllcklkZW50aXR5RGF0YSkpXG5cbiAgICBpZiAoIXN0YXRlSXNTeW5jcm9uaXplZCkge1xuICAgICAgaWYgKHBsYXllcnMubGVuZ3RoID4gMSAmJiByZXRyeUNvdW50IDw9IDIpIHtcbiAgICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coYFJlcXVlc3Rpbmcgc3RhdGUgYWdhaW4gJHtyZXRyeUNvdW50fSAobm8gcmVzcG9uc2UpLiBQbGF5ZXJzIGNvbm5lY3RlZDogJHtwbGF5ZXJzLmxlbmd0aCAtIDF9YClcbiAgICAgICAgdm9pZCByZXF1ZXN0U3RhdGUocmV0cnlDb3VudCArIDEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiYgY29uc29sZS5sb2coJ05vIGFjdGl2ZSBwbGF5ZXJzLiBTdGF0ZSBzeW5jcm9uaXplZCcpXG4gICAgICAgIHN0YXRlSXNTeW5jcm9uaXplZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwbGF5ZXJzLm9uRW50ZXJTY2VuZSgocGxheWVyKSA9PiB7XG4gICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdbb25FbnRlclNjZW5lXScsIHBsYXllci51c2VySWQpXG4gIH0pXG5cbiAgLy8gQXNrcyBmb3IgdGhlIFJFUV9DUkRUX1NUQVRFIHdoZW4gaXRzIGNvbm5lY3RlZCB0byBjb21tc1xuICBSZWFsbUluZm8ub25DaGFuZ2UoZW5naW5lLlJvb3RFbnRpdHksICh2YWx1ZSkgPT4ge1xuICAgIGlmICghdmFsdWU/LmlzQ29ubmVjdGVkU2NlbmVSb29tKSB7XG4gICAgICBERUJVR19ORVRXT1JLX01FU1NBR0VTKCkgJiYgY29uc29sZS5sb2coJ0Rpc2Nvbm5lY3RlZCBmcm9tIGNvbW1zJylcbiAgICAgIHN0YXRlSXNTeW5jcm9uaXplZCA9IGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHZhbHVlPy5pc0Nvbm5lY3RlZFNjZW5lUm9vbSkge1xuICAgICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gY29tbXMnKVxuICAgIH1cblxuICAgIGlmICh2YWx1ZT8uaXNDb25uZWN0ZWRTY2VuZVJvb20gJiYgIXN0YXRlSXNTeW5jcm9uaXplZCkge1xuICAgICAgdm9pZCByZXF1ZXN0U3RhdGUoKVxuICAgIH1cbiAgfSlcblxuICBwbGF5ZXJzLm9uTGVhdmVTY2VuZSgodXNlcklkKSA9PiB7XG4gICAgREVCVUdfTkVUV09SS19NRVNTQUdFUygpICYmIGNvbnNvbGUubG9nKCdbb25MZWF2ZVNjZW5lXScsIHVzZXJJZClcbiAgfSlcblxuICBmdW5jdGlvbiBpc1N0YXRlU3luY3Jvbml6ZWQoKSB7XG4gICAgcmV0dXJuIHN0YXRlSXNTeW5jcm9uaXplZFxuICB9XG5cbiAgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgbGV0IHRpbWVyID0gMFxuICAgICAgZnVuY3Rpb24gc2xlZXBTeXN0ZW0oZHQ6IG51bWJlcikge1xuICAgICAgICB0aW1lciArPSBkdFxuICAgICAgICBpZiAodGltZXIgKiAxMDAwID49IG1zKSB7XG4gICAgICAgICAgZW5naW5lLnJlbW92ZVN5c3RlbShzbGVlcFN5c3RlbSlcbiAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZW5naW5lLmFkZFN5c3RlbShzbGVlcFN5c3RlbSlcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5lbnRpdHlEZWZpbml0aW9ucyxcbiAgICBteVByb2ZpbGUsXG4gICAgaXNTdGF0ZVN5bmNyb25pemVkXG4gIH1cbn1cblxuLyoqXG4gKiBNZXNzYWdlcyBQcm90b2NvbCBFbmNvZGluZ1xuICpcbiAqIENSRFQ6IFBsYWluIFVpbnQ4QXJyYXlcbiAqXG4gKiBDUkRUX1NUQVRFX1JFUyB7IHNlbmRlcjogc3RyaW5nLCBkYXRhOiBVaW50OEFycmF5fVxuICovXG5mdW5jdGlvbiBkZWNvZGVDUkRUU3RhdGUoZGF0YTogVWludDhBcnJheSkge1xuICBsZXQgb2Zmc2V0ID0gMFxuICBjb25zdCByID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSlcbiAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhyLmJ1ZmZlcilcbiAgY29uc3Qgc2VuZGVyTGVuZ3RoID0gdmlldy5nZXRVaW50OChvZmZzZXQpXG4gIG9mZnNldCArPSAxXG4gIGNvbnN0IHNlbmRlciA9IGRlY29kZVN0cmluZyhkYXRhLnN1YmFycmF5KDEsIHNlbmRlckxlbmd0aCArIDEpKVxuICBvZmZzZXQgKz0gc2VuZGVyTGVuZ3RoXG4gIGNvbnN0IHN0YXRlID0gci5zdWJhcnJheShvZmZzZXQpXG5cbiAgcmV0dXJuIHsgc2VuZGVyLCBkYXRhOiBzdGF0ZSB9XG59XG5cbmZ1bmN0aW9uIGVuY29kZUNSRFRTdGF0ZShhZGRyZXNzOiBzdHJpbmcsIGRhdGE6IFVpbnQ4QXJyYXkpIHtcbiAgLy8gYWRkcmVzcyB0byB1aW50OGFycmF5XG4gIGNvbnN0IGFkZHJlc3NCdWZmZXIgPSBlbmNvZGVTdHJpbmcoYWRkcmVzcylcbiAgY29uc3QgYWRkcmVzc09mZnNldCA9IDFcbiAgY29uc3QgbWVzc2FnZUxlbmd0aCA9IGFkZHJlc3NPZmZzZXQgKyBhZGRyZXNzQnVmZmVyLmJ5dGVMZW5ndGggKyBkYXRhLmJ5dGVMZW5ndGhcblxuICBjb25zdCBzZXJpYWxpemVkTWVzc2FnZSA9IG5ldyBVaW50OEFycmF5KG1lc3NhZ2VMZW5ndGgpXG4gIHNlcmlhbGl6ZWRNZXNzYWdlLnNldChuZXcgVWludDhBcnJheShbYWRkcmVzc0J1ZmZlci5ieXRlTGVuZ3RoXSksIDApXG4gIHNlcmlhbGl6ZWRNZXNzYWdlLnNldChhZGRyZXNzQnVmZmVyLCAxKVxuICBzZXJpYWxpemVkTWVzc2FnZS5zZXQoZGF0YSwgYWRkcmVzc0J1ZmZlci5ieXRlTGVuZ3RoICsgMSlcbiAgcmV0dXJuIHNlcmlhbGl6ZWRNZXNzYWdlXG59XG4iXX0=