whatsapp-web.js 1.21.0 → 1.21.1-alpha.1
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/example.js +39 -12
- package/index.d.ts +37 -0
- package/package.json +1 -1
- package/src/Client.js +134 -12
- package/src/authStrategies/LocalAuth.js +2 -2
- package/src/structures/Chat.js +10 -1
- package/src/structures/Contact.js +3 -1
- package/src/structures/GroupChat.js +3 -2
- package/src/structures/Message.js +49 -2
- package/src/util/Constants.js +1 -0
- package/src/util/Injected.js +89 -12
- package/.wwebjs_cache/2.2320.10.html +0 -2
- package/.wwebjs_cache/2.2322.15.html +0 -2
package/example.js
CHANGED
|
@@ -140,6 +140,12 @@ client.on('message', async msg => {
|
|
|
140
140
|
const attachmentData = await quotedMsg.downloadMedia();
|
|
141
141
|
client.sendMessage(msg.from, attachmentData, { caption: 'Here\'s your requested media.' });
|
|
142
142
|
}
|
|
143
|
+
} else if (msg.body === '!isviewonce' && msg.hasQuotedMsg) {
|
|
144
|
+
const quotedMsg = await msg.getQuotedMessage();
|
|
145
|
+
if (quotedMsg.hasMedia) {
|
|
146
|
+
const media = await quotedMsg.downloadMedia();
|
|
147
|
+
await client.sendMessage(msg.from, media, { isViewOnce: true });
|
|
148
|
+
}
|
|
143
149
|
} else if (msg.body === '!location') {
|
|
144
150
|
msg.reply(new Location(37.422, -122.084, 'Googleplex\nGoogle Headquarters'));
|
|
145
151
|
} else if (msg.location) {
|
|
@@ -201,6 +207,27 @@ client.on('message', async msg => {
|
|
|
201
207
|
client.sendMessage(msg.from, list);
|
|
202
208
|
} else if (msg.body === '!reaction') {
|
|
203
209
|
msg.react('👍');
|
|
210
|
+
} else if (msg.body === '!edit') {
|
|
211
|
+
if (msg.hasQuotedMsg) {
|
|
212
|
+
const quotedMsg = await msg.getQuotedMessage();
|
|
213
|
+
if (quotedMsg.fromMe) {
|
|
214
|
+
quotedMsg.edit(msg.body.replace('!edit', ''));
|
|
215
|
+
} else {
|
|
216
|
+
msg.reply('I can only edit my own messages');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
} else if (msg.body === '!updatelabels') {
|
|
220
|
+
const chat = await msg.getChat();
|
|
221
|
+
await chat.changeLabels([0, 1]);
|
|
222
|
+
} else if (msg.body === '!addlabels') {
|
|
223
|
+
const chat = await msg.getChat();
|
|
224
|
+
let labels = (await chat.getLabels()).map(l => l.id);
|
|
225
|
+
labels.push('0');
|
|
226
|
+
labels.push('1');
|
|
227
|
+
await chat.changeLabels(labels);
|
|
228
|
+
} else if (msg.body === '!removelabels') {
|
|
229
|
+
const chat = await msg.getChat();
|
|
230
|
+
await chat.changeLabels([]);
|
|
204
231
|
}
|
|
205
232
|
});
|
|
206
233
|
|
|
@@ -286,28 +313,28 @@ client.on('contact_changed', async (message, oldId, newId, isContact) => {
|
|
|
286
313
|
`Their new phone number is ${newId.slice(0, -5)}.\n`);
|
|
287
314
|
|
|
288
315
|
/**
|
|
289
|
-
* Information about the
|
|
316
|
+
* Information about the @param {message}:
|
|
290
317
|
*
|
|
291
318
|
* 1. If a notification was emitted due to a group participant changing their phone number:
|
|
292
|
-
*
|
|
293
|
-
*
|
|
319
|
+
* @param {message.author} is a participant's id before the change.
|
|
320
|
+
* @param {message.recipients[0]} is a participant's id after the change (a new one).
|
|
294
321
|
*
|
|
295
322
|
* 1.1 If the contact who changed their number WAS in the current user's contact list at the time of the change:
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
* Also the
|
|
323
|
+
* @param {message.to} is a group chat id the event was emitted in.
|
|
324
|
+
* @param {message.from} is a current user's id that got an notification message in the group.
|
|
325
|
+
* Also the @param {message.fromMe} is TRUE.
|
|
299
326
|
*
|
|
300
327
|
* 1.2 Otherwise:
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
* Also
|
|
328
|
+
* @param {message.from} is a group chat id the event was emitted in.
|
|
329
|
+
* @param {message.to} is @type {undefined}.
|
|
330
|
+
* Also @param {message.fromMe} is FALSE.
|
|
304
331
|
*
|
|
305
332
|
* 2. If a notification was emitted due to a contact changing their phone number:
|
|
306
|
-
*
|
|
333
|
+
* @param {message.templateParams} is an array of two user's ids:
|
|
307
334
|
* the old (before the change) and a new one, stored in alphabetical order.
|
|
308
|
-
*
|
|
335
|
+
* @param {message.from} is a current user's id that has a chat with a user,
|
|
309
336
|
* whos phone number was changed.
|
|
310
|
-
*
|
|
337
|
+
* @param {message.to} is a user's id (after the change), the current user has a chat with.
|
|
311
338
|
*/
|
|
312
339
|
});
|
|
313
340
|
|
package/index.d.ts
CHANGED
|
@@ -60,6 +60,9 @@ declare namespace WAWebJS {
|
|
|
60
60
|
/** Get contact instance by ID */
|
|
61
61
|
getContactById(contactId: string): Promise<Contact>
|
|
62
62
|
|
|
63
|
+
/** Get message by ID */
|
|
64
|
+
getMessageById(messageId: string): Promise<Message>
|
|
65
|
+
|
|
63
66
|
/** Get all current contact instances */
|
|
64
67
|
getContacts(): Promise<Contact[]>
|
|
65
68
|
|
|
@@ -71,6 +74,9 @@ declare namespace WAWebJS {
|
|
|
71
74
|
|
|
72
75
|
/** Get all current Labels */
|
|
73
76
|
getLabels(): Promise<Label[]>
|
|
77
|
+
|
|
78
|
+
/** Change labels in chats */
|
|
79
|
+
addOrRemoveLabels(labelIds: Array<number|string>, chatIds: Array<string>): Promise<void>
|
|
74
80
|
|
|
75
81
|
/** Get Label instance by ID */
|
|
76
82
|
getLabelById(labelId: string): Promise<Label>
|
|
@@ -242,6 +248,16 @@ declare namespace WAWebJS {
|
|
|
242
248
|
ack: MessageAck
|
|
243
249
|
) => void): this
|
|
244
250
|
|
|
251
|
+
/** Emitted when an ack event occurrs on message type */
|
|
252
|
+
on(event: 'message_edit', listener: (
|
|
253
|
+
/** The message that was affected */
|
|
254
|
+
message: Message,
|
|
255
|
+
/** New text message */
|
|
256
|
+
newBody: String,
|
|
257
|
+
/** Prev text message */
|
|
258
|
+
prevBody: String
|
|
259
|
+
) => void): this
|
|
260
|
+
|
|
245
261
|
/** Emitted when a chat unread count changes */
|
|
246
262
|
on(event: 'unread_count', listener: (
|
|
247
263
|
/** The chat that was affected */
|
|
@@ -567,6 +583,7 @@ declare namespace WAWebJS {
|
|
|
567
583
|
MESSAGE_REVOKED_EVERYONE = 'message_revoke_everyone',
|
|
568
584
|
MESSAGE_REVOKED_ME = 'message_revoke_me',
|
|
569
585
|
MESSAGE_ACK = 'message_ack',
|
|
586
|
+
MESSAGE_EDIT = 'message_edit',
|
|
570
587
|
MEDIA_UPLOADED = 'media_uploaded',
|
|
571
588
|
CONTACT_CHANGED = 'contact_changed',
|
|
572
589
|
GROUP_JOIN = 'group_join',
|
|
@@ -789,6 +806,10 @@ declare namespace WAWebJS {
|
|
|
789
806
|
businessOwnerJid?: string,
|
|
790
807
|
/** Product JID */
|
|
791
808
|
productId?: string,
|
|
809
|
+
/** Last edit time */
|
|
810
|
+
latestEditSenderTimestampMs?: number,
|
|
811
|
+
/** Last edit message author */
|
|
812
|
+
latestEditMsgKey?: MessageId,
|
|
792
813
|
/** Message buttons */
|
|
793
814
|
dynamicReplyButtons?: object,
|
|
794
815
|
/** Selected button ID */
|
|
@@ -846,6 +867,8 @@ declare namespace WAWebJS {
|
|
|
846
867
|
* Gets the reactions associated with the given message
|
|
847
868
|
*/
|
|
848
869
|
getReactions: () => Promise<ReactionList[]>,
|
|
870
|
+
/** Edits the current message */
|
|
871
|
+
edit: (content: MessageContent, options?: MessageEditOptions) => Promise<Message | null>,
|
|
849
872
|
}
|
|
850
873
|
|
|
851
874
|
/** ID that represents a message */
|
|
@@ -889,6 +912,8 @@ declare namespace WAWebJS {
|
|
|
889
912
|
sendMediaAsSticker?: boolean
|
|
890
913
|
/** Send media as document */
|
|
891
914
|
sendMediaAsDocument?: boolean
|
|
915
|
+
/** Send photo/video as a view once message */
|
|
916
|
+
isViewOnce?: boolean
|
|
892
917
|
/** Automatically parse vCards and send them as contacts */
|
|
893
918
|
parseVCards?: boolean
|
|
894
919
|
/** Image or videos caption */
|
|
@@ -911,6 +936,16 @@ declare namespace WAWebJS {
|
|
|
911
936
|
stickerCategories?: string[]
|
|
912
937
|
}
|
|
913
938
|
|
|
939
|
+
/** Options for editing a message */
|
|
940
|
+
export interface MessageEditOptions {
|
|
941
|
+
/** Show links preview. Has no effect on multi-device accounts. */
|
|
942
|
+
linkPreview?: boolean
|
|
943
|
+
/** Contacts that are being mentioned in the message */
|
|
944
|
+
mentions?: Contact[]
|
|
945
|
+
/** Extra options */
|
|
946
|
+
extra?: any
|
|
947
|
+
}
|
|
948
|
+
|
|
914
949
|
export interface MediaFromURLOptions {
|
|
915
950
|
client?: Client
|
|
916
951
|
filename?: string
|
|
@@ -1135,6 +1170,8 @@ declare namespace WAWebJS {
|
|
|
1135
1170
|
markUnread: () => Promise<void>
|
|
1136
1171
|
/** Returns array of all Labels assigned to this Chat */
|
|
1137
1172
|
getLabels: () => Promise<Label[]>
|
|
1173
|
+
/** Add or remove labels to this Chat */
|
|
1174
|
+
changeLabels: (labelIds: Array<string | number>) => Promise<void>
|
|
1138
1175
|
}
|
|
1139
1176
|
|
|
1140
1177
|
export interface MessageSearchOptions {
|
package/package.json
CHANGED
package/src/Client.js
CHANGED
|
@@ -238,9 +238,9 @@ class Client extends EventEmitter {
|
|
|
238
238
|
// Listens to qr token change
|
|
239
239
|
if (mut.type === 'attributes' && mut.attributeName === 'data-ref') {
|
|
240
240
|
window.qrChanged(mut.target.dataset.ref);
|
|
241
|
-
}
|
|
241
|
+
}
|
|
242
242
|
// Listens to retry button, when found, click it
|
|
243
|
-
if (mut.type === 'childList') {
|
|
243
|
+
else if (mut.type === 'childList') {
|
|
244
244
|
const retry_button = document.querySelector(selectors.QR_RETRY_BUTTON);
|
|
245
245
|
if (retry_button) retry_button.click();
|
|
246
246
|
}
|
|
@@ -275,6 +275,50 @@ class Client extends EventEmitter {
|
|
|
275
275
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
await page.evaluate(() => {
|
|
279
|
+
/**
|
|
280
|
+
* Helper function that compares between two WWeb versions. Its purpose is to help the developer to choose the correct code implementation depending on the comparison value and the WWeb version.
|
|
281
|
+
* @param {string} lOperand The left operand for the WWeb version string to compare with
|
|
282
|
+
* @param {string} operator The comparison operator
|
|
283
|
+
* @param {string} rOperand The right operand for the WWeb version string to compare with
|
|
284
|
+
* @returns {boolean} Boolean value that indicates the result of the comparison
|
|
285
|
+
*/
|
|
286
|
+
window.compareWwebVersions = (lOperand, operator, rOperand) => {
|
|
287
|
+
if (!['>', '>=', '<', '<=', '='].includes(operator)) {
|
|
288
|
+
throw class _ extends Error {
|
|
289
|
+
constructor(m) { super(m); this.name = 'CompareWwebVersionsError'; }
|
|
290
|
+
}('Invalid comparison operator is provided');
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
if (typeof lOperand !== 'string' || typeof rOperand !== 'string') {
|
|
294
|
+
throw class _ extends Error {
|
|
295
|
+
constructor(m) { super(m); this.name = 'CompareWwebVersionsError'; }
|
|
296
|
+
}('A non-string WWeb version type is provided');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
lOperand = lOperand.replace(/-beta$/, '');
|
|
300
|
+
rOperand = rOperand.replace(/-beta$/, '');
|
|
301
|
+
|
|
302
|
+
while (lOperand.length !== rOperand.length) {
|
|
303
|
+
lOperand.length > rOperand.length
|
|
304
|
+
? rOperand = rOperand.concat('0')
|
|
305
|
+
: lOperand = lOperand.concat('0');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
lOperand = Number(lOperand.replace(/\./g, ''));
|
|
309
|
+
rOperand = Number(rOperand.replace(/\./g, ''));
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
operator === '>' ? lOperand > rOperand :
|
|
313
|
+
operator === '>=' ? lOperand >= rOperand :
|
|
314
|
+
operator === '<' ? lOperand < rOperand :
|
|
315
|
+
operator === '<=' ? lOperand <= rOperand :
|
|
316
|
+
operator === '=' ? lOperand === rOperand :
|
|
317
|
+
false
|
|
318
|
+
);
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
|
|
278
322
|
await page.evaluate(ExposeStore, moduleRaid.toString());
|
|
279
323
|
const authEventPayload = await this.authStrategy.getAuthEventPayload();
|
|
280
324
|
|
|
@@ -314,7 +358,7 @@ class Client extends EventEmitter {
|
|
|
314
358
|
await page.exposeFunction('onAddMessageEvent', msg => {
|
|
315
359
|
if (msg.type === 'gp2') {
|
|
316
360
|
const notification = new GroupNotification(this, msg);
|
|
317
|
-
if (
|
|
361
|
+
if (['add', 'invite', 'linked_group_join'].includes(msg.subtype)) {
|
|
318
362
|
/**
|
|
319
363
|
* Emitted when a user joins the chat via invite link or is added by an admin.
|
|
320
364
|
* @event Client#group_join
|
|
@@ -396,18 +440,18 @@ class Client extends EventEmitter {
|
|
|
396
440
|
|
|
397
441
|
/**
|
|
398
442
|
* The event notification that is received when one of
|
|
399
|
-
* the group participants changes
|
|
443
|
+
* the group participants changes their phone number.
|
|
400
444
|
*/
|
|
401
445
|
const isParticipant = msg.type === 'gp2' && msg.subtype === 'modify';
|
|
402
446
|
|
|
403
447
|
/**
|
|
404
448
|
* The event notification that is received when one of
|
|
405
|
-
* the contacts changes
|
|
449
|
+
* the contacts changes their phone number.
|
|
406
450
|
*/
|
|
407
451
|
const isContact = msg.type === 'notification_template' && msg.subtype === 'change_number';
|
|
408
452
|
|
|
409
453
|
if (isParticipant || isContact) {
|
|
410
|
-
/**
|
|
454
|
+
/** @type {GroupNotification} object does not provide enough information about this event, so a @type {Message} object is used. */
|
|
411
455
|
const message = new Message(this, msg);
|
|
412
456
|
|
|
413
457
|
const newId = isParticipant ? msg.recipients[0] : msg.to;
|
|
@@ -584,12 +628,28 @@ class Client extends EventEmitter {
|
|
|
584
628
|
this.emit(Events.CHAT_ARCHIVED, new Chat(this, chat), currState, prevState);
|
|
585
629
|
});
|
|
586
630
|
|
|
631
|
+
await page.exposeFunction('onEditMessageEvent', (msg, newBody, prevBody) => {
|
|
632
|
+
|
|
633
|
+
if(msg.type === 'revoked'){
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Emitted when messages are edited
|
|
638
|
+
* @event Client#message_edit
|
|
639
|
+
* @param {Message} message
|
|
640
|
+
* @param {string} newBody
|
|
641
|
+
* @param {string} prevBody
|
|
642
|
+
*/
|
|
643
|
+
this.emit(Events.MESSAGE_EDIT, new Message(this, msg), newBody, prevBody);
|
|
644
|
+
});
|
|
645
|
+
|
|
587
646
|
await page.evaluate(() => {
|
|
588
647
|
window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
|
|
589
648
|
window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
|
|
590
649
|
window.Store.Msg.on('change:ack', (msg, ack) => { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); });
|
|
591
650
|
window.Store.Msg.on('change:isUnsentMedia', (msg, unsent) => { if (msg.id.fromMe && !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); });
|
|
592
651
|
window.Store.Msg.on('remove', (msg) => { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); });
|
|
652
|
+
window.Store.Msg.on('change:body', (msg, newBody, prevBody) => { window.onEditMessageEvent(window.WWebJS.getMessageModel(msg), newBody, prevBody); });
|
|
593
653
|
window.Store.AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); });
|
|
594
654
|
window.Store.Conn.on('change:battery', (state) => { window.onBatteryStateChangedEvent(state); });
|
|
595
655
|
window.Store.Call.on('add', (call) => { window.onIncomingCall(call); });
|
|
@@ -686,7 +746,14 @@ class Client extends EventEmitter {
|
|
|
686
746
|
await this.pupPage.evaluate(() => {
|
|
687
747
|
return window.Store.AppState.logout();
|
|
688
748
|
});
|
|
689
|
-
|
|
749
|
+
await this.pupBrowser.close();
|
|
750
|
+
|
|
751
|
+
let maxDelay = 0;
|
|
752
|
+
while (this.pupBrowser.isConnected() && (maxDelay < 10)) { // waits a maximum of 1 second before calling the AuthStrategy
|
|
753
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
754
|
+
maxDelay++;
|
|
755
|
+
}
|
|
756
|
+
|
|
690
757
|
await this.authStrategy.logout();
|
|
691
758
|
}
|
|
692
759
|
|
|
@@ -722,6 +789,7 @@ class Client extends EventEmitter {
|
|
|
722
789
|
* @property {boolean} [sendVideoAsGif=false] - Send video as gif
|
|
723
790
|
* @property {boolean} [sendMediaAsSticker=false] - Send media as a sticker
|
|
724
791
|
* @property {boolean} [sendMediaAsDocument=false] - Send media as a document
|
|
792
|
+
* @property {boolean} [isViewOnce=false] - Send photo/video as a view once message
|
|
725
793
|
* @property {boolean} [parseVCards=true] - Automatically parse vCards and send them as contacts
|
|
726
794
|
* @property {string} [caption] - Image or video caption
|
|
727
795
|
* @property {string} [quotedMessageId] - Id of the message that is being quoted (or replied to)
|
|
@@ -732,7 +800,7 @@ class Client extends EventEmitter {
|
|
|
732
800
|
* @property {string[]} [stickerCategories=undefined] - Sets the categories of the sticker, (if sendMediaAsSticker is true). Provide emoji char array, can be null.
|
|
733
801
|
* @property {MessageMedia} [media] - Media to be sent
|
|
734
802
|
*/
|
|
735
|
-
|
|
803
|
+
|
|
736
804
|
/**
|
|
737
805
|
* Send a message to a specific chatId
|
|
738
806
|
* @param {string} chatId
|
|
@@ -742,6 +810,10 @@ class Client extends EventEmitter {
|
|
|
742
810
|
* @returns {Promise<Message>} Message that was just sent
|
|
743
811
|
*/
|
|
744
812
|
async sendMessage(chatId, content, options = {}) {
|
|
813
|
+
if (options.mentions && options.mentions.some(possiblyContact => possiblyContact instanceof Contact)) {
|
|
814
|
+
console.warn('Mentions with an array of Contact are now deprecated. See more at https://github.com/pedroslopez/whatsapp-web.js/pull/2166.');
|
|
815
|
+
options.mentions = options.mentions.map(a => a.id._serialized);
|
|
816
|
+
}
|
|
745
817
|
let internalOptions = {
|
|
746
818
|
linkPreview: options.linkPreview === false ? undefined : true,
|
|
747
819
|
sendAudioAsVoice: options.sendAudioAsVoice,
|
|
@@ -751,7 +823,7 @@ class Client extends EventEmitter {
|
|
|
751
823
|
caption: options.caption,
|
|
752
824
|
quotedMessageId: options.quotedMessageId,
|
|
753
825
|
parseVCards: options.parseVCards === false ? false : true,
|
|
754
|
-
mentionedJidList: Array.isArray(options.mentions) ? options.mentions
|
|
826
|
+
mentionedJidList: Array.isArray(options.mentions) ? options.mentions : [],
|
|
755
827
|
extraOptions: options.extra
|
|
756
828
|
};
|
|
757
829
|
|
|
@@ -759,10 +831,12 @@ class Client extends EventEmitter {
|
|
|
759
831
|
|
|
760
832
|
if (content instanceof MessageMedia) {
|
|
761
833
|
internalOptions.attachment = content;
|
|
834
|
+
internalOptions.isViewOnce = options.isViewOnce,
|
|
762
835
|
content = '';
|
|
763
836
|
} else if (options.media instanceof MessageMedia) {
|
|
764
837
|
internalOptions.attachment = options.media;
|
|
765
838
|
internalOptions.caption = content;
|
|
839
|
+
internalOptions.isViewOnce = options.isViewOnce,
|
|
766
840
|
content = '';
|
|
767
841
|
} else if (content instanceof Location) {
|
|
768
842
|
internalOptions.location = content;
|
|
@@ -781,7 +855,7 @@ class Client extends EventEmitter {
|
|
|
781
855
|
internalOptions.list = content;
|
|
782
856
|
content = '';
|
|
783
857
|
}
|
|
784
|
-
|
|
858
|
+
|
|
785
859
|
if (internalOptions.sendMediaAsSticker && internalOptions.attachment) {
|
|
786
860
|
internalOptions.attachment = await Util.formatToWebpSticker(
|
|
787
861
|
internalOptions.attachment, {
|
|
@@ -807,7 +881,7 @@ class Client extends EventEmitter {
|
|
|
807
881
|
|
|
808
882
|
return new Message(this, newMessage);
|
|
809
883
|
}
|
|
810
|
-
|
|
884
|
+
|
|
811
885
|
/**
|
|
812
886
|
* Searches for messages
|
|
813
887
|
* @param {string} query
|
|
@@ -875,6 +949,24 @@ class Client extends EventEmitter {
|
|
|
875
949
|
|
|
876
950
|
return ContactFactory.create(this, contact);
|
|
877
951
|
}
|
|
952
|
+
|
|
953
|
+
async getMessageById(messageId) {
|
|
954
|
+
const msg = await this.pupPage.evaluate(async messageId => {
|
|
955
|
+
let msg = window.Store.Msg.get(messageId);
|
|
956
|
+
if(msg) return window.WWebJS.getMessageModel(msg);
|
|
957
|
+
|
|
958
|
+
const params = messageId.split('_');
|
|
959
|
+
if(params.length !== 3) throw new Error('Invalid serialized message id specified');
|
|
960
|
+
|
|
961
|
+
let messagesObject = await window.Store.Msg.getMessagesById([messageId]);
|
|
962
|
+
if (messagesObject && messagesObject.messages.length) msg = messagesObject.messages[0];
|
|
963
|
+
|
|
964
|
+
if(msg) return window.WWebJS.getMessageModel(msg);
|
|
965
|
+
}, messageId);
|
|
966
|
+
|
|
967
|
+
if(msg) return new Message(this, msg);
|
|
968
|
+
return null;
|
|
969
|
+
}
|
|
878
970
|
|
|
879
971
|
/**
|
|
880
972
|
* Returns an object with information about the invite code's group
|
|
@@ -910,7 +1002,8 @@ class Client extends EventEmitter {
|
|
|
910
1002
|
if (inviteInfo.inviteCodeExp == 0) throw 'Expired invite code';
|
|
911
1003
|
return this.pupPage.evaluate(async inviteInfo => {
|
|
912
1004
|
let { groupId, fromId, inviteCode, inviteCodeExp } = inviteInfo;
|
|
913
|
-
|
|
1005
|
+
let userWid = window.Store.WidFactory.createWid(fromId);
|
|
1006
|
+
return await window.Store.JoinInviteV4.joinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, userWid);
|
|
914
1007
|
}, inviteInfo);
|
|
915
1008
|
}
|
|
916
1009
|
|
|
@@ -1312,6 +1405,35 @@ class Client extends EventEmitter {
|
|
|
1312
1405
|
|
|
1313
1406
|
return success;
|
|
1314
1407
|
}
|
|
1408
|
+
|
|
1409
|
+
/**
|
|
1410
|
+
* Change labels in chats
|
|
1411
|
+
* @param {Array<number|string>} labelIds
|
|
1412
|
+
* @param {Array<string>} chatIds
|
|
1413
|
+
* @returns {Promise<void>}
|
|
1414
|
+
*/
|
|
1415
|
+
async addOrRemoveLabels(labelIds, chatIds) {
|
|
1416
|
+
|
|
1417
|
+
return this.pupPage.evaluate(async (labelIds, chatIds) => {
|
|
1418
|
+
if (['smba', 'smbi'].indexOf(window.Store.Conn.platform) === -1) {
|
|
1419
|
+
throw '[LT01] Only Whatsapp business';
|
|
1420
|
+
}
|
|
1421
|
+
const labels = window.WWebJS.getLabels().filter(e => labelIds.find(l => l == e.id) !== undefined);
|
|
1422
|
+
const chats = window.Store.Chat.filter(e => chatIds.includes(e.id._serialized));
|
|
1423
|
+
|
|
1424
|
+
let actions = labels.map(label => ({id: label.id, type: 'add'}));
|
|
1425
|
+
|
|
1426
|
+
chats.forEach(chat => {
|
|
1427
|
+
(chat.labels || []).forEach(n => {
|
|
1428
|
+
if (!actions.find(e => e.id == n)) {
|
|
1429
|
+
actions.push({id: n, type: 'remove'});
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
return await window.Store.Label.addOrRemoveLabels(actions, chats);
|
|
1435
|
+
}, labelIds, chatIds);
|
|
1436
|
+
}
|
|
1315
1437
|
}
|
|
1316
1438
|
|
|
1317
1439
|
module.exports = Client;
|
|
@@ -44,10 +44,10 @@ class LocalAuth extends BaseAuthStrategy {
|
|
|
44
44
|
|
|
45
45
|
async logout() {
|
|
46
46
|
if (this.userDataDir) {
|
|
47
|
-
return (fs.rmSync ? fs.rmSync : fs.rmdirSync).call(this, this.userDataDir, { recursive: true });
|
|
47
|
+
return (fs.rmSync ? fs.rmSync : fs.rmdirSync).call(this, this.userDataDir, { recursive: true, force: true });
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
module.exports = LocalAuth;
|
|
53
|
+
module.exports = LocalAuth;
|
package/src/structures/Chat.js
CHANGED
|
@@ -187,7 +187,7 @@ class Chat extends Base {
|
|
|
187
187
|
if (m.isNotification) {
|
|
188
188
|
return false; // dont include notification messages
|
|
189
189
|
}
|
|
190
|
-
if (searchOptions && searchOptions.fromMe && m.id.fromMe !== searchOptions.fromMe) {
|
|
190
|
+
if (searchOptions && searchOptions.fromMe !== undefined && m.id.fromMe !== searchOptions.fromMe) {
|
|
191
191
|
return false;
|
|
192
192
|
}
|
|
193
193
|
return true;
|
|
@@ -261,6 +261,15 @@ class Chat extends Base {
|
|
|
261
261
|
async getLabels() {
|
|
262
262
|
return this.client.getChatLabels(this.id._serialized);
|
|
263
263
|
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Add or remove labels to this Chat
|
|
267
|
+
* @param {Array<number|string>} labelIds
|
|
268
|
+
* @returns {Promise<void>}
|
|
269
|
+
*/
|
|
270
|
+
async changeLabels(labelIds) {
|
|
271
|
+
return this.client.addOrRemoveLabels(labelIds, [this.id._serialized]);
|
|
272
|
+
}
|
|
264
273
|
}
|
|
265
274
|
|
|
266
275
|
module.exports = Chat;
|
|
@@ -156,9 +156,10 @@ class Contact extends Base {
|
|
|
156
156
|
|
|
157
157
|
await this.client.pupPage.evaluate(async (contactId) => {
|
|
158
158
|
const contact = window.Store.Contact.get(contactId);
|
|
159
|
-
await window.Store.BlockContact.blockContact(contact);
|
|
159
|
+
await window.Store.BlockContact.blockContact({contact});
|
|
160
160
|
}, this.id._serialized);
|
|
161
161
|
|
|
162
|
+
this.isBlocked = true;
|
|
162
163
|
return true;
|
|
163
164
|
}
|
|
164
165
|
|
|
@@ -174,6 +175,7 @@ class Contact extends Base {
|
|
|
174
175
|
await window.Store.BlockContact.unblockContact(contact);
|
|
175
176
|
}, this.id._serialized);
|
|
176
177
|
|
|
178
|
+
this.isBlocked = false;
|
|
177
179
|
return true;
|
|
178
180
|
}
|
|
179
181
|
|
|
@@ -153,8 +153,9 @@ class GroupChat extends Chat {
|
|
|
153
153
|
const success = await this.client.pupPage.evaluate(async (chatId, description) => {
|
|
154
154
|
const chatWid = window.Store.WidFactory.createWid(chatId);
|
|
155
155
|
let descId = window.Store.GroupMetadata.get(chatWid).descId;
|
|
156
|
+
let newId = await window.Store.MsgKey.newId();
|
|
156
157
|
try {
|
|
157
|
-
await window.Store.GroupUtils.setGroupDescription(chatWid, description,
|
|
158
|
+
await window.Store.GroupUtils.setGroupDescription(chatWid, description, newId, descId);
|
|
158
159
|
return true;
|
|
159
160
|
} catch (err) {
|
|
160
161
|
if(err.name === 'ServerStatusCodeError') return false;
|
|
@@ -278,4 +279,4 @@ class GroupChat extends Chat {
|
|
|
278
279
|
|
|
279
280
|
}
|
|
280
281
|
|
|
281
|
-
module.exports = GroupChat;
|
|
282
|
+
module.exports = GroupChat;
|
|
@@ -7,6 +7,7 @@ const Order = require('./Order');
|
|
|
7
7
|
const Payment = require('./Payment');
|
|
8
8
|
const Reaction = require('./Reaction');
|
|
9
9
|
const {MessageTypes} = require('../util/Constants');
|
|
10
|
+
const {Contact} = require('./Contact');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Represents a Message on WhatsApp
|
|
@@ -167,8 +168,8 @@ class Message extends Base {
|
|
|
167
168
|
inviteCodeExp: data.inviteCodeExp,
|
|
168
169
|
groupId: data.inviteGrp,
|
|
169
170
|
groupName: data.inviteGrpName,
|
|
170
|
-
fromId: data.from._serialized,
|
|
171
|
-
toId: data.to._serialized
|
|
171
|
+
fromId: data.from?._serialized ? data.from._serialized : data.from,
|
|
172
|
+
toId: data.to?._serialized ? data.to._serialized : data.to
|
|
172
173
|
} : undefined;
|
|
173
174
|
|
|
174
175
|
/**
|
|
@@ -224,6 +225,16 @@ class Message extends Base {
|
|
|
224
225
|
this.productId = data.productId;
|
|
225
226
|
}
|
|
226
227
|
|
|
228
|
+
/** Last edit time */
|
|
229
|
+
if (data.latestEditSenderTimestampMs) {
|
|
230
|
+
this.latestEditSenderTimestampMs = data.latestEditSenderTimestampMs;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** Last edit message author */
|
|
234
|
+
if (data.latestEditMsgKey) {
|
|
235
|
+
this.latestEditMsgKey = data.latestEditMsgKey;
|
|
236
|
+
}
|
|
237
|
+
|
|
227
238
|
/**
|
|
228
239
|
* Links included in the message.
|
|
229
240
|
* @type {Array<{link: string, isSuspicious: boolean}>}
|
|
@@ -576,6 +587,42 @@ class Message extends Base {
|
|
|
576
587
|
return reaction;
|
|
577
588
|
});
|
|
578
589
|
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Edits the current message.
|
|
593
|
+
* @param {string} content
|
|
594
|
+
* @param {MessageEditOptions} [options] - Options used when editing the message
|
|
595
|
+
* @returns {Promise<?Message>}
|
|
596
|
+
*/
|
|
597
|
+
async edit(content, options = {}) {
|
|
598
|
+
if (options.mentions && options.mentions.some(possiblyContact => possiblyContact instanceof Contact)) {
|
|
599
|
+
options.mentions = options.mentions.map(a => a.id._serialized);
|
|
600
|
+
}
|
|
601
|
+
let internalOptions = {
|
|
602
|
+
linkPreview: options.linkPreview === false ? undefined : true,
|
|
603
|
+
mentionedJidList: Array.isArray(options.mentions) ? options.mentions : [],
|
|
604
|
+
extraOptions: options.extra
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
if (!this.fromMe) {
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
const messageEdit = await this.client.pupPage.evaluate(async (msgId, message, options) => {
|
|
611
|
+
let msg = window.Store.Msg.get(msgId);
|
|
612
|
+
if (!msg) return null;
|
|
613
|
+
|
|
614
|
+
let catEdit = (msg.type === 'chat' && window.Store.MsgActionChecks.canEditText(msg));
|
|
615
|
+
if (catEdit) {
|
|
616
|
+
const msgEdit = await window.WWebJS.editMessage(msg, message, options);
|
|
617
|
+
return msgEdit.serialize();
|
|
618
|
+
}
|
|
619
|
+
return null;
|
|
620
|
+
}, this.id._serialized, content, internalOptions);
|
|
621
|
+
if (messageEdit) {
|
|
622
|
+
return new Message(this.client, messageEdit);
|
|
623
|
+
}
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
579
626
|
}
|
|
580
627
|
|
|
581
628
|
module.exports = Message;
|
package/src/util/Constants.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.Events = {
|
|
|
48
48
|
MESSAGE_REVOKED_EVERYONE: 'message_revoke_everyone',
|
|
49
49
|
MESSAGE_REVOKED_ME: 'message_revoke_me',
|
|
50
50
|
MESSAGE_ACK: 'message_ack',
|
|
51
|
+
MESSAGE_EDIT: 'message_edit',
|
|
51
52
|
UNREAD_COUNT: 'unread_count',
|
|
52
53
|
MESSAGE_REACTION: 'message_reaction',
|
|
53
54
|
MEDIA_UPLOADED: 'media_uploaded',
|
package/src/util/Injected.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
9
9
|
window.Store.AppState = window.mR.findModule('Socket')[0].Socket;
|
|
10
10
|
window.Store.Conn = window.mR.findModule('Conn')[0].Conn;
|
|
11
11
|
window.Store.BlockContact = window.mR.findModule('blockContact')[0];
|
|
12
|
-
window.Store.Call = window.mR.findModule(
|
|
12
|
+
window.Store.Call = window.mR.findModule((module) => module.default && module.default.Call)[0].default.Call;
|
|
13
13
|
window.Store.Cmd = window.mR.findModule('Cmd')[0].Cmd;
|
|
14
14
|
window.Store.CryptoLib = window.mR.findModule('decryptE2EMedia')[0];
|
|
15
15
|
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
|
|
@@ -31,8 +31,11 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
31
31
|
window.Store.SendClear = window.mR.findModule('sendClear')[0];
|
|
32
32
|
window.Store.SendDelete = window.mR.findModule('sendDelete')[0];
|
|
33
33
|
window.Store.SendMessage = window.mR.findModule('addAndSendMsgToChat')[0];
|
|
34
|
+
window.Store.EditMessage = window.mR.findModule('addAndSendMessageEdit')[0];
|
|
34
35
|
window.Store.SendSeen = window.mR.findModule('sendSeen')[0];
|
|
35
36
|
window.Store.User = window.mR.findModule('getMaybeMeUser')[0];
|
|
37
|
+
window.Store.ContactMethods = window.mR.findModule('getUserid')[0];
|
|
38
|
+
window.Store.BusinessProfileCollection = window.mR.findModule('BusinessProfileCollection')[0].BusinessProfileCollection;
|
|
36
39
|
window.Store.UploadUtils = window.mR.findModule((module) => (module.default && module.default.encryptAndUpload) ? module.default : null)[0].default;
|
|
37
40
|
window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default;
|
|
38
41
|
window.Store.Validators = window.mR.findModule('findLinks')[0];
|
|
@@ -42,7 +45,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
42
45
|
window.Store.PresenceUtils = window.mR.findModule('sendPresenceAvailable')[0];
|
|
43
46
|
window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0];
|
|
44
47
|
window.Store.GroupParticipants = window.mR.findModule('promoteParticipants')[0];
|
|
45
|
-
window.Store.JoinInviteV4 = window.mR.findModule('
|
|
48
|
+
window.Store.JoinInviteV4 = window.mR.findModule('queryGroupInviteV4')[0];
|
|
46
49
|
window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups;
|
|
47
50
|
window.Store.StatusUtils = window.mR.findModule('setMyStatus')[0];
|
|
48
51
|
window.Store.ConversationMsgs = window.mR.findModule('loadEarlierMsgs')[0];
|
|
@@ -124,6 +127,7 @@ exports.LoadUtils = () => {
|
|
|
124
127
|
attOptions.caption = options.caption;
|
|
125
128
|
}
|
|
126
129
|
content = options.sendMediaAsSticker ? undefined : attOptions.preview;
|
|
130
|
+
attOptions.isViewOnce = options.isViewOnce;
|
|
127
131
|
|
|
128
132
|
delete options.attachment;
|
|
129
133
|
delete options.sendMediaAsSticker;
|
|
@@ -229,8 +233,8 @@ exports.LoadUtils = () => {
|
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
let listOptions = {};
|
|
232
|
-
if(options.list){
|
|
233
|
-
if(window.Store.Conn.platform === 'smba' || window.Store.Conn.platform === 'smbi'){
|
|
236
|
+
if (options.list) {
|
|
237
|
+
if (window.Store.Conn.platform === 'smba' || window.Store.Conn.platform === 'smbi') {
|
|
234
238
|
throw '[LT01] Whatsapp business can\'t send this yet';
|
|
235
239
|
}
|
|
236
240
|
listOptions = {
|
|
@@ -289,6 +293,40 @@ exports.LoadUtils = () => {
|
|
|
289
293
|
await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
|
|
290
294
|
return window.Store.Msg.get(newMsgId._serialized);
|
|
291
295
|
};
|
|
296
|
+
|
|
297
|
+
window.WWebJS.editMessage = async (msg, content, options = {}) => {
|
|
298
|
+
|
|
299
|
+
const extraOptions = options.extraOptions || {};
|
|
300
|
+
delete options.extraOptions;
|
|
301
|
+
|
|
302
|
+
if (options.mentionedJidList) {
|
|
303
|
+
options.mentionedJidList = options.mentionedJidList.map(cId => window.Store.Contact.get(cId).id);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (options.linkPreview) {
|
|
307
|
+
options.linkPreview = null;
|
|
308
|
+
|
|
309
|
+
// Not supported yet by WhatsApp Web on MD
|
|
310
|
+
if(!window.Store.MDBackend) {
|
|
311
|
+
const link = window.Store.Validators.findLink(content);
|
|
312
|
+
if (link) {
|
|
313
|
+
const preview = await window.Store.Wap.queryLinkPreview(link.url);
|
|
314
|
+
preview.preview = true;
|
|
315
|
+
preview.subtype = 'url';
|
|
316
|
+
options = { ...options, ...preview };
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
const internalOptions = {
|
|
323
|
+
...options,
|
|
324
|
+
...extraOptions
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
await window.Store.EditMessage.sendMessageEdit(msg, content, internalOptions);
|
|
328
|
+
return window.Store.Msg.get(msg.id._serialized);
|
|
329
|
+
};
|
|
292
330
|
|
|
293
331
|
window.WWebJS.toStickerData = async (mediaInfo) => {
|
|
294
332
|
if (mediaInfo.mimetype == 'image/webp') return mediaInfo;
|
|
@@ -437,7 +475,7 @@ exports.LoadUtils = () => {
|
|
|
437
475
|
|
|
438
476
|
res.lastMessage = null;
|
|
439
477
|
if (res.msgs && res.msgs.length) {
|
|
440
|
-
const lastMessage = window.Store.Msg.get(chat.lastReceivedKey._serialized);
|
|
478
|
+
const lastMessage = chat.lastReceivedKey ? window.Store.Msg.get(chat.lastReceivedKey._serialized) : null;
|
|
441
479
|
if (lastMessage) {
|
|
442
480
|
res.lastMessage = window.WWebJS.getMessageModel(lastMessage);
|
|
443
481
|
}
|
|
@@ -465,19 +503,56 @@ exports.LoadUtils = () => {
|
|
|
465
503
|
|
|
466
504
|
window.WWebJS.getContactModel = contact => {
|
|
467
505
|
let res = contact.serialize();
|
|
468
|
-
res.isBusiness = contact.isBusiness;
|
|
506
|
+
res.isBusiness = contact.isBusiness === undefined ? false : contact.isBusiness;
|
|
469
507
|
|
|
470
508
|
if (contact.businessProfile) {
|
|
471
509
|
res.businessProfile = contact.businessProfile.serialize();
|
|
472
510
|
}
|
|
473
511
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
res.
|
|
512
|
+
// TODO: remove useOldImplementation and its checks once all clients are updated to >= v2.2327.4
|
|
513
|
+
const useOldImplementation
|
|
514
|
+
= window.compareWwebVersions(window.Debug.VERSION, '<', '2.2327.4');
|
|
515
|
+
|
|
516
|
+
res.isMe = useOldImplementation
|
|
517
|
+
? contact.isMe
|
|
518
|
+
: window.Store.ContactMethods.getIsMe(contact);
|
|
519
|
+
res.isUser = useOldImplementation
|
|
520
|
+
? contact.isUser
|
|
521
|
+
: window.Store.ContactMethods.getIsUser(contact);
|
|
522
|
+
res.isGroup = useOldImplementation
|
|
523
|
+
? contact.isGroup
|
|
524
|
+
: window.Store.ContactMethods.getIsGroup(contact);
|
|
525
|
+
res.isWAContact = useOldImplementation
|
|
526
|
+
? contact.isWAContact
|
|
527
|
+
: window.Store.ContactMethods.getIsWAContact(contact);
|
|
528
|
+
res.isMyContact = useOldImplementation
|
|
529
|
+
? contact.isMyContact
|
|
530
|
+
: window.Store.ContactMethods.getIsMyContact(contact);
|
|
479
531
|
res.isBlocked = contact.isContactBlocked;
|
|
480
|
-
res.userid =
|
|
532
|
+
res.userid = useOldImplementation
|
|
533
|
+
? contact.userid
|
|
534
|
+
: window.Store.ContactMethods.getUserid(contact);
|
|
535
|
+
res.isEnterprise = useOldImplementation
|
|
536
|
+
? contact.isEnterprise
|
|
537
|
+
: window.Store.ContactMethods.getIsEnterprise(contact);
|
|
538
|
+
res.verifiedName = useOldImplementation
|
|
539
|
+
? contact.verifiedName
|
|
540
|
+
: window.Store.ContactMethods.getVerifiedName(contact);
|
|
541
|
+
res.verifiedLevel = useOldImplementation
|
|
542
|
+
? contact.verifiedLevel
|
|
543
|
+
: window.Store.ContactMethods.getVerifiedLevel(contact);
|
|
544
|
+
res.statusMute = useOldImplementation
|
|
545
|
+
? contact.statusMute
|
|
546
|
+
: window.Store.ContactMethods.getStatusMute(contact);
|
|
547
|
+
res.name = useOldImplementation
|
|
548
|
+
? contact.name
|
|
549
|
+
: window.Store.ContactMethods.getName(contact);
|
|
550
|
+
res.shortName = useOldImplementation
|
|
551
|
+
? contact.shortName
|
|
552
|
+
: window.Store.ContactMethods.getShortName(contact);
|
|
553
|
+
res.pushname = useOldImplementation
|
|
554
|
+
? contact.pushname
|
|
555
|
+
: window.Store.ContactMethods.getPushname(contact);
|
|
481
556
|
|
|
482
557
|
return res;
|
|
483
558
|
};
|
|
@@ -485,6 +560,8 @@ exports.LoadUtils = () => {
|
|
|
485
560
|
window.WWebJS.getContact = async contactId => {
|
|
486
561
|
const wid = window.Store.WidFactory.createWid(contactId);
|
|
487
562
|
const contact = await window.Store.Contact.find(wid);
|
|
563
|
+
const bizProfile = await window.Store.BusinessProfileCollection.fetchBizProfile(wid);
|
|
564
|
+
bizProfile.profileOptions && (contact.businessProfile = bizProfile);
|
|
488
565
|
return window.WWebJS.getContactModel(contact);
|
|
489
566
|
};
|
|
490
567
|
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="no-js" dir="ltr" loc="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>WhatsApp Web</title><meta name="viewport" content="width=device-width"><meta name="google" content="notranslate"><meta name="format-detection" content="telephone=no"><meta name="description" content="Quickly send and receive WhatsApp messages right from your computer."><meta name="og:description" content="Quickly send and receive WhatsApp messages right from your computer."><meta name="og:url" content="https://web.whatsapp.com/"><meta name="og:title" content="WhatsApp Web"><meta name="og:image" content="https://static.facebook.com/images/whatsapp/www/whatsapp-promo.png"><link id="favicon" rel="shortcut icon" href="/img/favicon/1x/favicon.png" type="image/png"><link rel="apple-touch-icon" sizes="194x194" href="/apple-touch-icon.png" type="image/png"><meta name="theme-color" content="#111b21" media="(prefers-color-scheme: dark)"><meta name="theme-color" content="#f0f2f5"><link id="whatsapp-pwa-manifest-link" rel="manifest" href="/manifest.json" crossorigin="use-credentials"><style>#initial_startup{--startup-background:#f0f2f5;--startup-background-rgb:240,242,245;--startup-icon:#bbc5cb;--secondary-lighter:#8696a0;--primary-title:#41525d;--progress-primary:#00c298;--progress-background:#e9edef}.dark #initial_startup{--startup-background:#111b21;--startup-background-rgb:17,27,33;--startup-icon:#676f73;--primary-title:rgba(233, 237, 239, 0.88);--secondary-lighter:#667781;--progress-primary:#0b846d;--progress-background:#233138}#app,body,html{width:100%;height:100%;padding:0;margin:0;overflow:hidden}#app{position:absolute;top:0;left:0}#initial_startup{position:fixed;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;user-select:none;background-color:var(--startup-background)}#initial_startup .graphic{margin-top:-40px;color:var(--startup-icon)}#initial_startup .graphic .resume-logo{transform:translateX(calc(50% - 52px / 2))}#initial_startup .graphic::after{position:relative;top:-100%;left:calc(50% - 72px * 2 - 72px / 2);display:block;width:calc(72px * 3);height:100%;content:'';background:linear-gradient(to right,rgba(var(--startup-background-rgb),.5) 0,rgba(var(--startup-background-rgb),.5) 33.33%,rgba(var(--startup-background-rgb),0) 44.1%,rgba(var(--startup-background-rgb),0) 55.8%,rgba(var(--startup-background-rgb),.5) 66.66%,rgba(var(--startup-background-rgb),.5) 100%);opacity:1;animation:shimmer 1.5s linear .6s infinite}html[dir=rtl] #initial_startup .graphic::after{animation-direction:reverse}@keyframes shimmer{from{left:calc(50% - 72px * 2 - 72px / 2)}to{left:calc(50% - 72px / 2)}}#initial_startup .progress{position:relative;width:420px;height:3px;margin-top:40px}#initial_startup .progress progress{vertical-align:top}#initial_startup .main{margin-top:40px;font-size:17px;color:var(--primary-title)}#initial_startup .secondary{margin-top:12px;font-size:14px;color:var(--secondary-lighter)}#initial_startup .secondary span{display:inline-block;margin-bottom:2px;vertical-align:middle}progress{-webkit-appearance:none;appearance:none;width:100%;height:3px;margin:0;color:var(--progress-primary);background-color:var(--progress-background);border:none}progress[value]::-webkit-progress-bar{background-color:var(--progress-background)}progress[value]::-moz-progress-bar,progress[value]::-webkit-progress-value{background-color:var(--progress-primary);transition:width .45s ease}</style><link href="/stylex-4a088306e44f3215558b4ef8b78657c5.css" rel="stylesheet"><link href="/app-a2c2cd1b2aea3ab61005.css" rel="stylesheet"></head><body class="web"><script data-binary-transparency-hash-key="inline-js-4b79b6dc91a7ee33373b115991c3eb287ed710cfb6708421b4cab682eddbfcbd">try{var systemThemeDark,theme=window.localStorage.getItem(""),systemThemeMode=window.localStorage.getItem("system-theme-mode");if(("true"===systemThemeMode||!theme)&&window.matchMedia){var systemTheme=window.matchMedia("(prefers-color-scheme: dark)");systemThemeDark=systemTheme&&systemTheme.matches}var darkTheme='"dark"'===theme||Boolean(systemThemeDark);darkTheme&&document.body.classList.add("dark")}catch(e){}</script><div id="app"></div><div id="hard_expire_time" data-time="1699300794.986"></div><div id="initial_startup"><div class="graphic"><span><svg width="250" height="52" xmlns="http://www.w3.org/2000/svg"><path class="resume-logo" d="M37.7 31.2c-.6-.4-3.8-2-4.4-2.1-.6-.2-1-.4-1.4.3l-2 2.5c-.4.4-.8.5-1.5.2-.6-.3-2.7-1-5.1-3.2-2-1.7-3.2-3.8-3.6-4.5-.4-.6 0-1 .3-1.3l1-1.1.6-1.1c.2-.4 0-.8 0-1.1l-2-4.8c-.6-1.3-1.1-1-1.5-1.1h-1.2c-.5 0-1.2.1-1.8.8-.5.6-2.2 2.2-2.2 5.3 0 3.2 2.3 6.3 2.6 6.7.3.4 4.6 7 11 9.7l3.7 1.4c1.5.5 3 .4 4 .2 1.3-.1 3.9-1.5 4.4-3 .5-1.5.5-2.8.4-3-.2-.4-.6-.5-1.3-.8M26 47.2c-3.9 0-7.6-1-11-3l-.7-.4-8.1 2L8.4 38l-.6-.8A21.4 21.4 0 0126 4.4a21.3 21.3 0 0121.4 21.4c0 11.8-9.6 21.4-21.4 21.4M44.2 7.6a25.8 25.8 0 00-40.6 31L0 52l13.7-3.6A25.8 25.8 0 0044.3 7.5" fill="currentColor"></path></svg></span></div><div class="progress"><progress value="0" max="100" dir="ltr"></progress></div><div class="main">WhatsApp</div><div class="secondary"><span><svg width="10" height="12" xmlns="http://www.w3.org/2000/svg"><path d="M5 1.6c1.4 0 2.5 1 2.6 2.4v1.5h.2c.5 0 1 .4 1 1V10c0 .6-.5 1-1 1H2.3a1 1 0 01-1.1-1V6.5c0-.6.5-1 1-1h.2V4.2c0-1.4 1-2.5 2.4-2.6H5zm0 1.2c-.7 0-1.3.6-1.3 1.3v1.4h2.6V4.2c0-.7-.4-1.2-1-1.3H5z" fill="currentColor"></path></svg> </span> End-to-end encrypted</div></div><link rel="preload" crossorigin="anonymous" as="fetch" href="/binary-transparency-manifest-2.2320.10.json" id="binary-transparency-manifest-preload"><script src="/libsignal-protocol-ee5b8ba.min.js"></script><script defer="defer" src="/runtime.48c50558556d819fec57.js"></script><script data-binary-transparency-hash-key="inline-js-026e63eb49dc1ea304d8d5b3073c120b618f17c45d3e4186fc3a06527b75bc4a">/*! Copyright (c) 2023 WhatsApp Inc. All Rights Reserved. */
|
|
2
|
-
(self.webpackChunkwhatsapp_web_client=self.webpackChunkwhatsapp_web_client||[]).push([[5617],{307914:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}}},595318:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}},e.exports.default=e.exports,e.exports.__esModule=!0},415227:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){const t=new Error(e);if(void 0===t.stack)try{throw t}catch(e){}return t}},670983:(e,t,r)=>{"use strict";var n=r(307914);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"?";if(null==e)throw(0,o.default)("Unexpected null or undefined: "+t);return e};var o=n(r(415227))},801506:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TICKET_URL=t.CLB_URL=t.CLB_TOKEN=t.CLB_CHECK_URL=void 0,t.CLB_CHECK_URL="https://crashlogs.whatsapp.net/wa_fls_upload_check",t.CLB_TOKEN="1063127757113399|745146ffa34413f9dbb5469f5370b7af",t.CLB_URL="https://crashlogs.whatsapp.net/wa_clb_data",t.TICKET_URL="https://web.whatsapp.com/web-contact-us"},207024:(e,t,r)=>{"use strict";var n=r(595318);Object.defineProperty(t,"__esModule",{value:!0}),t.getDistribution=function(){let e="unknown";return e="prod","web_prod"},t.getLogUserAgent=function(e){let t,{appVersion:r,browser:n,device:o}=e;return t="Web/"+n,`WhatsApp/${r} ${t} Device/${o}`},n(r(556869))},794858:(e,t,r)=>{"use strict";var n=r(595318),o=n(r(670983)),a=r(801506),s=r(207024),c=n(r(174285)),u=r(425017);function i(e){!function(e,t){const r=window.navigator.userAgent;if(r===p&&e.includes("getElementsByTagName"))return;const n=new FormData,i=new Blob([e],{type:"text/plain"});n.append("from_jid",function(){if(f)return f;try{f=JSON.parse((0,o.default)(c.default,"localStorage").getItem(d)),f&&(f=f.replace("-",""))}catch(e){}if(!f){f="unknown"+Math.floor(1e10*Math.random());const e=f;try{(0,o.default)(c.default,"localStorage").setItem(d,JSON.stringify(e))}catch(e){}}return(0,o.default)(f,"id")}()),n.append("agent",(0,s.getLogUserAgent)((0,u.parseUASimple)(r,"2.2320.10"))),n.append("file",i,"logs.txt"),n.append("tags","load");const l=new XMLHttpRequest,_=a.CLB_URL+"?access_token="+encodeURIComponent(a.CLB_TOKEN);l.open("POST",_,!0),l.send(n)}(e)}function l(e){let{error:t,reason:r,stack:n}=e;const o=(new Date).toISOString();return`${o}: error: ${t}\n${o}: reason for logs: ${r}\n${o}: userAgent: ${window.navigator.userAgent}\n${n}`}null==window.onerror&&(window.onerror=function(e,t,r){const n=t.split("?")[0];return"Uncaught SyntaxError: Unexpected token '<'"===e?(function(e){i(l({error:"failed to load a js or css bundle",reason:`failed to load [${e.split("/")[3].replace(/^\//,"")}]`,stack:""}))}(n),!0):(i(l({error:e,reason:`Error at [${n}:${r}]`,stack:""})),!1)});const d="WAUnknownID",p="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";let f},425017:(e,t)=>{"use strict";function r(e){return e.includes("windows")?"Windows":e.includes("mac")?"Mac OS":e.includes("linux")?"Linux":"Unparsed"}Object.defineProperty(t,"__esModule",{value:!0}),t.parseUASimple=function(e,t){const n=e.toLowerCase();return{browser:s(n),device:r(n),appVersion:t}};const n=/(chrome|firefox)\/([\w\.]+)/i,o=/(edge|opr)\/([\w\.]+)/i,a={chrome:"Chrome",edge:"Edge",opr:"Opera",firefox:"Firefox"};function s(e){const t=e.match(o)||e.match(n);return null==t?"Unparsed":`${a[t[1]]} ${t[2]}`}},174285:(e,t)=>{"use strict";let r;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;try{r=window.localStorage}catch(e){}var n=r;t.default=n},556869:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function e(t){const r=new Error(t);if(void 0===r.stack)try{throw e}catch(e){}return r}}},e=>{"use strict";e(e.s=794858)}])</script><script defer="defer" src="/vendor1~app.a91035d81a749b3d5627.js"></script><script defer="defer" src="/app.e77d49e02fab96b93f06.js"></script><script data-binary-transparency-hash-key="inline-js-9c8cd3d0f4d5af8c7f5cd1c45208edd308bfe472e353a50e4cbacbf6cb58627c">(i => {const l = document.getElementById(i); l &&fetch(l.href).then(b => b.text()).then(code => {const script = document.createElement('script');script.id = 'binary-transparency-manifest';script.type = 'application/json';script.innerHTML = code;document.body.append(script);});})('binary-transparency-manifest-preload');</script></body></html>
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="no-js" dir="ltr" loc="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>WhatsAppX Web</title><meta name="viewport" content="width=device-width"><meta name="google" content="notranslate"><meta name="format-detection" content="telephone=no"><meta name="description" content="Quickly send and receive WhatsApp messages right from your computer."><meta name="og:description" content="Quickly send and receive WhatsApp messages right from your computer."><meta name="og:url" content="https://web.whatsapp.com/"><meta name="og:title" content="WhatsApp Web"><meta name="og:image" content="https://static.facebook.com/images/whatsapp/www/whatsapp-promo.png"><link id="favicon" rel="shortcut icon" href="/img/favicon/1x/favicon.png" type="image/png"><link rel="apple-touch-icon" sizes="194x194" href="/apple-touch-icon.png" type="image/png"><meta name="theme-color" content="#111b21" media="(prefers-color-scheme: dark)"><meta name="theme-color" content="#f0f2f5"><link id="whatsapp-pwa-manifest-link" rel="manifest" href="/manifest.json" crossorigin="use-credentials"><style>#initial_startup{--startup-background:#f0f2f5;--startup-background-rgb:240,242,245;--startup-icon:#bbc5cb;--secondary-lighter:#8696a0;--primary-title:#41525d;--progress-primary:#00c298;--progress-background:#e9edef}.dark #initial_startup{--startup-background:#111b21;--startup-background-rgb:17,27,33;--startup-icon:#676f73;--primary-title:rgba(233, 237, 239, 0.88);--secondary-lighter:#667781;--progress-primary:#0b846d;--progress-background:#233138}#app,body,html{width:100%;height:100%;padding:0;margin:0;overflow:hidden}#app{position:absolute;top:0;left:0}#initial_startup{position:fixed;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;user-select:none;background-color:var(--startup-background)}#initial_startup .graphic{margin-top:-40px;color:var(--startup-icon)}#initial_startup .graphic .resume-logo{transform:translateX(calc(50% - 52px / 2))}#initial_startup .graphic::after{position:relative;top:-100%;left:calc(50% - 72px * 2 - 72px / 2);display:block;width:calc(72px * 3);height:100%;content:'';background:linear-gradient(to right,rgba(var(--startup-background-rgb),.5) 0,rgba(var(--startup-background-rgb),.5) 33.33%,rgba(var(--startup-background-rgb),0) 44.1%,rgba(var(--startup-background-rgb),0) 55.8%,rgba(var(--startup-background-rgb),.5) 66.66%,rgba(var(--startup-background-rgb),.5) 100%);opacity:1;animation:shimmer 1.5s linear .6s infinite}html[dir=rtl] #initial_startup .graphic::after{animation-direction:reverse}@keyframes shimmer{from{left:calc(50% - 72px * 2 - 72px / 2)}to{left:calc(50% - 72px / 2)}}#initial_startup .progress{position:relative;width:420px;height:3px;margin-top:40px}#initial_startup .progress progress{vertical-align:top}#initial_startup .main{margin-top:40px;font-size:17px;color:var(--primary-title)}#initial_startup .secondary{margin-top:12px;font-size:14px;color:var(--secondary-lighter)}#initial_startup .secondary span{display:inline-block;margin-bottom:2px;vertical-align:middle}progress{-webkit-appearance:none;appearance:none;width:100%;height:3px;margin:0;color:var(--progress-primary);background-color:var(--progress-background);border:none}progress[value]::-webkit-progress-bar{background-color:var(--progress-background)}progress[value]::-moz-progress-bar,progress[value]::-webkit-progress-value{background-color:var(--progress-primary);transition:width .45s ease}</style><link href="/stylex-534e186735a7216f8166323ac4f40ec0.css" rel="stylesheet"><link href="/app-397dc77d692df7ff99b6.css" rel="stylesheet"></head><body class="web"><script data-binary-transparency-hash-key="inline-js-4b79b6dc91a7ee33373b115991c3eb287ed710cfb6708421b4cab682eddbfcbd">try{var systemThemeDark,theme=window.localStorage.getItem(""),systemThemeMode=window.localStorage.getItem("system-theme-mode");if(("true"===systemThemeMode||!theme)&&window.matchMedia){var systemTheme=window.matchMedia("(prefers-color-scheme: dark)");systemThemeDark=systemTheme&&systemTheme.matches}var darkTheme='"dark"'===theme||Boolean(systemThemeDark);darkTheme&&document.body.classList.add("dark")}catch(e){}</script><div id="app"></div><div id="hard_expire_time" data-time="1700350311.621"></div><div id="initial_startup"><div class="graphic"><span><svg width="250" height="52" xmlns="http://www.w3.org/2000/svg"><path class="resume-logo" d="M37.7 31.2c-.6-.4-3.8-2-4.4-2.1-.6-.2-1-.4-1.4.3l-2 2.5c-.4.4-.8.5-1.5.2-.6-.3-2.7-1-5.1-3.2-2-1.7-3.2-3.8-3.6-4.5-.4-.6 0-1 .3-1.3l1-1.1.6-1.1c.2-.4 0-.8 0-1.1l-2-4.8c-.6-1.3-1.1-1-1.5-1.1h-1.2c-.5 0-1.2.1-1.8.8-.5.6-2.2 2.2-2.2 5.3 0 3.2 2.3 6.3 2.6 6.7.3.4 4.6 7 11 9.7l3.7 1.4c1.5.5 3 .4 4 .2 1.3-.1 3.9-1.5 4.4-3 .5-1.5.5-2.8.4-3-.2-.4-.6-.5-1.3-.8M26 47.2c-3.9 0-7.6-1-11-3l-.7-.4-8.1 2L8.4 38l-.6-.8A21.4 21.4 0 0126 4.4a21.3 21.3 0 0121.4 21.4c0 11.8-9.6 21.4-21.4 21.4M44.2 7.6a25.8 25.8 0 00-40.6 31L0 52l13.7-3.6A25.8 25.8 0 0044.3 7.5" fill="currentColor"></path></svg></span></div><div class="progress"><progress value="0" max="100" dir="ltr"></progress></div><div class="main">WhatsApp</div><div class="secondary"><span><svg width="10" height="12" xmlns="http://www.w3.org/2000/svg"><path d="M5 1.6c1.4 0 2.5 1 2.6 2.4v1.5h.2c.5 0 1 .4 1 1V10c0 .6-.5 1-1 1H2.3a1 1 0 01-1.1-1V6.5c0-.6.5-1 1-1h.2V4.2c0-1.4 1-2.5 2.4-2.6H5zm0 1.2c-.7 0-1.3.6-1.3 1.3v1.4h2.6V4.2c0-.7-.4-1.2-1-1.3H5z" fill="currentColor"></path></svg> </span> End-to-end encrypted</div></div><link rel="preload" crossorigin="anonymous" as="fetch" href="/binary-transparency-manifest-2.2322.15.json" id="binary-transparency-manifest-preload"><script src="/libsignal-protocol-ee5b8ba.min.js"></script><script defer="defer" src="/runtime.d9a06bd6a7a484d6e04e.js"></script><script data-binary-transparency-hash-key="inline-js-fa16de51ee7511dd7a3e11537a929d8433d81c4653032c11129c2f55dd563575">/*! Copyright (c) 2023 WhatsApp Inc. All Rights Reserved. */
|
|
2
|
-
(self.webpackChunkwhatsapp_web_client=self.webpackChunkwhatsapp_web_client||[]).push([[5617],{307914:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}}},595318:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}},e.exports.default=e.exports,e.exports.__esModule=!0},415227:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){const t=new Error(e);if(void 0===t.stack)try{throw t}catch(e){}return t}},670983:(e,t,r)=>{"use strict";var n=r(307914);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"?";if(null==e)throw(0,o.default)("Unexpected null or undefined: "+t);return e};var o=n(r(415227))},801506:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TICKET_URL=t.CLB_URL=t.CLB_TOKEN=t.CLB_CHECK_URL=void 0,t.CLB_CHECK_URL="https://crashlogs.whatsapp.net/wa_fls_upload_check",t.CLB_TOKEN="1063127757113399|745146ffa34413f9dbb5469f5370b7af",t.CLB_URL="https://crashlogs.whatsapp.net/wa_clb_data",t.TICKET_URL="https://web.whatsapp.com/web-contact-us"},207024:(e,t,r)=>{"use strict";var n=r(595318);Object.defineProperty(t,"__esModule",{value:!0}),t.getDistribution=function(){let e="unknown";return e="prod","web_prod"},t.getLogUserAgent=function(e){let t,{appVersion:r,browser:n,device:o}=e;return t="Web/"+n,`WhatsApp/${r} ${t} Device/${o}`},n(r(97359)),n(r(556869))},794858:(e,t,r)=>{"use strict";var n=r(595318),o=n(r(670983)),a=r(801506),s=r(207024),u=n(r(174285)),c=r(425017);function i(e){!function(e,t){const r=window.navigator.userAgent;if(r===f&&e.includes("getElementsByTagName"))return;const n=new FormData,i=new Blob([e],{type:"text/plain"});n.append("from_jid",function(){if(p)return p;try{p=JSON.parse((0,o.default)(u.default,"localStorage").getItem(d)),p&&(p=p.replace("-",""))}catch(e){}if(!p){p="unknown"+Math.floor(1e10*Math.random());const e=p;try{(0,o.default)(u.default,"localStorage").setItem(d,JSON.stringify(e))}catch(e){}}return(0,o.default)(p,"id")}()),n.append("agent",(0,s.getLogUserAgent)((0,c.parseUASimple)(r,"2.2322.15"))),n.append("file",i,"logs.txt"),n.append("tags","load");const l=new XMLHttpRequest,_=a.CLB_URL+"?access_token="+encodeURIComponent(a.CLB_TOKEN);l.open("POST",_,!0),l.send(n)}(e)}function l(e){let{error:t,reason:r,stack:n}=e;const o=(new Date).toISOString();return`${o}: error: ${t}\n${o}: reason for logs: ${r}\n${o}: userAgent: ${window.navigator.userAgent}\n${n}`}null==window.onerror&&(window.onerror=function(e,t,r){const n=t.split("?")[0];return"Uncaught SyntaxError: Unexpected token '<'"===e?(function(e){i(l({error:"failed to load a js or css bundle",reason:`failed to load [${e.split("/")[3].replace(/^\//,"")}]`,stack:""}))}(n),!0):(i(l({error:e,reason:`Error at [${n}:${r}]`,stack:""})),!1)});const d="WAUnknownID",f="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";let p},425017:(e,t)=>{"use strict";function r(e){return e.includes("windows")?"Windows":e.includes("mac")?"Mac OS":e.includes("linux")?"Linux":"Unparsed"}Object.defineProperty(t,"__esModule",{value:!0}),t.parseUASimple=function(e,t){const n=e.toLowerCase();return{browser:s(n),device:r(n),appVersion:t}};const n=/(chrome|firefox)\/([\w\.]+)/i,o=/(edge|opr)\/([\w\.]+)/i,a={chrome:"Chrome",edge:"Edge",opr:"Opera",firefox:"Firefox"};function s(e){const t=e.match(o)||e.match(n);return null==t?"Unparsed":`${a[t[1]]} ${t[2]}`}},174285:(e,t)=>{"use strict";let r;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;try{r=window.localStorage}catch(e){}var n=r;t.default=n},97359:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e.default}},556869:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function e(t){const r=new Error(t);if(void 0===r.stack)try{throw e}catch(e){}return r}}},e=>{"use strict";e(e.s=794858)}])</script><script defer="defer" src="/vendor1~app.a91035d81a749b3d5627.js"></script><script defer="defer" src="/app.df22dc4b1b984dc87f36.js"></script><script data-binary-transparency-hash-key="inline-js-9c8cd3d0f4d5af8c7f5cd1c45208edd308bfe472e353a50e4cbacbf6cb58627c">(i => {const l = document.getElementById(i); l &&fetch(l.href).then(b => b.text()).then(code => {const script = document.createElement('script');script.id = 'binary-transparency-manifest';script.type = 'application/json';script.innerHTML = code;document.body.append(script);});})('binary-transparency-manifest-preload');</script></body></html>
|