alicezetion 1.6.7 → 1.6.8

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 (57) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -1
  2. package/.cache/replit/nix/env.json +1 -1
  3. package/index.js +804 -381
  4. package/leiamnash/addExternalModule.js +19 -19
  5. package/leiamnash/addUserToGroup.js +113 -113
  6. package/leiamnash/changeAdminStatus.js +79 -79
  7. package/leiamnash/changeApprovalMode.js +80 -0
  8. package/leiamnash/changeArchivedStatus.js +55 -55
  9. package/leiamnash/changeBio.js +77 -77
  10. package/leiamnash/changeBlockedStatus.js +47 -47
  11. package/leiamnash/changeGroupImage.js +129 -129
  12. package/leiamnash/changeNickname.js +59 -59
  13. package/leiamnash/changeThreadColor.js +71 -71
  14. package/leiamnash/changeThreadEmoji.js +55 -55
  15. package/leiamnash/chat.js +447 -459
  16. package/leiamnash/createNewGroup.js +86 -86
  17. package/leiamnash/createPoll.js +71 -71
  18. package/leiamnash/deleteMessage.js +56 -56
  19. package/leiamnash/deleteThread.js +56 -56
  20. package/leiamnash/forwardAttachment.js +60 -60
  21. package/leiamnash/getCurrentUserID.js +7 -7
  22. package/leiamnash/getEmojiUrl.js +29 -29
  23. package/leiamnash/getFriendsList.js +84 -84
  24. package/leiamnash/getThreadHistory.js +645 -645
  25. package/leiamnash/getThreadHistoryDeprecated.js +93 -93
  26. package/leiamnash/getThreadInfo.js +212 -206
  27. package/leiamnash/getThreadInfoDeprecated.js +80 -80
  28. package/leiamnash/getThreadList.js +238 -238
  29. package/leiamnash/getThreadListDeprecated.js +75 -75
  30. package/leiamnash/getThreadPictures.js +79 -79
  31. package/leiamnash/getUserID.js +66 -66
  32. package/leiamnash/getUserInfo.js +72 -72
  33. package/leiamnash/handleFriendRequest.js +61 -61
  34. package/leiamnash/handleMessageRequest.js +65 -65
  35. package/leiamnash/httpGet.js +52 -52
  36. package/leiamnash/httpPost.js +52 -52
  37. package/leiamnash/listenMqtt.js +1078 -509
  38. package/leiamnash/logout.js +75 -75
  39. package/leiamnash/markAsDelivered.js +58 -58
  40. package/leiamnash/markAsRead.js +80 -80
  41. package/leiamnash/markAsReadAll.js +49 -49
  42. package/leiamnash/markAsSeen.js +59 -59
  43. package/leiamnash/muteThread.js +52 -52
  44. package/leiamnash/removeUserFromGroup.js +79 -79
  45. package/leiamnash/resolvePhotoUrl.js +45 -45
  46. package/leiamnash/searchForThread.js +53 -53
  47. package/leiamnash/sendTypingIndicator.js +103 -103
  48. package/leiamnash/setMessageReaction.js +117 -117
  49. package/leiamnash/setPostReaction.js +76 -76
  50. package/leiamnash/setTitle.js +86 -86
  51. package/leiamnash/threadColors.js +57 -57
  52. package/leiamnash/unfriend.js +52 -52
  53. package/leiamnash/unsendMessage.js +49 -49
  54. package/package.json +72 -72
  55. package/replit.nix +3 -0
  56. package/utils.js +196 -71
  57. package/leiamnash/listen.js +0 -553
package/utils.js CHANGED
@@ -1,11 +1,24 @@
1
1
  "use strict";
2
2
 
3
3
  var bluebird = require("bluebird");
4
- var request = bluebird.promisify(require("request").defaults({ jar: true }), {multiArgs: true});
4
+ var request = bluebird.promisify(require("request").defaults({ jar: true }));
5
5
  var stream = require("stream");
6
6
  var log = require("npmlog");
