@mtcute/core 0.16.13 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/chunks/cjs/{CntZHjXA.js → BcdQkLTS.js} +83 -15
  2. package/chunks/cjs/{chPq0GcA.js → CSfUPcui.js} +914 -796
  3. package/chunks/cjs/{BO3RV06t.js → kxT7E_JE.js} +3 -3
  4. package/chunks/es/{xihQcMp0.js → BJRm2PAH.js} +3 -3
  5. package/chunks/es/{Jz_hDg6M.js → CbXFWEiB.js} +83 -15
  6. package/chunks/es/{Btmu4f4t.js → DKzd1_Yg.js} +914 -796
  7. package/client.cjs +21 -9
  8. package/client.js +21 -9
  9. package/highlevel/client.d.ts +109 -25
  10. package/highlevel/methods/files/upload-file.d.ts +8 -0
  11. package/highlevel/methods/premium/accept-star-gift.d.ts +16 -0
  12. package/highlevel/methods/premium/get-star-gift-options.d.ts +6 -0
  13. package/highlevel/methods/premium/get-star-gifts.d.ts +22 -0
  14. package/highlevel/methods/premium/iter-star-gifts.d.ts +26 -0
  15. package/highlevel/methods/premium/send-star-gift.d.ts +35 -0
  16. package/highlevel/methods/stickers/create-sticker-set.d.ts +1 -7
  17. package/highlevel/methods.d.ts +5 -1
  18. package/highlevel/types/bots/keyboards/factories.d.ts +7 -0
  19. package/highlevel/types/media/video.d.ts +1 -0
  20. package/highlevel/types/messages/message-action.d.ts +19 -2
  21. package/highlevel/types/misc/sticker-set.d.ts +1 -5
  22. package/highlevel/types/premium/index.d.ts +1 -0
  23. package/highlevel/types/premium/stars-gift.d.ts +57 -0
  24. package/highlevel/types/premium/stars-transaction.d.ts +8 -0
  25. package/index.cjs +5 -3
  26. package/index.js +7 -5
  27. package/methods.cjs +7 -3
  28. package/methods.js +7 -3
  29. package/network/client.d.ts +1 -1
  30. package/network/multi-session-connection.d.ts +1 -1
  31. package/network/persistent-connection.d.ts +1 -1
  32. package/network/transports/abstract.d.ts +1 -1
  33. package/network/transports/streamed.d.ts +1 -1
  34. package/network/transports/wrapped.d.ts +1 -1
  35. package/package.json +4 -4
  36. package/highlevel/methods/stories/report-story.d.ts +0 -19
@@ -1224,6 +1224,13 @@ function requestPeer(text2, buttonId, params) {
1224
1224
  maxQuantity: params.count ?? 1
1225
1225
  };
1226
1226
  }
1227
+ function copy(params) {
1228
+ return {
1229
+ _: "keyboardButtonCopy",
1230
+ text: params.text,
1231
+ copyText: params?.copyText ?? params.text
1232
+ };
1233
+ }
1227
1234
  function findButton(buttons, predicate) {
1228
1235
  if (typeof predicate === "string") {
1229
1236
  const text2 = predicate;
@@ -1301,6 +1308,7 @@ const factories$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
1301
1308
  _rowsTo2d,
1302
1309
  builder,
1303
1310
  callback,
1311
+ copy,
1304
1312
  findButton,
1305
1313
  forceReply,
1306
1314
  game: game$2,
@@ -3154,945 +3162,1044 @@ class Photo extends FileLocation$1 {
3154
3162
  }
3155
3163
  const Photo$1 = /* @__PURE__ */ memoizeGetters(Photo, ["thumbnails", "fileId", "uniqueFileId"]);
3156
3164
  const Photo$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Photo$1, ["fileSize", "dcId", "width", "height"], ["inputMedia", "inputPhoto"]);
3157
- function _messageActionFromTl(act) {
3158
- switch (act._) {
3159
- case "messageActionChatCreate":
3160
- return {
3161
- type: "chat_created",
3162
- title: act.title,
3163
- users: act.users
3164
- };
3165
- case "messageActionChannelCreate":
3166
- return {
3167
- type: "channel_created",
3168
- title: act.title
3169
- };
3170
- case "messageActionChatMigrateTo":
3171
- return {
3172
- type: "chat_migrate_to",
3173
- id: act.channelId
3174
- };
3175
- case "messageActionChannelMigrateFrom":
3176
- return {
3177
- type: "channel_migrate_from",
3178
- id: act.chatId,
3179
- title: act.title
3180
- };
3181
- case "messageActionPinMessage":
3182
- return {
3183
- type: "message_pinned"
3184
- };
3185
- case "messageActionHistoryClear":
3186
- return {
3187
- type: "history_cleared"
3188
- };
3189
- case "messageActionGameScore":
3190
- return {
3191
- type: "game_score",
3192
- gameId: act.gameId,
3193
- score: act.score
3194
- };
3195
- case "messageActionContactSignUp":
3196
- return {
3197
- type: "contact_joined"
3198
- };
3199
- case "messageActionChatEditTitle":
3200
- return {
3201
- type: "title_changed",
3202
- title: act.title
3203
- };
3204
- case "messageActionChatEditPhoto":
3205
- return {
3206
- type: "photo_changed",
3207
- photo: new Photo$2(act.photo)
3208
- };
3209
- case "messageActionChatDeletePhoto":
3210
- return {
3211
- type: "photo_deleted"
3212
- };
3213
- case "messageActionChatAddUser":
3214
- return {
3215
- type: "users_added",
3216
- users: act.users
3217
- };
3218
- case "messageActionChatDeleteUser":
3219
- if (this.raw.fromId?._ === "peerUser" && act.userId === this.raw.fromId.userId) {
3220
- return {
3221
- type: "user_left"
3222
- };
3223
- }
3224
- return {
3225
- type: "user_removed",
3226
- user: act.userId
3227
- };
3228
- case "messageActionChatJoinedByLink":
3229
- return {
3230
- type: "user_joined_link",
3231
- inviter: act.inviterId
3232
- };
3233
- case "messageActionPaymentSentMe":
3234
- return {
3235
- type: "payment_received",
3236
- currency: act.currency,
3237
- amount: act.totalAmount,
3238
- payload: act.payload,
3239
- info: act.info,
3240
- shippingOptionId: act.shippingOptionId,
3241
- charge: act.charge
3242
- };
3243
- case "messageActionPaymentSent":
3244
- return {
3245
- type: "payment_sent",
3246
- currency: act.currency,
3247
- amount: act.totalAmount
3248
- };
3249
- case "messageActionPhoneCall":
3250
- return {
3251
- type: "call",
3252
- id: act.callId,
3253
- isVideo: Boolean(act.video),
3254
- reason: act.reason ? _callDiscardReasonFromTl(act.reason) : void 0,
3255
- duration: act.duration ?? 0
3256
- };
3257
- case "messageActionScreenshotTaken":
3258
- return {
3259
- type: "screenshot_taken"
3260
- };
3261
- case "messageActionBotAllowed":
3262
- return {
3263
- type: "bot_allowed",
3264
- domain: act.domain
3265
- };
3266
- case "messageActionGeoProximityReached":
3267
- if (act.fromId._ !== "peerUser" || act.toId._ !== "peerUser") {
3268
- return null;
3165
+ class RawDocument extends FileLocation$1 {
3166
+ constructor(raw) {
3167
+ super(
3168
+ {
3169
+ _: "inputDocumentFileLocation",
3170
+ id: raw.id,
3171
+ fileReference: raw.fileReference,
3172
+ accessHash: raw.accessHash,
3173
+ thumbSize: ""
3174
+ },
3175
+ raw.size,
3176
+ raw.dcId
3177
+ );
3178
+ this.raw = raw;
3179
+ this.raw = raw;
3180
+ }
3181
+ /**
3182
+ * Original file name, extracted from the document
3183
+ * attributes.
3184
+ */
3185
+ get fileName() {
3186
+ const attr = this.raw.attributes.find((it) => it._ === "documentAttributeFilename");
3187
+ return attr?.fileName ?? null;
3188
+ }
3189
+ /**
3190
+ * File MIME type, as defined by the sender.
3191
+ */
3192
+ get mimeType() {
3193
+ return this.raw.mimeType;
3194
+ }
3195
+ /**
3196
+ * Date the document was sent
3197
+ */
3198
+ get date() {
3199
+ return new Date(this.raw.date * 1e3);
3200
+ }
3201
+ /**
3202
+ * Available thumbnails, if any.
3203
+ *
3204
+ * If there are no thumbnails, the array will be empty.
3205
+ */
3206
+ get thumbnails() {
3207
+ const arr = [];
3208
+ this.raw.thumbs?.forEach((sz) => arr.push(new Thumbnail$2(this.raw, sz)));
3209
+ this.raw.videoThumbs?.forEach((sz) => arr.push(new Thumbnail$2(this.raw, sz)));
3210
+ return arr;
3211
+ }
3212
+ /**
3213
+ * Get a thumbnail by its type.
3214
+ *
3215
+ * Thumbnail types are described in the
3216
+ * [Telegram docs](https://core.telegram.org/api/files#image-thumbnail-types),
3217
+ * and are also available as static members of {@link Thumbnail} for convenience.
3218
+ *
3219
+ * @param type Thumbnail type
3220
+ */
3221
+ getThumbnail(type) {
3222
+ return this.thumbnails.find((it) => {
3223
+ if (it.raw._ === "videoSizeEmojiMarkup" || it.raw._ === "videoSizeStickerMarkup") {
3224
+ return false;
3269
3225
  }
3270
- return {
3271
- type: "geo_proximity",
3272
- targetId: act.toId.userId,
3273
- userId: act.fromId.userId,
3274
- distance: act.distance
3275
- };
3276
- case "messageActionGroupCall":
3277
- if (act.duration) {
3278
- return {
3279
- type: "group_call_ended",
3280
- call: act.call,
3281
- duration: act.duration
3282
- };
3226
+ return it.raw.type === type;
3227
+ }) ?? null;
3228
+ }
3229
+ /**
3230
+ * Input document TL object generated from this object,
3231
+ * to be used with methods that use it
3232
+ */
3233
+ get inputDocument() {
3234
+ return {
3235
+ _: "inputDocument",
3236
+ id: this.raw.id,
3237
+ accessHash: this.raw.accessHash,
3238
+ fileReference: this.raw.fileReference
3239
+ };
3240
+ }
3241
+ /**
3242
+ * Input media TL object generated from this object,
3243
+ * to be used inside {@link InputMediaLike} and
3244
+ * {@link TelegramClient.sendMedia}
3245
+ */
3246
+ get inputMedia() {
3247
+ return {
3248
+ _: "inputMediaDocument",
3249
+ id: this.inputDocument
3250
+ };
3251
+ }
3252
+ _fileIdType() {
3253
+ return fileId.tdFileId.FileType.Document;
3254
+ }
3255
+ /**
3256
+ * Get TDLib and Bot API compatible File ID
3257
+ * representing this document.
3258
+ */
3259
+ get fileId() {
3260
+ return fileId.toFileId(platform.getPlatform(), {
3261
+ type: this._fileIdType(),
3262
+ dcId: this.raw.dcId,
3263
+ fileReference: this.raw.fileReference,
3264
+ location: {
3265
+ _: "common",
3266
+ id: this.raw.id,
3267
+ accessHash: this.raw.accessHash
3283
3268
  }
3284
- return {
3285
- type: "group_call_started",
3286
- call: act.call
3287
- };
3288
- case "messageActionGroupCallScheduled":
3289
- return {
3290
- type: "group_call_scheduled",
3291
- call: act.call,
3292
- date: new Date(act.scheduleDate * 1e3)
3293
- };
3294
- case "messageActionInviteToGroupCall":
3295
- return {
3296
- type: "group_call_invite",
3297
- call: act.call,
3298
- userIds: act.users
3299
- };
3300
- case "messageActionSetMessagesTTL":
3301
- return {
3302
- type: "ttl_changed",
3303
- period: act.period
3304
- };
3305
- case "messageActionTopicCreate":
3306
- return {
3307
- type: "topic_created",
3308
- title: act.title,
3309
- iconColor: act.iconColor,
3310
- iconCustomEmoji: act.iconEmojiId
3311
- };
3312
- case "messageActionTopicEdit":
3313
- return {
3314
- type: "topic_edited",
3315
- title: act.title,
3316
- iconCustomEmoji: act.iconEmojiId,
3317
- closed: act.closed,
3318
- hidden: act.hidden
3319
- };
3320
- case "messageActionCustomAction":
3321
- return {
3322
- type: "custom",
3323
- action: act.message
3324
- };
3325
- case "messageActionSetChatTheme":
3326
- return {
3327
- type: "theme_changed",
3328
- emoji: act.emoticon
3329
- };
3330
- case "messageActionChatJoinedByRequest":
3331
- return {
3332
- type: "user_joined_approved"
3333
- };
3334
- case "messageActionWebViewDataSent":
3335
- return {
3336
- type: "webview_sent",
3337
- text: act.text
3338
- };
3339
- case "messageActionWebViewDataSentMe":
3340
- return {
3341
- type: "webview_received",
3342
- text: act.text,
3343
- data: act.data
3344
- };
3345
- case "messageActionGiftPremium":
3346
- return {
3347
- type: "premium_gifted",
3348
- currency: act.currency,
3349
- amount: act.amount.toNumber(),
3350
- months: act.months,
3351
- crypto: act.cryptoAmount ? {
3352
- currency: act.cryptoCurrency,
3353
- amount: act.cryptoAmount.toNumber()
3354
- } : void 0
3355
- };
3356
- case "messageActionSuggestProfilePhoto":
3357
- return {
3358
- type: "photo_suggested",
3359
- photo: new Photo$2(act.photo)
3360
- };
3361
- case "messageActionRequestedPeerSentMe":
3362
- return {
3363
- type: "peer_sent",
3364
- buttonId: act.buttonId,
3365
- peers: act.peers
3366
- };
3367
- case "messageActionRequestedPeer":
3368
- return {
3369
- type: "peer_chosen",
3370
- buttonId: act.buttonId,
3371
- peers: act.peers.map((it) => parsePeer(it, this._peers))
3372
- };
3373
- case "messageActionSetChatWallPaper":
3374
- return {
3375
- type: "wallpaper_changed",
3376
- same: act.same,
3377
- forBoth: act.forBoth,
3378
- wallpaper: act.wallpaper
3379
- };
3380
- case "messageActionGiftCode":
3381
- return {
3382
- type: "gift_code",
3383
- raw: act
3384
- };
3385
- case "messageActionGiveawayLaunch":
3386
- return {
3387
- type: "giveaway_started"
3388
- };
3389
- case "messageActionGiveawayResults":
3390
- return {
3391
- type: "giveaway_ended",
3392
- winners: act.winnersCount,
3393
- undistributed: act.unclaimedCount
3394
- };
3395
- case "messageActionBoostApply":
3396
- return {
3397
- type: "boost_apply",
3398
- count: act.boosts
3399
- };
3400
- case "messageActionPaymentRefunded":
3401
- return {
3402
- type: "payment_refunded",
3403
- currency: act.currency,
3404
- peerId: conditionVariable.getMarkedPeerId(act.peer),
3405
- amount: act.totalAmount,
3406
- payload: act.payload,
3407
- charge: act.charge
3408
- };
3409
- case "messageActionGiftStars":
3410
- return {
3411
- type: "stars_gifted",
3412
- isCrypto: Boolean(act.cryptoCurrency),
3413
- currency: act.cryptoCurrency ?? act.currency,
3414
- amount: act.cryptoAmount ?? act.amount,
3415
- stars: act.stars,
3416
- transactionId: act.transactionId
3417
- };
3418
- case "messageActionPrizeStars":
3419
- return {
3420
- type: "stars_prize",
3421
- claimed: !act.unclaimed,
3422
- stars: act.stars,
3423
- transactionId: act.transactionId,
3424
- boostPeer: parsePeer(act.boostPeer, this._peers),
3425
- giveawayMessageId: act.giveawayMsgId
3426
- };
3427
- default:
3428
- return null;
3429
- }
3430
- }
3431
- class MessageForwardInfo {
3432
- constructor(raw, _peers) {
3433
- this.raw = raw;
3434
- this._peers = _peers;
3269
+ });
3435
3270
  }
3436
3271
  /**
3437
- * Date the original message was sent
3272
+ * Get a unique File ID representing this document.
3438
3273
  */
3439
- get date() {
3440
- return new Date(this.raw.date * 1e3);
3274
+ get uniqueFileId() {
3275
+ return fileId.toUniqueFileId(platform.getPlatform(), fileId.tdFileId.FileType.Document, {
3276
+ _: "common",
3277
+ id: this.raw.id
3278
+ });
3441
3279
  }
3442
- /**
3443
- * Sender of the original message (either user or a channel)
3444
- * or their name (for users with private forwards)
3445
- */
3446
- get sender() {
3447
- if (this.raw.fromName) {
3448
- return {
3449
- type: "anonymous",
3450
- displayName: this.raw.fromName
3451
- };
3452
- }
3453
- if (this.raw.fromId) {
3454
- return parsePeer(this.raw.fromId, this._peers);
3455
- }
3456
- throw new platform.MtTypeAssertionError("MessageForwardInfo", "to have fromId or fromName", "neither");
3280
+ }
3281
+ class Document extends RawDocument {
3282
+ type = "document";
3283
+ }
3284
+ const Document$1 = /* @__PURE__ */ memoizeGetters(Document, ["fileName", "thumbnails", "fileId", "uniqueFileId"]);
3285
+ const Document$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Document$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3286
+ class Audio extends RawDocument {
3287
+ constructor(doc, attr) {
3288
+ super(doc);
3289
+ this.attr = attr;
3290
+ }
3291
+ /** Type of the media (for use in a tagged union) */
3292
+ type = "audio";
3293
+ /** Type of the file for File ID generation */
3294
+ _fileIdType() {
3295
+ return fileId.tdFileId.FileType.Audio;
3457
3296
  }
3458
3297
  /**
3459
- * For "saved" messages (i.e. messages forwarded to yourself,
3460
- * "Saved Messages"), the peer where the message was originally sent
3298
+ * Duration of the audio in seconds.
3299
+ *
3300
+ * May not be accurate since provided by the sender.
3461
3301
  */
3462
- fromChat() {
3463
- if (!this.raw.savedFromPeer) return null;
3464
- return Chat$2._parseFromPeer(this.raw.savedFromPeer, this._peers);
3302
+ get duration() {
3303
+ return this.attr.duration;
3465
3304
  }
3466
3305
  /**
3467
- * For messages forwarded from channels,
3468
- * identifier of the original message in the channel
3306
+ * Performer of the audio track.
3469
3307
  */
3470
- get fromMessageId() {
3471
- return this.raw.savedFromMsgId ?? null;
3308
+ get performer() {
3309
+ return this.attr.performer ?? null;
3472
3310
  }
3473
3311
  /**
3474
- * For messages forwarded from channels,
3475
- * signature of the post author (if present)
3312
+ * Title of the audio track.
3476
3313
  */
3477
- get signature() {
3478
- return this.raw.postAuthor ?? null;
3314
+ get title() {
3315
+ return this.attr.title ?? null;
3479
3316
  }
3480
3317
  }
3481
- const MessageForwardInfo$1 = /* @__PURE__ */ memoizeGetters(MessageForwardInfo, ["sender", "fromChat"]);
3482
- const MessageForwardInfo$2 = /* @__PURE__ */ conditionVariable.makeInspectable(MessageForwardInfo$1);
3483
- class Contact {
3484
- constructor(obj) {
3485
- this.obj = obj;
3318
+ const Audio$1 = /* @__PURE__ */ memoizeGetters(Audio, ["fileName", "thumbnails", "fileId", "uniqueFileId"]);
3319
+ const Audio$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Audio$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3320
+ const MASK_POSITION_POINT_TO_TL = {
3321
+ forehead: 0,
3322
+ eyes: 1,
3323
+ mouth: 2,
3324
+ chin: 3
3325
+ };
3326
+ const MASK_POS = ["forehead", "eyes", "mouth", "chin"];
3327
+ class Sticker extends RawDocument {
3328
+ constructor(doc, attr, attr2) {
3329
+ super(doc);
3330
+ this.attr = attr;
3331
+ this.attr2 = attr2;
3486
3332
  }
3487
- type = "contact";
3488
- /**
3489
- * Contact's phone number
3490
- */
3491
- get phoneNumber() {
3492
- return this.obj.phoneNumber;
3333
+ type = "sticker";
3334
+ _fileIdType() {
3335
+ return fileId.tdFileId.FileType.Sticker;
3493
3336
  }
3494
3337
  /**
3495
- * Contact's first name
3338
+ * Sticker width in pixels
3496
3339
  */
3497
- get firstName() {
3498
- return this.obj.firstName;
3340
+ get width() {
3341
+ return this.attr2?.w ?? 512;
3499
3342
  }
3500
3343
  /**
3501
- * Contact's last name
3344
+ * Sticker height in pixels
3502
3345
  */
3503
- get lastName() {
3504
- return this.obj.lastName;
3346
+ get height() {
3347
+ return this.attr2?.h ?? 512;
3505
3348
  }
3506
3349
  /**
3507
- * Contact's user ID in Telegram or `0` if not available
3350
+ * Whether this sticker is a premium sticker
3351
+ * (has premium fullscreen animation)
3508
3352
  */
3509
- get userId() {
3510
- return this.obj.userId;
3353
+ get isPremiumSticker() {
3354
+ return Boolean(this.raw.videoThumbs?.some((s) => s._ === "videoSize" && s.type === "f"));
3511
3355
  }
3512
3356
  /**
3513
- * Input media TL object generated from this object,
3514
- * to be used inside {@link InputMediaLike} and
3515
- * {@link TelegramClient.sendMedia}
3357
+ * Whether this sticker is a valid sticker.
3358
+ *
3359
+ * If it is not, then this is probably a WEBP photo
3360
+ * that Telegram treats as a sticker.
3516
3361
  */
3517
- get inputMedia() {
3518
- return {
3519
- ...this.obj,
3520
- _: "inputMediaContact"
3521
- };
3362
+ get isValidSticker() {
3363
+ return this.attr2 !== void 0 && (this.attr2.w === 512 || this.attr2.h === 512);
3522
3364
  }
3523
- }
3524
- const Contact$1 = /* @__PURE__ */ conditionVariable.makeInspectable(Contact, void 0, ["inputMedia"]);
3525
- class Dice {
3526
- constructor(obj) {
3527
- this.obj = obj;
3528
- }
3529
- type = "dice";
3530
3365
  /**
3531
- * A simple 6-sided dice.
3366
+ * Primary emoji associated with this sticker,
3367
+ * that is displayed in dialogs list.
3532
3368
  *
3533
- * {@link value} represents its value (1-6)
3534
- */
3535
- static TYPE_DICE = "🎲";
3536
- /**
3537
- * A dart. Telegram dart has 4 rings and middle.
3369
+ * If there is none, empty string is returned.
3538
3370
  *
3539
- * {@link value} represents the position of the dart:
3540
- * ![Dart position graph](https://i.imgur.com/iPBm7HG.png)
3371
+ * **Note:** This only contains at most one emoji.
3372
+ * Some stickers have multiple associated emojis,
3373
+ * but only one is returned here. This is Telegram's
3374
+ * limitation! Use {@link getAllEmojis} instead.
3375
+ *
3376
+ * For custom emojis, this alt should be used as a fallback
3377
+ * text that will be "behind" the custom emoji entity.
3541
3378
  */
3542
- static TYPE_DART = "🎯";
3379
+ get emoji() {
3380
+ return this.attr.alt;
3381
+ }
3543
3382
  /**
3544
- * A basketball thrown into a hoop.
3383
+ * Whether this custom emoji can be used by non-premium users.
3384
+ * `false` if this is not a custom emoji.
3545
3385
  *
3546
- * {@link value} represents the motion of the ball:
3547
- * - 1: simple miss (ball hits right part, bounces to the left)
3548
- * - 2: first hit the ring, then miss
3549
- * - 3: ball gets stuck between the ring and the base
3550
- * - 4: first hit the ring, then score
3551
- * - 5: direct score
3386
+ * > Not sure if there are any such stickers currently.
3552
3387
  */
3553
- static TYPE_BASKETBALL = "🏀";
3388
+ get customEmojiFree() {
3389
+ return this.attr._ === "documentAttributeCustomEmoji" ? this.attr.free ?? false : false;
3390
+ }
3554
3391
  /**
3555
- * A football thrown to the gate.
3556
- *
3557
- * {@link value} represents the motion of the ball:
3558
- * - 1: flies above the top barbell
3559
- * - 2: hits right barbell, then miss
3560
- * - 3: direct score in the middle
3561
- * - 4: hits left barbell, then score, then hits right barbell
3562
- * - 5: score in the top-right corner
3392
+ * If this is a custom emoji, its unique ID
3393
+ * that can be used in {@link TelegramClient#getCustomEmojis}
3563
3394
  */
3564
- static TYPE_FOOTBALL = "⚽️";
3395
+ get customEmojiId() {
3396
+ if (this.attr._ !== "documentAttributeCustomEmoji") {
3397
+ throw new platform.MtArgumentError("This is not a custom emoji");
3398
+ }
3399
+ return this.raw.id;
3400
+ }
3565
3401
  /**
3566
- * A bowling ball thrown to pins.
3567
- *
3568
- * Assuming the following identifiers for the pins:
3569
- * ```
3570
- * 4 5 6
3571
- * 2 3
3572
- * 1
3573
- * ```
3574
- *
3575
- * {@link value} represents the motion of the ball and pins:
3576
- * - 1: the ball touched 6th pin, none are down
3577
- * - 2: the ball hit 4th pin, only 4th pin is down.
3578
- * - 3: the ball hit 1st pin, pins 1, 2, 5 are down, leaving pins 3, 4, 6
3579
- * - 4: the ball hit 1st pin on the right side, all the pins except 2nd and 6th are down
3580
- * - 5: the ball hit 3rd pin and all the pins except 2nd are down.
3581
- * - 6: the ball hit 1st pin and all pins are down
3402
+ * Type of the sticker
3582
3403
  */
3583
- static TYPE_BOWLING = "🎳";
3404
+ get stickerType() {
3405
+ if (this.attr._ === "documentAttributeSticker") {
3406
+ return this.attr.mask ? "mask" : "sticker";
3407
+ } else if (this.attr._ === "documentAttributeCustomEmoji") {
3408
+ return "emoji";
3409
+ }
3410
+ return "sticker";
3411
+ }
3584
3412
  /**
3585
- * A slot machine.
3586
- *
3587
- * {@link value} represents the result of the machine.
3588
- * Value itself is an integer in range `[1, 64]`,
3589
- * and is composed out of several parts.
3590
- *
3591
- * > **Note**: The following information is based on the TDesktop
3592
- * > implementation. These are the relevant files:
3593
- * > - [`chat_helpers/stickers_dice_pack.cpp`](https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp)
3594
- * > - [`history/view/media/history_view_slot_machine.cpp`](https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/history/view/media/history_view_slot_machine.cpp)
3595
- *
3596
- * Unlike other animated dices, this does not have
3597
- * all the possible combinations in the sticker set.
3598
- * Instead, `value` is a specially encoded integer that contains
3599
- * the information about the indexes.
3600
- *
3601
- * There are some base parts of the animations:
3602
- * - 0th sticker is the base background of the machine
3603
- * - 1st sticker is the background of the machine for the "winning" state (i.e. `777`)
3604
- * - 2nd sticker is the frame of the machine, including the handle
3605
- * - 8th sticker is the "idle" state for the left slot
3606
- * - 14th sticker is the "idle" state for the middle slot
3607
- * - 20th sticker is the "idle" state for the right slot
3608
- *
3609
- * The machine result is encoded as 3 concatenated two-bit integers,
3610
- * and the resulting integer is incremented by one.
3611
- *
3612
- * So, to decode the value to its parts, you can use this code:
3613
- * ```typescript
3614
- * const computePartValue = (val: number, idx: number) => ((val - 1) >> (idx * 2)) & 0x03; // 0..3
3615
- * const parts = [
3616
- * computePartValue(msg.media.value, 0),
3617
- * computePartValue(msg.media.value, 1),
3618
- * computePartValue(msg.media.value, 2),
3619
- * ]
3620
- * ```
3621
- *
3622
- * Each part of the value corresponds to a particular slot (i.e. part 0 is left slot,
3623
- * part 1 is middle, part 2 is right). The slot values are as follows:
3624
- * - 0: BAR (displayed as a *BAR* sign on a black background)
3625
- * - 1: BERRIES (displayed as berries, similar to emoji 🍇)
3626
- * - 2: LEMON (displayed as a lemon, similar to emoji 🍋)
3627
- * - 3: SEVEN (displayed as a red digit 7)
3628
- *
3629
- * Therefore, the winning value (i.e. `777`) is represented as `(3 << 4 | 3 << 2 | 3 << 0) + 1 = 64`
3630
- *
3631
- * To determine the needed animation parts, you'll need to apply some shifts.
3632
- * These are the offsets for the individual symbols:
3633
- * - WIN_SEVEN: 0
3634
- * - SEVEN: 1
3635
- * - BAR: 2
3636
- * - BERRIES: 3
3637
- * - LEMON: 4
3638
- *
3639
- * And these are the shifts for each slot:
3640
- * - LEFT: 3
3641
- * - MIDDLE: 9
3642
- * - RIGHT: 15
3643
- *
3644
- * > WIN_SEVEN is the same as SEVEN, but only used if the machine result is `777` (i.e. `value = 64`),
3645
- * > as it contains additional "blinking" animation.
3646
- *
3647
- * The sticker index is computed as follows: `SHIFTS[SLOT] + OFFSETS[SYM]`.
3648
- * For example, berries for the middle slot would be: `SHIFTS[MIDDLE] + OFFSETS[BERRIES] = 9 + 3 = 12`
3649
- *
3650
- * Currently, this sticker set is used for the machine: [SlotMachineAnimated](https://t.me/addstickers/SlotMachineAnimated)
3413
+ * Type of the file representing the sticker
3651
3414
  */
3652
- static TYPE_SLOTS = "🎰";
3415
+ get sourceType() {
3416
+ if (this.attr2?._ === "documentAttributeVideo") {
3417
+ return "video";
3418
+ }
3419
+ return this.mimeType === "application/x-tgsticker" ? "animated" : "static";
3420
+ }
3653
3421
  /**
3654
- * An emoji which was originally sent.
3655
- *
3656
- * See static members of {@link Dice} for a list
3657
- * of possible values
3422
+ * Whether this sticker has an associated public sticker set.
3658
3423
  */
3659
- get emoji() {
3660
- return this.obj.emoticon;
3424
+ get hasStickerSet() {
3425
+ return this.attr.stickerset._ === "inputStickerSetID";
3661
3426
  }
3662
3427
  /**
3663
- * Emoji's interactive value.
3664
- *
3665
- * See what this value represents in the corresponding
3666
- * type's documentation (in {@link Dice} static fields)
3428
+ * Input sticker set that it associated with this sticker, if available.
3667
3429
  */
3668
- get value() {
3669
- return this.obj.value;
3430
+ get inputStickerSet() {
3431
+ return this.attr.stickerset._ === "inputStickerSetEmpty" ? null : this.attr.stickerset;
3670
3432
  }
3671
3433
  /**
3672
- * Input media TL object generated from this object,
3673
- * to be used inside {@link InputMediaLike} and
3674
- * {@link TelegramClient.sendMedia}
3675
- *
3676
- * Note that when you use this media, a new `value`
3677
- * will be generated!
3434
+ * Position where this mask should be placed
3678
3435
  */
3679
- get inputMedia() {
3436
+ get maskPosition() {
3437
+ if (this.attr._ !== "documentAttributeSticker" || !this.attr.maskCoords) {
3438
+ return null;
3439
+ }
3440
+ const raw = this.attr.maskCoords;
3680
3441
  return {
3681
- _: "inputMediaDice",
3682
- emoticon: this.obj.emoticon
3442
+ point: MASK_POS[raw.n],
3443
+ x: raw.x,
3444
+ y: raw.y,
3445
+ scale: raw.zoom
3683
3446
  };
3684
3447
  }
3685
3448
  }
3686
- const Dice$1 = /* @__PURE__ */ conditionVariable.makeInspectable(Dice, void 0, ["inputMedia"]);
3687
- class RawDocument extends FileLocation$1 {
3688
- constructor(raw) {
3689
- super(
3690
- {
3691
- _: "inputDocumentFileLocation",
3692
- id: raw.id,
3693
- fileReference: raw.fileReference,
3694
- accessHash: raw.accessHash,
3695
- thumbSize: ""
3696
- },
3697
- raw.size,
3698
- raw.dcId
3699
- );
3700
- this.raw = raw;
3701
- this.raw = raw;
3449
+ const Sticker$1 = /* @__PURE__ */ memoizeGetters(Sticker, ["fileName", "thumbnails", "fileId", "uniqueFileId", "maskPosition"]);
3450
+ const Sticker$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Sticker$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3451
+ class Video extends RawDocument {
3452
+ constructor(doc, attr, media2) {
3453
+ super(doc);
3454
+ this.attr = attr;
3455
+ this.media = media2;
3456
+ }
3457
+ type = "video";
3458
+ _fileIdType() {
3459
+ if (this.isRound) return fileId.tdFileId.FileType.VideoNote;
3460
+ if (this.isAnimation) return fileId.tdFileId.FileType.Animation;
3461
+ return fileId.tdFileId.FileType.Video;
3702
3462
  }
3703
3463
  /**
3704
- * Original file name, extracted from the document
3705
- * attributes.
3464
+ * Video width in pixels
3706
3465
  */
3707
- get fileName() {
3708
- const attr = this.raw.attributes.find((it) => it._ === "documentAttributeFilename");
3709
- return attr?.fileName ?? null;
3466
+ get width() {
3467
+ return this.attr.w;
3710
3468
  }
3711
3469
  /**
3712
- * File MIME type, as defined by the sender.
3470
+ * Video height in pixels
3713
3471
  */
3714
- get mimeType() {
3715
- return this.raw.mimeType;
3472
+ get height() {
3473
+ return this.attr.h;
3716
3474
  }
3717
3475
  /**
3718
- * Date the document was sent
3476
+ * Video duration in seconds.
3477
+ *
3478
+ * `0` for legacy GIFs
3719
3479
  */
3720
- get date() {
3721
- return new Date(this.raw.date * 1e3);
3480
+ get duration() {
3481
+ return this.attr._ === "documentAttributeVideo" ? this.attr.duration : 0;
3722
3482
  }
3723
3483
  /**
3724
- * Available thumbnails, if any.
3725
- *
3726
- * If there are no thumbnails, the array will be empty.
3484
+ * Whether this video is an animated GIF
3485
+ * (represented either by actual GIF or a silent MP4 video)
3727
3486
  */
3728
- get thumbnails() {
3729
- const arr = [];
3730
- this.raw.thumbs?.forEach((sz) => arr.push(new Thumbnail$2(this.raw, sz)));
3731
- this.raw.videoThumbs?.forEach((sz) => arr.push(new Thumbnail$2(this.raw, sz)));
3732
- return arr;
3487
+ get isAnimation() {
3488
+ return this.attr._ === "documentAttributeImageSize" || this.raw.attributes.some((it) => it._ === "documentAttributeAnimated");
3733
3489
  }
3734
3490
  /**
3735
- * Get a thumbnail by its type.
3736
- *
3737
- * Thumbnail types are described in the
3738
- * [Telegram docs](https://core.telegram.org/api/files#image-thumbnail-types),
3739
- * and are also available as static members of {@link Thumbnail} for convenience.
3740
- *
3741
- * @param type Thumbnail type
3491
+ * Whether this video is a round video message (aka video note)
3742
3492
  */
3743
- getThumbnail(type) {
3744
- return this.thumbnails.find((it) => {
3745
- if (it.raw._ === "videoSizeEmojiMarkup" || it.raw._ === "videoSizeStickerMarkup") {
3746
- return false;
3747
- }
3748
- return it.raw.type === type;
3749
- }) ?? null;
3493
+ get isRound() {
3494
+ return this.attr._ === "documentAttributeVideo" && Boolean(this.attr.roundMessage);
3750
3495
  }
3751
3496
  /**
3752
- * Input document TL object generated from this object,
3753
- * to be used with methods that use it
3497
+ * Whether this video is a legacy GIF (i.e. its MIME is `image/gif`)
3754
3498
  */
3755
- get inputDocument() {
3756
- return {
3757
- _: "inputDocument",
3758
- id: this.raw.id,
3759
- accessHash: this.raw.accessHash,
3760
- fileReference: this.raw.fileReference
3761
- };
3499
+ get isLegacyGif() {
3500
+ return this.attr._ === "documentAttributeImageSize";
3762
3501
  }
3763
- /**
3764
- * Input media TL object generated from this object,
3765
- * to be used inside {@link InputMediaLike} and
3766
- * {@link TelegramClient.sendMedia}
3767
- */
3768
- get inputMedia() {
3769
- return {
3770
- _: "inputMediaDocument",
3771
- id: this.inputDocument
3772
- };
3502
+ /** Whether this video is hidden with a spoiler */
3503
+ get hasSpoiler() {
3504
+ return this.media?.spoiler ?? false;
3773
3505
  }
3774
- _fileIdType() {
3775
- return fileId.tdFileId.FileType.Document;
3506
+ /** For self-destructing videos, TTL in seconds */
3507
+ get ttlSeconds() {
3508
+ return this.media?.ttlSeconds ?? null;
3776
3509
  }
3777
- /**
3778
- * Get TDLib and Bot API compatible File ID
3779
- * representing this document.
3780
- */
3781
- get fileId() {
3782
- return fileId.toFileId(platform.getPlatform(), {
3783
- type: this._fileIdType(),
3784
- dcId: this.raw.dcId,
3785
- fileReference: this.raw.fileReference,
3786
- location: {
3787
- _: "common",
3788
- id: this.raw.id,
3789
- accessHash: this.raw.accessHash
3790
- }
3791
- });
3510
+ get videoStartTs() {
3511
+ return this.attr._ === "documentAttributeVideo" ? this.attr.videoStartTs ?? null : null;
3792
3512
  }
3793
- /**
3794
- * Get a unique File ID representing this document.
3795
- */
3796
- get uniqueFileId() {
3797
- return fileId.toUniqueFileId(platform.getPlatform(), fileId.tdFileId.FileType.Document, {
3798
- _: "common",
3799
- id: this.raw.id
3800
- });
3513
+ get codec() {
3514
+ return this.attr._ === "documentAttributeVideo" ? this.attr.videoCodec ?? null : null;
3801
3515
  }
3802
3516
  }
3803
- class Document extends RawDocument {
3804
- type = "document";
3805
- }
3806
- const Document$1 = /* @__PURE__ */ memoizeGetters(Document, ["fileName", "thumbnails", "fileId", "uniqueFileId"]);
3807
- const Document$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Document$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3808
- class Audio extends RawDocument {
3517
+ const Video$1 = /* @__PURE__ */ memoizeGetters(Video, ["fileName", "thumbnails", "fileId", "uniqueFileId", "isAnimation"]);
3518
+ const Video$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Video$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3519
+ class Voice extends RawDocument {
3809
3520
  constructor(doc, attr) {
3810
3521
  super(doc);
3811
3522
  this.attr = attr;
3812
3523
  }
3813
- /** Type of the media (for use in a tagged union) */
3814
- type = "audio";
3815
- /** Type of the file for File ID generation */
3524
+ type = "voice";
3816
3525
  _fileIdType() {
3817
- return fileId.tdFileId.FileType.Audio;
3526
+ return fileId.tdFileId.FileType.VoiceNote;
3818
3527
  }
3819
3528
  /**
3820
- * Duration of the audio in seconds.
3821
- *
3822
- * May not be accurate since provided by the sender.
3529
+ * Duration of the voice note in seconds.
3823
3530
  */
3824
3531
  get duration() {
3825
3532
  return this.attr.duration;
3826
3533
  }
3827
3534
  /**
3828
- * Performer of the audio track.
3535
+ * Voice note's waveform
3536
+ *
3537
+ * Represented with integers in range [0, 31],
3538
+ * usually has length of 100
3829
3539
  */
3830
- get performer() {
3831
- return this.attr.performer ?? null;
3540
+ get waveform() {
3541
+ return conditionVariable.decodeWaveform(this.attr.waveform);
3542
+ }
3543
+ }
3544
+ const Voice$1 = /* @__PURE__ */ memoizeGetters(Voice, ["fileName", "thumbnails", "fileId", "uniqueFileId", "waveform"]);
3545
+ const Voice$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Voice$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument", "waveform"]);
3546
+ function parseSticker(doc) {
3547
+ const stickerAttr = doc.attributes.find(
3548
+ (a) => a._ === "documentAttributeSticker" || a._ === "documentAttributeCustomEmoji"
3549
+ );
3550
+ if (stickerAttr) {
3551
+ const sz = doc.attributes.find(
3552
+ (it) => it._ === "documentAttributeImageSize" || it._ === "documentAttributeVideo"
3553
+ );
3554
+ return new Sticker$2(doc, stickerAttr, sz);
3555
+ }
3556
+ }
3557
+ function parseDocument(doc, media2) {
3558
+ const sticker2 = parseSticker(doc);
3559
+ if (sticker2) return sticker2;
3560
+ for (const attr of doc.attributes) {
3561
+ switch (attr._) {
3562
+ case "documentAttributeAudio":
3563
+ if (attr.voice) {
3564
+ return new Voice$2(doc, attr);
3565
+ }
3566
+ return new Audio$2(doc, attr);
3567
+ case "documentAttributeVideo":
3568
+ return new Video$2(doc, attr, media2);
3569
+ case "documentAttributeImageSize":
3570
+ if (doc.mimeType === "image/gif") {
3571
+ return new Video$2(doc, attr, media2);
3572
+ }
3573
+ }
3574
+ }
3575
+ return new Document$2(doc);
3576
+ }
3577
+ class StarGift {
3578
+ constructor(raw) {
3579
+ this.raw = raw;
3580
+ }
3581
+ /** ID of the gift */
3582
+ get id() {
3583
+ return this.raw.id;
3584
+ }
3585
+ /** Sticker associated with the gift */
3586
+ get sticker() {
3587
+ controllablePromise.assertTypeIs("StarGift#sticker", this.raw.sticker, "document");
3588
+ const parsed = parseDocument(this.raw.sticker);
3589
+ if (parsed.type !== "sticker") {
3590
+ throw new platform.MtTypeAssertionError("StarGift#sticker", "sticker", parsed.type);
3591
+ }
3592
+ return parsed;
3593
+ }
3594
+ /** Amount of stars the gift was purchased for */
3595
+ get purchaseStars() {
3596
+ return this.raw.stars;
3832
3597
  }
3833
3598
  /**
3834
- * Title of the audio track.
3599
+ * Amount of stars the gift can be converted to by the recipient
3835
3600
  */
3836
- get title() {
3837
- return this.attr.title ?? null;
3601
+ get convertStars() {
3602
+ return this.raw.convertStars;
3603
+ }
3604
+ /**
3605
+ * For limited availability gifts,
3606
+ * the number of remaining and total gifts available
3607
+ */
3608
+ get availability() {
3609
+ if (!this.raw.availabilityRemains || !this.raw.availabilityTotal) {
3610
+ return null;
3611
+ }
3612
+ return {
3613
+ remains: this.raw.availabilityRemains,
3614
+ total: this.raw.availabilityTotal
3615
+ };
3616
+ }
3617
+ }
3618
+ const StarGift$1 = /* @__PURE__ */ conditionVariable.makeInspectable(StarGift);
3619
+ const StarGift$2 = /* @__PURE__ */ memoizeGetters(StarGift$1, ["sticker"]);
3620
+ class UserStarGift {
3621
+ constructor(raw, peers) {
3622
+ this.raw = raw;
3623
+ this.peers = peers;
3624
+ }
3625
+ /** Whether the sender chose to appear anonymously */
3626
+ get nameHidden() {
3627
+ return this.raw.nameHidden;
3628
+ }
3629
+ /** Whether this gift is not visible on the recipient's profile */
3630
+ get hidden() {
3631
+ return this.raw.unsaved;
3632
+ }
3633
+ /** Sender of the gift, if available */
3634
+ get sender() {
3635
+ return this.raw.fromId ? new User$2(this.peers.user(this.raw.fromId)) : null;
3636
+ }
3637
+ /** Message ID where the gift was sent, if available */
3638
+ get messageId() {
3639
+ return this.raw.msgId ?? null;
3640
+ }
3641
+ /** Date the gift was sent */
3642
+ get date() {
3643
+ return new Date(this.raw.date * 1e3);
3644
+ }
3645
+ /** The gift itself */
3646
+ get gift() {
3647
+ return new StarGift(this.raw.gift);
3648
+ }
3649
+ /** Text attached to the gift */
3650
+ get text() {
3651
+ return this.raw.message ?? null;
3652
+ }
3653
+ /**
3654
+ * If the gift was converted to stars, the amount of stars
3655
+ * it was converted to
3656
+ */
3657
+ get convertStars() {
3658
+ return this.raw.convertStars ?? null;
3659
+ }
3660
+ }
3661
+ const UserStarGift$1 = /* @__PURE__ */ conditionVariable.makeInspectable(UserStarGift);
3662
+ const UserStarGift$2 = /* @__PURE__ */ memoizeGetters(UserStarGift$1, ["sender", "gift"]);
3663
+ function _messageActionFromTl(act) {
3664
+ switch (act._) {
3665
+ case "messageActionChatCreate":
3666
+ return {
3667
+ type: "chat_created",
3668
+ title: act.title,
3669
+ users: act.users
3670
+ };
3671
+ case "messageActionChannelCreate":
3672
+ return {
3673
+ type: "channel_created",
3674
+ title: act.title
3675
+ };
3676
+ case "messageActionChatMigrateTo":
3677
+ return {
3678
+ type: "chat_migrate_to",
3679
+ id: act.channelId
3680
+ };
3681
+ case "messageActionChannelMigrateFrom":
3682
+ return {
3683
+ type: "channel_migrate_from",
3684
+ id: act.chatId,
3685
+ title: act.title
3686
+ };
3687
+ case "messageActionPinMessage":
3688
+ return {
3689
+ type: "message_pinned"
3690
+ };
3691
+ case "messageActionHistoryClear":
3692
+ return {
3693
+ type: "history_cleared"
3694
+ };
3695
+ case "messageActionGameScore":
3696
+ return {
3697
+ type: "game_score",
3698
+ gameId: act.gameId,
3699
+ score: act.score
3700
+ };
3701
+ case "messageActionContactSignUp":
3702
+ return {
3703
+ type: "contact_joined"
3704
+ };
3705
+ case "messageActionChatEditTitle":
3706
+ return {
3707
+ type: "title_changed",
3708
+ title: act.title
3709
+ };
3710
+ case "messageActionChatEditPhoto":
3711
+ return {
3712
+ type: "photo_changed",
3713
+ photo: new Photo$2(act.photo)
3714
+ };
3715
+ case "messageActionChatDeletePhoto":
3716
+ return {
3717
+ type: "photo_deleted"
3718
+ };
3719
+ case "messageActionChatAddUser":
3720
+ return {
3721
+ type: "users_added",
3722
+ users: act.users
3723
+ };
3724
+ case "messageActionChatDeleteUser":
3725
+ if (this.raw.fromId?._ === "peerUser" && act.userId === this.raw.fromId.userId) {
3726
+ return {
3727
+ type: "user_left"
3728
+ };
3729
+ }
3730
+ return {
3731
+ type: "user_removed",
3732
+ user: act.userId
3733
+ };
3734
+ case "messageActionChatJoinedByLink":
3735
+ return {
3736
+ type: "user_joined_link",
3737
+ inviter: act.inviterId
3738
+ };
3739
+ case "messageActionPaymentSentMe":
3740
+ return {
3741
+ type: "payment_received",
3742
+ currency: act.currency,
3743
+ amount: act.totalAmount,
3744
+ payload: act.payload,
3745
+ info: act.info,
3746
+ shippingOptionId: act.shippingOptionId,
3747
+ charge: act.charge
3748
+ };
3749
+ case "messageActionPaymentSent":
3750
+ return {
3751
+ type: "payment_sent",
3752
+ currency: act.currency,
3753
+ amount: act.totalAmount
3754
+ };
3755
+ case "messageActionPhoneCall":
3756
+ return {
3757
+ type: "call",
3758
+ id: act.callId,
3759
+ isVideo: Boolean(act.video),
3760
+ reason: act.reason ? _callDiscardReasonFromTl(act.reason) : void 0,
3761
+ duration: act.duration ?? 0
3762
+ };
3763
+ case "messageActionScreenshotTaken":
3764
+ return {
3765
+ type: "screenshot_taken"
3766
+ };
3767
+ case "messageActionBotAllowed":
3768
+ return {
3769
+ type: "bot_allowed",
3770
+ domain: act.domain
3771
+ };
3772
+ case "messageActionGeoProximityReached":
3773
+ if (act.fromId._ !== "peerUser" || act.toId._ !== "peerUser") {
3774
+ return null;
3775
+ }
3776
+ return {
3777
+ type: "geo_proximity",
3778
+ targetId: act.toId.userId,
3779
+ userId: act.fromId.userId,
3780
+ distance: act.distance
3781
+ };
3782
+ case "messageActionGroupCall":
3783
+ if (act.duration) {
3784
+ return {
3785
+ type: "group_call_ended",
3786
+ call: act.call,
3787
+ duration: act.duration
3788
+ };
3789
+ }
3790
+ return {
3791
+ type: "group_call_started",
3792
+ call: act.call
3793
+ };
3794
+ case "messageActionGroupCallScheduled":
3795
+ return {
3796
+ type: "group_call_scheduled",
3797
+ call: act.call,
3798
+ date: new Date(act.scheduleDate * 1e3)
3799
+ };
3800
+ case "messageActionInviteToGroupCall":
3801
+ return {
3802
+ type: "group_call_invite",
3803
+ call: act.call,
3804
+ userIds: act.users
3805
+ };
3806
+ case "messageActionSetMessagesTTL":
3807
+ return {
3808
+ type: "ttl_changed",
3809
+ period: act.period
3810
+ };
3811
+ case "messageActionTopicCreate":
3812
+ return {
3813
+ type: "topic_created",
3814
+ title: act.title,
3815
+ iconColor: act.iconColor,
3816
+ iconCustomEmoji: act.iconEmojiId
3817
+ };
3818
+ case "messageActionTopicEdit":
3819
+ return {
3820
+ type: "topic_edited",
3821
+ title: act.title,
3822
+ iconCustomEmoji: act.iconEmojiId,
3823
+ closed: act.closed,
3824
+ hidden: act.hidden
3825
+ };
3826
+ case "messageActionCustomAction":
3827
+ return {
3828
+ type: "custom",
3829
+ action: act.message
3830
+ };
3831
+ case "messageActionSetChatTheme":
3832
+ return {
3833
+ type: "theme_changed",
3834
+ emoji: act.emoticon
3835
+ };
3836
+ case "messageActionChatJoinedByRequest":
3837
+ return {
3838
+ type: "user_joined_approved"
3839
+ };
3840
+ case "messageActionWebViewDataSent":
3841
+ return {
3842
+ type: "webview_sent",
3843
+ text: act.text
3844
+ };
3845
+ case "messageActionWebViewDataSentMe":
3846
+ return {
3847
+ type: "webview_received",
3848
+ text: act.text,
3849
+ data: act.data
3850
+ };
3851
+ case "messageActionGiftPremium":
3852
+ return {
3853
+ type: "premium_gifted",
3854
+ currency: act.currency,
3855
+ amount: act.amount.toNumber(),
3856
+ months: act.months,
3857
+ crypto: act.cryptoAmount ? {
3858
+ currency: act.cryptoCurrency,
3859
+ amount: act.cryptoAmount.toNumber()
3860
+ } : void 0
3861
+ };
3862
+ case "messageActionSuggestProfilePhoto":
3863
+ return {
3864
+ type: "photo_suggested",
3865
+ photo: new Photo$2(act.photo)
3866
+ };
3867
+ case "messageActionRequestedPeerSentMe":
3868
+ return {
3869
+ type: "peer_sent",
3870
+ buttonId: act.buttonId,
3871
+ peers: act.peers
3872
+ };
3873
+ case "messageActionRequestedPeer":
3874
+ return {
3875
+ type: "peer_chosen",
3876
+ buttonId: act.buttonId,
3877
+ peers: act.peers.map((it) => parsePeer(it, this._peers))
3878
+ };
3879
+ case "messageActionSetChatWallPaper":
3880
+ return {
3881
+ type: "wallpaper_changed",
3882
+ same: act.same,
3883
+ forBoth: act.forBoth,
3884
+ wallpaper: act.wallpaper
3885
+ };
3886
+ case "messageActionGiftCode":
3887
+ return {
3888
+ type: "gift_code",
3889
+ raw: act
3890
+ };
3891
+ case "messageActionGiveawayLaunch":
3892
+ return {
3893
+ type: "giveaway_started"
3894
+ };
3895
+ case "messageActionGiveawayResults":
3896
+ return {
3897
+ type: "giveaway_ended",
3898
+ winners: act.winnersCount,
3899
+ undistributed: act.unclaimedCount
3900
+ };
3901
+ case "messageActionBoostApply":
3902
+ return {
3903
+ type: "boost_apply",
3904
+ count: act.boosts
3905
+ };
3906
+ case "messageActionPaymentRefunded":
3907
+ return {
3908
+ type: "payment_refunded",
3909
+ currency: act.currency,
3910
+ peerId: conditionVariable.getMarkedPeerId(act.peer),
3911
+ amount: act.totalAmount,
3912
+ payload: act.payload,
3913
+ charge: act.charge
3914
+ };
3915
+ case "messageActionGiftStars":
3916
+ return {
3917
+ type: "stars_gifted",
3918
+ isCrypto: Boolean(act.cryptoCurrency),
3919
+ currency: act.cryptoCurrency ?? act.currency,
3920
+ amount: act.cryptoAmount ?? act.amount,
3921
+ stars: act.stars,
3922
+ transactionId: act.transactionId
3923
+ };
3924
+ case "messageActionPrizeStars":
3925
+ return {
3926
+ type: "stars_prize",
3927
+ claimed: !act.unclaimed,
3928
+ stars: act.stars,
3929
+ transactionId: act.transactionId,
3930
+ boostPeer: parsePeer(act.boostPeer, this._peers),
3931
+ giveawayMessageId: act.giveawayMsgId
3932
+ };
3933
+ case "messageActionStarGift":
3934
+ return {
3935
+ type: "stars_gift",
3936
+ nameHidden: act.nameHidden,
3937
+ saved: act.saved,
3938
+ converted: act.converted,
3939
+ convertStars: act.convertStars,
3940
+ gift: new StarGift$2(act.gift),
3941
+ message: act.message ?? null
3942
+ };
3943
+ default:
3944
+ return null;
3838
3945
  }
3839
3946
  }
3840
- const Audio$1 = /* @__PURE__ */ memoizeGetters(Audio, ["fileName", "thumbnails", "fileId", "uniqueFileId"]);
3841
- const Audio$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Audio$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3842
- const MASK_POSITION_POINT_TO_TL = {
3843
- forehead: 0,
3844
- eyes: 1,
3845
- mouth: 2,
3846
- chin: 3
3847
- };
3848
- const MASK_POS = ["forehead", "eyes", "mouth", "chin"];
3849
- class Sticker extends RawDocument {
3850
- constructor(doc, attr, attr2) {
3851
- super(doc);
3852
- this.attr = attr;
3853
- this.attr2 = attr2;
3854
- }
3855
- type = "sticker";
3856
- _fileIdType() {
3857
- return fileId.tdFileId.FileType.Sticker;
3858
- }
3859
- /**
3860
- * Sticker width in pixels
3861
- */
3862
- get width() {
3863
- return this.attr2?.w ?? 512;
3947
+ class MessageForwardInfo {
3948
+ constructor(raw, _peers) {
3949
+ this.raw = raw;
3950
+ this._peers = _peers;
3864
3951
  }
3865
3952
  /**
3866
- * Sticker height in pixels
3953
+ * Date the original message was sent
3867
3954
  */
3868
- get height() {
3869
- return this.attr2?.h ?? 512;
3955
+ get date() {
3956
+ return new Date(this.raw.date * 1e3);
3870
3957
  }
3871
3958
  /**
3872
- * Whether this sticker is a premium sticker
3873
- * (has premium fullscreen animation)
3959
+ * Sender of the original message (either user or a channel)
3960
+ * or their name (for users with private forwards)
3874
3961
  */
3875
- get isPremiumSticker() {
3876
- return Boolean(this.raw.videoThumbs?.some((s) => s._ === "videoSize" && s.type === "f"));
3962
+ get sender() {
3963
+ if (this.raw.fromName) {
3964
+ return {
3965
+ type: "anonymous",
3966
+ displayName: this.raw.fromName
3967
+ };
3968
+ }
3969
+ if (this.raw.fromId) {
3970
+ return parsePeer(this.raw.fromId, this._peers);
3971
+ }
3972
+ throw new platform.MtTypeAssertionError("MessageForwardInfo", "to have fromId or fromName", "neither");
3877
3973
  }
3878
3974
  /**
3879
- * Whether this sticker is a valid sticker.
3880
- *
3881
- * If it is not, then this is probably a WEBP photo
3882
- * that Telegram treats as a sticker.
3975
+ * For "saved" messages (i.e. messages forwarded to yourself,
3976
+ * "Saved Messages"), the peer where the message was originally sent
3883
3977
  */
3884
- get isValidSticker() {
3885
- return this.attr2 !== void 0 && (this.attr2.w === 512 || this.attr2.h === 512);
3978
+ fromChat() {
3979
+ if (!this.raw.savedFromPeer) return null;
3980
+ return Chat$2._parseFromPeer(this.raw.savedFromPeer, this._peers);
3886
3981
  }
3887
3982
  /**
3888
- * Primary emoji associated with this sticker,
3889
- * that is displayed in dialogs list.
3890
- *
3891
- * If there is none, empty string is returned.
3892
- *
3893
- * **Note:** This only contains at most one emoji.
3894
- * Some stickers have multiple associated emojis,
3895
- * but only one is returned here. This is Telegram's
3896
- * limitation! Use {@link getAllEmojis} instead.
3897
- *
3898
- * For custom emojis, this alt should be used as a fallback
3899
- * text that will be "behind" the custom emoji entity.
3983
+ * For messages forwarded from channels,
3984
+ * identifier of the original message in the channel
3900
3985
  */
3901
- get emoji() {
3902
- return this.attr.alt;
3986
+ get fromMessageId() {
3987
+ return this.raw.savedFromMsgId ?? null;
3903
3988
  }
3904
3989
  /**
3905
- * Whether this custom emoji can be used by non-premium users.
3906
- * `false` if this is not a custom emoji.
3907
- *
3908
- * > Not sure if there are any such stickers currently.
3990
+ * For messages forwarded from channels,
3991
+ * signature of the post author (if present)
3909
3992
  */
3910
- get customEmojiFree() {
3911
- return this.attr._ === "documentAttributeCustomEmoji" ? this.attr.free ?? false : false;
3993
+ get signature() {
3994
+ return this.raw.postAuthor ?? null;
3912
3995
  }
3913
- /**
3914
- * If this is a custom emoji, its unique ID
3915
- * that can be used in {@link TelegramClient#getCustomEmojis}
3916
- */
3917
- get customEmojiId() {
3918
- if (this.attr._ !== "documentAttributeCustomEmoji") {
3919
- throw new platform.MtArgumentError("This is not a custom emoji");
3920
- }
3921
- return this.raw.id;
3996
+ }
3997
+ const MessageForwardInfo$1 = /* @__PURE__ */ memoizeGetters(MessageForwardInfo, ["sender", "fromChat"]);
3998
+ const MessageForwardInfo$2 = /* @__PURE__ */ conditionVariable.makeInspectable(MessageForwardInfo$1);
3999
+ class Contact {
4000
+ constructor(obj) {
4001
+ this.obj = obj;
3922
4002
  }
4003
+ type = "contact";
3923
4004
  /**
3924
- * Type of the sticker
4005
+ * Contact's phone number
3925
4006
  */
3926
- get stickerType() {
3927
- if (this.attr._ === "documentAttributeSticker") {
3928
- return this.attr.mask ? "mask" : "sticker";
3929
- } else if (this.attr._ === "documentAttributeCustomEmoji") {
3930
- return "emoji";
3931
- }
3932
- return "sticker";
4007
+ get phoneNumber() {
4008
+ return this.obj.phoneNumber;
3933
4009
  }
3934
4010
  /**
3935
- * Type of the file representing the sticker
4011
+ * Contact's first name
3936
4012
  */
3937
- get sourceType() {
3938
- if (this.attr2?._ === "documentAttributeVideo") {
3939
- return "video";
3940
- }
3941
- return this.mimeType === "application/x-tgsticker" ? "animated" : "static";
4013
+ get firstName() {
4014
+ return this.obj.firstName;
3942
4015
  }
3943
4016
  /**
3944
- * Whether this sticker has an associated public sticker set.
4017
+ * Contact's last name
3945
4018
  */
3946
- get hasStickerSet() {
3947
- return this.attr.stickerset._ === "inputStickerSetID";
4019
+ get lastName() {
4020
+ return this.obj.lastName;
3948
4021
  }
3949
4022
  /**
3950
- * Input sticker set that it associated with this sticker, if available.
4023
+ * Contact's user ID in Telegram or `0` if not available
3951
4024
  */
3952
- get inputStickerSet() {
3953
- return this.attr.stickerset._ === "inputStickerSetEmpty" ? null : this.attr.stickerset;
4025
+ get userId() {
4026
+ return this.obj.userId;
3954
4027
  }
3955
4028
  /**
3956
- * Position where this mask should be placed
4029
+ * Input media TL object generated from this object,
4030
+ * to be used inside {@link InputMediaLike} and
4031
+ * {@link TelegramClient.sendMedia}
3957
4032
  */
3958
- get maskPosition() {
3959
- if (this.attr._ !== "documentAttributeSticker" || !this.attr.maskCoords) {
3960
- return null;
3961
- }
3962
- const raw = this.attr.maskCoords;
4033
+ get inputMedia() {
3963
4034
  return {
3964
- point: MASK_POS[raw.n],
3965
- x: raw.x,
3966
- y: raw.y,
3967
- scale: raw.zoom
4035
+ ...this.obj,
4036
+ _: "inputMediaContact"
3968
4037
  };
3969
4038
  }
3970
4039
  }
3971
- const Sticker$1 = /* @__PURE__ */ memoizeGetters(Sticker, ["fileName", "thumbnails", "fileId", "uniqueFileId", "maskPosition"]);
3972
- const Sticker$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Sticker$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
3973
- class Video extends RawDocument {
3974
- constructor(doc, attr, media2) {
3975
- super(doc);
3976
- this.attr = attr;
3977
- this.media = media2;
3978
- }
3979
- type = "video";
3980
- _fileIdType() {
3981
- if (this.isRound) return fileId.tdFileId.FileType.VideoNote;
3982
- if (this.isAnimation) return fileId.tdFileId.FileType.Animation;
3983
- return fileId.tdFileId.FileType.Video;
4040
+ const Contact$1 = /* @__PURE__ */ conditionVariable.makeInspectable(Contact, void 0, ["inputMedia"]);
4041
+ class Dice {
4042
+ constructor(obj) {
4043
+ this.obj = obj;
3984
4044
  }
4045
+ type = "dice";
3985
4046
  /**
3986
- * Video width in pixels
4047
+ * A simple 6-sided dice.
4048
+ *
4049
+ * {@link value} represents its value (1-6)
3987
4050
  */
3988
- get width() {
3989
- return this.attr.w;
3990
- }
4051
+ static TYPE_DICE = "🎲";
3991
4052
  /**
3992
- * Video height in pixels
4053
+ * A dart. Telegram dart has 4 rings and middle.
4054
+ *
4055
+ * {@link value} represents the position of the dart:
4056
+ * ![Dart position graph](https://i.imgur.com/iPBm7HG.png)
3993
4057
  */
3994
- get height() {
3995
- return this.attr.h;
3996
- }
4058
+ static TYPE_DART = "🎯";
3997
4059
  /**
3998
- * Video duration in seconds.
4060
+ * A basketball thrown into a hoop.
3999
4061
  *
4000
- * `0` for legacy GIFs
4062
+ * {@link value} represents the motion of the ball:
4063
+ * - 1: simple miss (ball hits right part, bounces to the left)
4064
+ * - 2: first hit the ring, then miss
4065
+ * - 3: ball gets stuck between the ring and the base
4066
+ * - 4: first hit the ring, then score
4067
+ * - 5: direct score
4001
4068
  */
4002
- get duration() {
4003
- return this.attr._ === "documentAttributeVideo" ? this.attr.duration : 0;
4004
- }
4069
+ static TYPE_BASKETBALL = "🏀";
4005
4070
  /**
4006
- * Whether this video is an animated GIF
4007
- * (represented either by actual GIF or a silent MP4 video)
4071
+ * A football thrown to the gate.
4072
+ *
4073
+ * {@link value} represents the motion of the ball:
4074
+ * - 1: flies above the top barbell
4075
+ * - 2: hits right barbell, then miss
4076
+ * - 3: direct score in the middle
4077
+ * - 4: hits left barbell, then score, then hits right barbell
4078
+ * - 5: score in the top-right corner
4008
4079
  */
4009
- get isAnimation() {
4010
- return this.attr._ === "documentAttributeImageSize" || this.raw.attributes.some((it) => it._ === "documentAttributeAnimated");
4011
- }
4080
+ static TYPE_FOOTBALL = "⚽️";
4012
4081
  /**
4013
- * Whether this video is a round video message (aka video note)
4082
+ * A bowling ball thrown to pins.
4083
+ *
4084
+ * Assuming the following identifiers for the pins:
4085
+ * ```
4086
+ * 4 5 6
4087
+ * 2 3
4088
+ * 1
4089
+ * ```
4090
+ *
4091
+ * {@link value} represents the motion of the ball and pins:
4092
+ * - 1: the ball touched 6th pin, none are down
4093
+ * - 2: the ball hit 4th pin, only 4th pin is down.
4094
+ * - 3: the ball hit 1st pin, pins 1, 2, 5 are down, leaving pins 3, 4, 6
4095
+ * - 4: the ball hit 1st pin on the right side, all the pins except 2nd and 6th are down
4096
+ * - 5: the ball hit 3rd pin and all the pins except 2nd are down.
4097
+ * - 6: the ball hit 1st pin and all pins are down
4014
4098
  */
4015
- get isRound() {
4016
- return this.attr._ === "documentAttributeVideo" && Boolean(this.attr.roundMessage);
4017
- }
4099
+ static TYPE_BOWLING = "🎳";
4018
4100
  /**
4019
- * Whether this video is a legacy GIF (i.e. its MIME is `image/gif`)
4101
+ * A slot machine.
4102
+ *
4103
+ * {@link value} represents the result of the machine.
4104
+ * Value itself is an integer in range `[1, 64]`,
4105
+ * and is composed out of several parts.
4106
+ *
4107
+ * > **Note**: The following information is based on the TDesktop
4108
+ * > implementation. These are the relevant files:
4109
+ * > - [`chat_helpers/stickers_dice_pack.cpp`](https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp)
4110
+ * > - [`history/view/media/history_view_slot_machine.cpp`](https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/history/view/media/history_view_slot_machine.cpp)
4111
+ *
4112
+ * Unlike other animated dices, this does not have
4113
+ * all the possible combinations in the sticker set.
4114
+ * Instead, `value` is a specially encoded integer that contains
4115
+ * the information about the indexes.
4116
+ *
4117
+ * There are some base parts of the animations:
4118
+ * - 0th sticker is the base background of the machine
4119
+ * - 1st sticker is the background of the machine for the "winning" state (i.e. `777`)
4120
+ * - 2nd sticker is the frame of the machine, including the handle
4121
+ * - 8th sticker is the "idle" state for the left slot
4122
+ * - 14th sticker is the "idle" state for the middle slot
4123
+ * - 20th sticker is the "idle" state for the right slot
4124
+ *
4125
+ * The machine result is encoded as 3 concatenated two-bit integers,
4126
+ * and the resulting integer is incremented by one.
4127
+ *
4128
+ * So, to decode the value to its parts, you can use this code:
4129
+ * ```typescript
4130
+ * const computePartValue = (val: number, idx: number) => ((val - 1) >> (idx * 2)) & 0x03; // 0..3
4131
+ * const parts = [
4132
+ * computePartValue(msg.media.value, 0),
4133
+ * computePartValue(msg.media.value, 1),
4134
+ * computePartValue(msg.media.value, 2),
4135
+ * ]
4136
+ * ```
4137
+ *
4138
+ * Each part of the value corresponds to a particular slot (i.e. part 0 is left slot,
4139
+ * part 1 is middle, part 2 is right). The slot values are as follows:
4140
+ * - 0: BAR (displayed as a *BAR* sign on a black background)
4141
+ * - 1: BERRIES (displayed as berries, similar to emoji 🍇)
4142
+ * - 2: LEMON (displayed as a lemon, similar to emoji 🍋)
4143
+ * - 3: SEVEN (displayed as a red digit 7)
4144
+ *
4145
+ * Therefore, the winning value (i.e. `777`) is represented as `(3 << 4 | 3 << 2 | 3 << 0) + 1 = 64`
4146
+ *
4147
+ * To determine the needed animation parts, you'll need to apply some shifts.
4148
+ * These are the offsets for the individual symbols:
4149
+ * - WIN_SEVEN: 0
4150
+ * - SEVEN: 1
4151
+ * - BAR: 2
4152
+ * - BERRIES: 3
4153
+ * - LEMON: 4
4154
+ *
4155
+ * And these are the shifts for each slot:
4156
+ * - LEFT: 3
4157
+ * - MIDDLE: 9
4158
+ * - RIGHT: 15
4159
+ *
4160
+ * > WIN_SEVEN is the same as SEVEN, but only used if the machine result is `777` (i.e. `value = 64`),
4161
+ * > as it contains additional "blinking" animation.
4162
+ *
4163
+ * The sticker index is computed as follows: `SHIFTS[SLOT] + OFFSETS[SYM]`.
4164
+ * For example, berries for the middle slot would be: `SHIFTS[MIDDLE] + OFFSETS[BERRIES] = 9 + 3 = 12`
4165
+ *
4166
+ * Currently, this sticker set is used for the machine: [SlotMachineAnimated](https://t.me/addstickers/SlotMachineAnimated)
4020
4167
  */
4021
- get isLegacyGif() {
4022
- return this.attr._ === "documentAttributeImageSize";
4023
- }
4024
- /** Whether this video is hidden with a spoiler */
4025
- get hasSpoiler() {
4026
- return this.media?.spoiler ?? false;
4027
- }
4028
- /** For self-destructing videos, TTL in seconds */
4029
- get ttlSeconds() {
4030
- return this.media?.ttlSeconds ?? null;
4031
- }
4032
- get videoStartTs() {
4033
- return this.attr._ === "documentAttributeVideo" ? this.attr.videoStartTs ?? null : null;
4034
- }
4035
- }
4036
- const Video$1 = /* @__PURE__ */ memoizeGetters(Video, ["fileName", "thumbnails", "fileId", "uniqueFileId", "isAnimation"]);
4037
- const Video$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Video$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument"]);
4038
- class Voice extends RawDocument {
4039
- constructor(doc, attr) {
4040
- super(doc);
4041
- this.attr = attr;
4042
- }
4043
- type = "voice";
4044
- _fileIdType() {
4045
- return fileId.tdFileId.FileType.VoiceNote;
4046
- }
4168
+ static TYPE_SLOTS = "🎰";
4047
4169
  /**
4048
- * Duration of the voice note in seconds.
4170
+ * An emoji which was originally sent.
4171
+ *
4172
+ * See static members of {@link Dice} for a list
4173
+ * of possible values
4049
4174
  */
4050
- get duration() {
4051
- return this.attr.duration;
4175
+ get emoji() {
4176
+ return this.obj.emoticon;
4052
4177
  }
4053
4178
  /**
4054
- * Voice note's waveform
4179
+ * Emoji's interactive value.
4055
4180
  *
4056
- * Represented with integers in range [0, 31],
4057
- * usually has length of 100
4181
+ * See what this value represents in the corresponding
4182
+ * type's documentation (in {@link Dice} static fields)
4058
4183
  */
4059
- get waveform() {
4060
- return conditionVariable.decodeWaveform(this.attr.waveform);
4061
- }
4062
- }
4063
- const Voice$1 = /* @__PURE__ */ memoizeGetters(Voice, ["fileName", "thumbnails", "fileId", "uniqueFileId", "waveform"]);
4064
- const Voice$2 = /* @__PURE__ */ conditionVariable.makeInspectable(Voice$1, ["fileSize", "dcId"], ["inputMedia", "inputDocument", "waveform"]);
4065
- function parseSticker(doc) {
4066
- const stickerAttr = doc.attributes.find(
4067
- (a) => a._ === "documentAttributeSticker" || a._ === "documentAttributeCustomEmoji"
4068
- );
4069
- if (stickerAttr) {
4070
- const sz = doc.attributes.find(
4071
- (it) => it._ === "documentAttributeImageSize" || it._ === "documentAttributeVideo"
4072
- );
4073
- return new Sticker$2(doc, stickerAttr, sz);
4184
+ get value() {
4185
+ return this.obj.value;
4074
4186
  }
4075
- }
4076
- function parseDocument(doc, media2) {
4077
- const sticker2 = parseSticker(doc);
4078
- if (sticker2) return sticker2;
4079
- for (const attr of doc.attributes) {
4080
- switch (attr._) {
4081
- case "documentAttributeAudio":
4082
- if (attr.voice) {
4083
- return new Voice$2(doc, attr);
4084
- }
4085
- return new Audio$2(doc, attr);
4086
- case "documentAttributeVideo":
4087
- return new Video$2(doc, attr, media2);
4088
- case "documentAttributeImageSize":
4089
- if (doc.mimeType === "image/gif") {
4090
- return new Video$2(doc, attr, media2);
4091
- }
4092
- }
4187
+ /**
4188
+ * Input media TL object generated from this object,
4189
+ * to be used inside {@link InputMediaLike} and
4190
+ * {@link TelegramClient.sendMedia}
4191
+ *
4192
+ * Note that when you use this media, a new `value`
4193
+ * will be generated!
4194
+ */
4195
+ get inputMedia() {
4196
+ return {
4197
+ _: "inputMediaDice",
4198
+ emoticon: this.obj.emoticon
4199
+ };
4093
4200
  }
4094
- return new Document$2(doc);
4095
4201
  }
4202
+ const Dice$1 = /* @__PURE__ */ conditionVariable.makeInspectable(Dice, void 0, ["inputMedia"]);
4096
4203
  class Game {
4097
4204
  constructor(game2) {
4098
4205
  this.game = game2;
@@ -6660,6 +6767,7 @@ async function uploadFile(client, params) {
6660
6767
  if (HAS_FILE && file2 instanceof File) {
6661
6768
  fileName = file2.name;
6662
6769
  fileSize = file2.size;
6770
+ fileMime = file2.type;
6663
6771
  file2 = file2.stream();
6664
6772
  }
6665
6773
  if (HAS_URL && file2 instanceof URL) {
@@ -6789,6 +6897,18 @@ async function uploadFile(client, params) {
6789
6897
  if (fileName === void 0) {
6790
6898
  const ext = MIME_TO_EXTENSION[fileMime];
6791
6899
  fileName = ext ? `${DEFAULT_FILE_NAME}.${ext}` : DEFAULT_FILE_NAME;
6900
+ } else if (params.requireExtension) {
6901
+ const extFromMime = MIME_TO_EXTENSION[fileMime];
6902
+ const idx2 = fileName.lastIndexOf(".");
6903
+ const extFromName = idx2 === -1 ? void 0 : fileName.slice(idx2 + 1);
6904
+ if (!extFromName) {
6905
+ if (!extFromMime) {
6906
+ throw new platform.MtArgumentError(`File name does not have an extension, and we cannot guess it from the mime type (${fileMime})`);
6907
+ }
6908
+ fileName = `${fileName}.${extFromMime}`;
6909
+ } else if (extFromMime && extFromName !== extFromMime) {
6910
+ throw new platform.MtArgumentError(`File name has ${extFromName} extension (${fileName}), but the mime type (${fileMime}) expects it to be ${extFromMime}`);
6911
+ }
6792
6912
  }
6793
6913
  let inputFile;
6794
6914
  if (isBig) {
@@ -7028,7 +7148,8 @@ async function _normalizeInputMedia(client, media2, params = {}, uploadMedia = f
7028
7148
  fileName: media2.fileName,
7029
7149
  fileMime: sendMime,
7030
7150
  fileSize: media2.fileSize,
7031
- requireFileSize: media2.type === "photo"
7151
+ requireFileSize: media2.type === "photo",
7152
+ requireExtension: media2.type === "photo"
7032
7153
  });
7033
7154
  inputFile = uploaded.inputFile;
7034
7155
  mime = uploaded.mime;
@@ -8233,18 +8354,6 @@ class StickerSet {
8233
8354
  }
8234
8355
  return "sticker";
8235
8356
  }
8236
- /**
8237
- * Source file type of the stickers in this set
8238
- */
8239
- get sourceType() {
8240
- if (this.brief.animated) {
8241
- return "animated";
8242
- }
8243
- if (this.brief.videos) {
8244
- return "video";
8245
- }
8246
- return "static";
8247
- }
8248
8357
  /**
8249
8358
  * Date when this sticker set was installed
8250
8359
  */
@@ -9782,6 +9891,13 @@ class StarsTransaction {
9782
9891
  messageId: this.raw.giveawayPostId
9783
9892
  };
9784
9893
  }
9894
+ if (this.raw.stargift) {
9895
+ return {
9896
+ type: "star_gift",
9897
+ peer,
9898
+ gift: new StarGift$2(this.raw.stargift)
9899
+ };
9900
+ }
9785
9901
  if (this.raw.msgId) {
9786
9902
  if (this.raw.reaction) {
9787
9903
  return {
@@ -10100,6 +10216,7 @@ exports.ReactionCount$1 = ReactionCount$1;
10100
10216
  exports.RepliedMessageInfo$2 = RepliedMessageInfo$2;
10101
10217
  exports.SearchFilters = SearchFilters;
10102
10218
  exports.SentCode$1 = SentCode$1;
10219
+ exports.StarGift$2 = StarGift$2;
10103
10220
  exports.StarsStatus$2 = StarsStatus$2;
10104
10221
  exports.StarsTransaction$2 = StarsTransaction$2;
10105
10222
  exports.Sticker$2 = Sticker$2;
@@ -10119,6 +10236,7 @@ exports.StoryViewersList$2 = StoryViewersList$2;
10119
10236
  exports.TakeoutSession$1 = TakeoutSession$1;
10120
10237
  exports.Thumbnail$2 = Thumbnail$2;
10121
10238
  exports.User$2 = User$2;
10239
+ exports.UserStarGift$2 = UserStarGift$2;
10122
10240
  exports.Venue$2 = Venue$2;
10123
10241
  exports.Video$2 = Video$2;
10124
10242
  exports.Voice$2 = Voice$2;