7
+ var querystring = require("querystring");
8
+ var url = require("url");
9
+
10
+ function setProxy(url) {
11
+ if (typeof url == undefined)
12
+ return request = bluebird.promisify(require("request").defaults({
13
+ jar: true,
14
+ }));
15
+ return request = bluebird.promisify(require("request").defaults({
16
+ jar: true,
17
+ proxy: url
18
+ }));
19
+ }
7
20
 
8
- function getHeaders(url, options) {
21
+ function getHeaders(url, options, ctx, customHeader) {
9
22
  var headers = {
10
23
  "Content-Type": "application/x-www-form-urlencoded",
11
24
  Referer: "https://www.facebook.com/",
@@ -14,6 +27,12 @@ function getHeaders(url, options) {
14
27
  "User-Agent": options.userAgent,
15
28
  Connection: "keep-alive"
16
29
  };
30
+ if (customHeader) {
31
+ Object.assign(headers, customHeader);
32
+ }
33
+ if (ctx && ctx.region) {
34
+ headers["X-MSGR-Region"] = ctx.region;
35
+ }
17
36
 
18
37
  return headers;
19
38
  }
@@ -27,7 +46,7 @@ function isReadableStream(obj) {
27
46
  );
28
47
  }
29
48
 
30
- function get(url, jar, qs, options) {
49
+ function get(url, jar, qs, options, ctx) {
31
50
  // I'm still confused about this
32
51
  if (getType(qs) === "Object") {
33
52
  for (var prop in qs) {
@@ -37,7 +56,7 @@ function get(url, jar, qs, options) {
37
56
  }
38
57
  }
39
58
  var op = {
40
- headers: getHeaders(url, options),
59
+ headers: getHeaders(url, options, ctx),
41
60
  timeout: 60000,
42
61
  qs: qs,
43
62
  url: url,
@@ -46,14 +65,14 @@ function get(url, jar, qs, options) {
46
65
  gzip: true
47
66
  };
48
67
 
49
- return request(op).then(function(res) {
68
+ return request(op).then(function (res) {
50
69
  return res[0];
51
70
  });
52
71
  }
53
72
 
54
- function post(url, jar, form, options) {
73
+ function post(url, jar, form, options, ctx, customHeader) {
55
74
  var op = {
56
- headers: getHeaders(url, options),
75
+ headers: getHeaders(url, options, ctx, customHeader),
57
76
  timeout: 60000,
58
77
  url: url,
59
78
  method: "POST",
@@ -62,13 +81,13 @@ function post(url, jar, form, options) {
62
81
  gzip: true
63
82
  };
64
83
 
65
- return request(op).then(function(res) {
84
+ return request(op).then(function (res) {
66
85
  return res[0];
67
86
  });
68
87
  }
69
88
 
70
- function postFormData(url, jar, form, qs, options) {
71
- var headers = getHeaders(url, options);
89
+ function postFormData(url, jar, form, qs, options, ctx) {
90
+ var headers = getHeaders(url, options, ctx);
72
91
  headers["Content-Type"] = "multipart/form-data";
73
92
  var op = {
74
93
  headers: headers,
@@ -81,7 +100,7 @@ function postFormData(url, jar, form, qs, options) {
81
100
  gzip: true
82
101
  };
83
102
 
84
- return request(op).then(function(res) {
103
+ return request(op).then(function (res) {
85
104
  return res[0];
86
105
  });
87
106
  }
@@ -162,7 +181,7 @@ var j = {
162
181
  Z:
163
182
  "%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a"
164
183
  };
165
- (function() {
184
+ (function () {
166
185
  var l = [];
167
186
  for (var m in j) {
168
187
  i[j[m]] = m;
@@ -174,18 +193,19 @@ var j = {
174
193
 
175
194
  function presenceEncode(str) {
176
195
  return encodeURIComponent(str)
177
- .replace(/([_A-Z])|%../g, function(m, n) {
196
+ .replace(/([_A-Z])|%../g, function (m, n) {
178
197
  return n ? "%" + n.charCodeAt(0).toString(16) : m;
179
198
  })
180
199
  .toLowerCase()
181
- .replace(h, function(m) {
200
+ .replace(h, function (m) {
182
201
  return i[m];
183
202
  });
184
203
  }
185
204
 
205
+ // eslint-disable-next-line no-unused-vars
186
206
  function presenceDecode(str) {
187
207
  return decodeURIComponent(
188
- str.replace(/[_A-Z]/g, function(m) {
208
+ str.replace(/[_A-Z]/g, function (m) {
189
209
  return j[m];
190
210
  })
191
211
  );
@@ -237,7 +257,7 @@ function getGUID() {
237
257
  /** @type {number} */
238
258
  var sectionLength = Date.now();
239
259
  /** @type {string} */
240
- var id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
260
+ var id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
241
261
  /** @type {number} */
242
262
  var r = Math.floor((sectionLength + Math.random() * 16) % 16);
243
263
  /** @type {number} */
@@ -265,7 +285,17 @@ function _formatAttachment(attachment1, attachment2) {
265
285
  type = "StickerAttachment";
266
286
  blob = attachment1.sticker_attachment;
267
287
  } else if (!type && attachment1.extensible_attachment) {
268
- type = "ExtensibleAttachment";
288
+ if (
289
+ attachment1.extensible_attachment.story_attachment &&
290
+ attachment1.extensible_attachment.story_attachment.target &&
291
+ attachment1.extensible_attachment.story_attachment.target.__typename &&
292
+ attachment1.extensible_attachment.story_attachment.target.__typename === "MessageLocation"
293
+ ) {
294
+ type = "MessageLocation";
295
+ } else {
296
+ type = "ExtensibleAttachment";
297
+ }
298
+
269
299
  blob = attachment1.extensible_attachment;
270
300
  }
271
301
  // TODO: Determine whether "sticker", "photo", "file" etc are still used
@@ -506,6 +536,49 @@ function _formatAttachment(attachment1, attachment2) {
506
536
  spriteURI: blob.sprite_image, // @Legacy
507
537
  spriteURI2x: blob.sprite_image_2x // @Legacy
508
538
  };
539
+ case "MessageLocation":
540
+ var urlAttach = blob.story_attachment.url;
541
+ var mediaAttach = blob.story_attachment.media;
542
+
543
+ var u = querystring.parse(url.parse(urlAttach).query).u;
544
+ var where1 = querystring.parse(url.parse(u).query).where1;
545
+ var address = where1.split(", ");
546
+
547
+ var latitude;
548
+ var longitude;
549
+
550
+ try {
551
+ latitude = Number.parseFloat(address[0]);
552
+ longitude = Number.parseFloat(address[1]);
553
+ } catch (err) {
554
+ /* empty */
555
+ }
556
+
557
+ var imageUrl;
558
+ var width;
559
+ var height;
560
+
561
+ if (mediaAttach && mediaAttach.image) {
562
+ imageUrl = mediaAttach.image.uri;
563
+ width = mediaAttach.image.width;
564
+ height = mediaAttach.image.height;
565
+ }
566
+
567
+ return {
568
+ type: "location",
569
+ ID: blob.legacy_attachment_id,
570
+ latitude: latitude,
571
+ longitude: longitude,
572
+ image: imageUrl,
573
+ width: width,
574
+ height: height,
575
+ url: u || urlAttach,
576
+ address: where1,
577
+
578
+ facebookUrl: blob.story_attachment.url, // @Legacy
579
+ target: blob.story_attachment.target, // @Legacy
580
+ styleList: blob.story_attachment.style_list // @Legacy
581
+ };
509
582
  case "ExtensibleAttachment":
510
583
  return {
511
584
  type: "share",
@@ -544,7 +617,7 @@ function _formatAttachment(attachment1, attachment2) {
544
617
  : blob.story_attachment.media.playable_url,
545
618
 
546
619
  subattachments: blob.story_attachment.subattachments,
547
- properties: blob.story_attachment.properties.reduce(function(obj, cur) {
620
+ properties: blob.story_attachment.properties.reduce(function (obj, cur) {
548
621
  obj[cur.key] = cur.value.text;
549
622
  return obj;
550
623
  }, {}),
@@ -570,12 +643,12 @@ function _formatAttachment(attachment1, attachment2) {
570
643
  default:
571
644
  throw new Error(
572
645
  "unrecognized attach_file of type " +
573
- type +
574
- "`" +
575
- JSON.stringify(attachment1, null, 4) +
576
- " attachment2: " +
577
- JSON.stringify(attachment2, null, 4) +
578
- "`"
646
+ type +
647
+ "`" +
648
+ JSON.stringify(attachment1, null, 4) +
649
+ " attachment2: " +
650
+ JSON.stringify(attachment2, null, 4) +
651
+ "`"
579
652
  );
580
653
  }
581
654
  }
@@ -583,16 +656,16 @@ function _formatAttachment(attachment1, attachment2) {
583
656
  function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
584
657
  attachmentMap = shareMap || attachmentMap;
585
658
  return attachments
586
- ? attachments.map(function(val, i) {
587
- if (
588
- !attachmentMap ||
589
- !attachmentIds ||
590
- !attachmentMap[attachmentIds[i]]
591
- ) {
592
- return _formatAttachment(val);
593
- }
594
- return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
595
- })
659
+ ? attachments.map(function (val, i) {
660
+ if (
661
+ !attachmentMap ||
662
+ !attachmentIds ||
663
+ !attachmentMap[attachmentIds[i]]
664
+ ) {
665
+ return _formatAttachment(val);
666
+ }
667
+ return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
668
+ })
596
669
  : [];
597
670
  }
598
671
 
@@ -609,6 +682,8 @@ function formatDeltaMessage(m) {
609
682
  var m_offset = mdata.map(u => u.o);
610
683
  var m_length = mdata.map(u => u.l);
611
684
  var mentions = {};
685
+ var body = m.delta.body || "";
686
+ var args = body == "" ? [] : body.trim().split(/\s+/);
612
687
  for (var i = 0; i < m_id.length; i++) {
613
688
  mentions[m_id[i]] = m.delta.body.substring(
614
689
  m_offset[i],
@@ -619,15 +694,17 @@ function formatDeltaMessage(m) {
619
694
  return {
620
695
  type: "message",
621
696
  senderID: formatID(md.actorFbId.toString()),
622
- body: m.delta.body || "",
623
697
  threadID: formatID(
624
698
  (md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()
625
699
  ),
700
+ args: args,
701
+ body: body,
626
702
  messageID: md.messageId,
627
703
  attachments: (m.delta.attachments || []).map(v => _formatAttachment(v)),
628
704
  mentions: mentions,
629
705
  timestamp: md.timestamp,
630
- isGroup: !!md.threadKey.threadFbId
706
+ isGroup: !!md.threadKey.threadFbId,
707
+ participantIDs: m.delta.participants || []
631
708
  };
632
709
  }
633
710
 
@@ -649,9 +726,9 @@ function formatMessage(m) {
649
726
  ? originalMessage.group_thread_info.participant_names
650
727
  : [originalMessage.sender_name.split(" ")[0]],
651
728
  participantIDs: originalMessage.group_thread_info
652
- ? originalMessage.group_thread_info.participant_ids.map(function(v) {
653
- return formatID(v.toString());
654
- })
729
+ ? originalMessage.group_thread_info.participant_ids.map(function (v) {
730
+ return formatID(v.toString());
731
+ })
655
732
  : [formatID(originalMessage.sender_fbid)],
656
733
  body: originalMessage.body || "",
657
734
  threadID: formatID(
@@ -723,10 +800,20 @@ function getAdminTextMessageType(type) {
723
800
  switch (type) {
724
801
  case "change_thread_theme":
725
802
  return "log:thread-color";
803
+ // case "change_thread_icon": deprecated
804
+ case "change_thread_quick_reaction":
805
+ return "log:thread-icon";
726
806
  case "change_thread_nickname":
727
807
  return "log:user-nickname";
728
- case "change_thread_icon":
729
- return "log:thread-icon";
808
+ case "change_thread_admins":
809
+ return "log:thread-admins";
810
+ case "group_poll":
811
+ return "log:thread-poll";
812
+ case "change_thread_approval_mode":
813
+ return "log:thread-approval-mode";
814
+ case "messenger_call_log":
815
+ case "participant_joined_group_call":
816
+ return "log:thread-call";
730
817
  default:
731
818
  return type;
732
819
  }
@@ -745,8 +832,8 @@ function formatDeltaEvent(m) {
745
832
 
746
833
  switch (m.class) {
747
834
  case "AdminTextMessage":
748
- logMessageData = m.untypedData;
749
835
  logMessageType = getAdminTextMessageType(m.type);
836
+ logMessageData = m.untypedData;
750
837
  break;
751
838
  case "ThreadName":
752
839
  logMessageType = "log:thread-name";
@@ -773,7 +860,8 @@ function formatDeltaEvent(m) {
773
860
  logMessageType: logMessageType,
774
861
  logMessageData: logMessageData,
775
862
  logMessageBody: m.messageMetadata.adminText,
776
- author: m.messageMetadata.actorFbId
863
+ author: m.messageMetadata.actorFbId,
864
+ participantIDs: m.participants || []
777
865
  };
778
866
  }
779
867
 
@@ -862,17 +950,17 @@ function makeParsable(html) {
862
950
  function arrToForm(form) {
863
951
  return arrayToObject(
864
952
  form,
865
- function(v) {
953
+ function (v) {
866
954
  return v.name;
867
955
  },
868
- function(v) {
956
+ function (v) {
869
957
  return v.val;
870
958
  }
871
959
  );
872
960
  }
873
961
 
874
962
  function arrayToObject(arr, getKey, getValue) {
875
- return arr.reduce(function(acc, val) {
963
+ return arr.reduce(function (acc, val) {
876
964
  acc[getKey(val)] = getValue(val);
877
965
  return acc;
878
966
  }, {});
@@ -958,21 +1046,22 @@ function makeDefaults(html, userID, ctx) {
958
1046
  return newObj;
959
1047
  }
960
1048
 
961
- function postWithDefaults(url, jar, form) {
962
- return post(url, jar, mergeWithDefaults(form), ctx.globalOptions);
1049
+ function postWithDefaults(url, jar, form, ctxx) {
1050
+ return post(url, jar, mergeWithDefaults(form), ctx.globalOptions, ctxx || ctx);
963
1051
  }
964
1052
 
965
- function getWithDefaults(url, jar, qs) {
966
- return get(url, jar, mergeWithDefaults(qs), ctx.globalOptions);
1053
+ function getWithDefaults(url, jar, qs, ctxx) {
1054
+ return get(url, jar, mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx);
967
1055
  }
968
1056
 
969
- function postFormDataWithDefault(url, jar, form, qs) {
1057
+ function postFormDataWithDefault(url, jar, form, qs, ctxx) {
970
1058
  return postFormData(
971
1059
  url,
972
1060
  jar,
973
1061
  mergeWithDefaults(form),
974
1062
  mergeWithDefaults(qs),
975
- ctx.globalOptions
1063
+ ctx.globalOptions,
1064
+ ctxx || ctx
976
1065
  );
977
1066
  }
978
1067
 
@@ -987,8 +1076,8 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
987
1076
  if (retryCount == undefined) {
988
1077
  retryCount = 0;
989
1078
  }
990
- return function(data) {
991
- return bluebird.try(function() {
1079
+ return function (data) {
1080
+ return bluebird.try(function () {
992
1081
  log.verbose("parseAndCheckLogin", data.body);
993
1082
  if (data.statusCode >= 500 && data.statusCode < 600) {
994
1083
  if (retryCount >= 5) {
@@ -1004,12 +1093,12 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
1004
1093
  log.warn(
1005
1094
  "parseAndCheckLogin",
1006
1095
  "Got status code " +
1007
- data.statusCode +
1008
- " - " +
1009
- retryCount +
1010
- ". attempt to retry in " +
1011
- retryTime +
1012
- " milliseconds..."
1096
+ data.statusCode +
1097
+ " - " +
1098
+ retryCount +
1099
+ ". attempt to retry in " +
1100
+ retryTime +
1101
+ " milliseconds..."
1013
1102
  );
1014
1103
  var url =
1015
1104
  data.request.uri.protocol +
@@ -1022,7 +1111,7 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
1022
1111
  ) {
1023
1112
  return bluebird
1024
1113
  .delay(retryTime)
1025
- .then(function() {
1114
+ .then(function () {
1026
1115
  return defaultFuncs.postFormData(
1027
1116
  url,
1028
1117
  ctx.jar,
@@ -1034,7 +1123,7 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
1034
1123
  } else {
1035
1124
  return bluebird
1036
1125
  .delay(retryTime)
1037
- .then(function() {
1126
+ .then(function () {
1038
1127
  return defaultFuncs.post(url, ctx.jar, data.request.formData);
1039
1128
  })
1040
1129
  .then(parseAndCheckLogin(ctx, defaultFuncs, retryCount));
@@ -1043,8 +1132,8 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
1043
1132
  if (data.statusCode !== 200)
1044
1133
  throw new Error(
1045
1134
  "parseAndCheckLogin got status code: " +
1046
- data.statusCode +
1047
- ". Bailing out of trying to parse response."
1135
+ data.statusCode +
1136
+ ". Bailing out of trying to parse response."
1048
1137
  );
1049
1138
 
1050
1139
  var res = null;
@@ -1108,9 +1197,9 @@ function parseAndCheckLogin(ctx, defaultFuncs, retryCount) {
1108
1197
  }
1109
1198
 
1110
1199
  function saveCookies(jar) {
1111
- return function(res) {
1200
+ return function (res) {
1112
1201
  var cookies = res.headers["set-cookie"] || [];
1113
- cookies.forEach(function(c) {
1202
+ cookies.forEach(function (c) {
1114
1203
  if (c.indexOf(".facebook.com") > -1) {
1115
1204
  jar.setCookie(c, "https://www.facebook.com");
1116
1205
  }
@@ -1214,7 +1303,7 @@ function formatProxyPresence(presence, userID) {
1214
1303
  return {
1215
1304
  type: "presence",
1216
1305
  timestamp: presence.lat * 1000,
1217
- userID: userID,
1306
+ userID: userID || '',
1218
1307
  statuses: presence.p
1219
1308
  };
1220
1309
  }
@@ -1223,7 +1312,7 @@ function formatPresence(presence, userID) {
1223
1312
  return {
1224
1313
  type: "presence",
1225
1314
  timestamp: presence.la * 1000,
1226
- userID: userID,
1315
+ userID: userID || '',
1227
1316
  statuses: presence.a
1228
1317
  };
1229
1318
  }
@@ -1232,7 +1321,41 @@ function decodeClientPayload(payload) {
1232
1321
  /*
1233
1322
  Special function which Client using to "encode" clients JSON payload
1234
1323
  */
1235
- return JSON.parse(String.fromCharCode.apply(null, payload));
1324
+ function Utf8ArrayToStr(array) {
1325
+ var out, i, len, c;
1326
+ var char2, char3;
1327
+ out = "";
1328
+ len = array.length;
1329
+ i = 0;
1330
+ while (i < len) {
1331
+ c = array[i++];
1332
+ switch (c >> 4) {
1333
+ case 0:
1334
+ case 1:
1335
+ case 2:
1336
+ case 3:
1337
+ case 4:
1338
+ case 5:
1339
+ case 6:
1340
+ case 7:
1341
+ out += String.fromCharCode(c);
1342
+ break;
1343
+ case 12:
1344
+ case 13:
1345
+ char2 = array[i++];
1346
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
1347
+ break;
1348
+ case 14:
1349
+ char2 = array[i++];
1350
+ char3 = array[i++];
1351
+ out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
1352
+ break;
1353
+ }
1354
+ }
1355
+ return out;
1356
+ }
1357
+
1358
+ return JSON.parse(Utf8ArrayToStr(payload));
1236
1359
  }
1237
1360
 
1238
1361
  function getAppState(jar) {
@@ -1278,5 +1401,7 @@ module.exports = {
1278
1401
  formatDate,
1279
1402
  decodeClientPayload,
1280
1403
  getAppState,
1281
- getAdminTextMessageType
1282
- };
1404
+ getAdminTextMessageType,
1405
+ setProxy
1406
+ };
1407
+