diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 601366ee4..7b57efbe0 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1741,6 +1741,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_action_giveaway_results#other" = "{count} winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes."; "lng_action_giveaway_results_some" = "Some winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes."; "lng_action_giveaway_results_none" = "No winners of the giveaway could be selected."; +"lng_action_boost_apply#one" = "{from} boosted the group."; +"lng_action_boost_apply#other" = "{from} boosted the group {count} times."; "lng_similar_channels_title" = "Similar channels"; "lng_similar_channels_view_all" = "View all"; @@ -3748,6 +3750,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_admin_log_changed_stickers_group" = "{from} changed the group's {sticker_set}"; "lng_admin_log_changed_stickers_set" = "sticker set"; "lng_admin_log_removed_stickers_group" = "{from} removed the group's sticker set"; +"lng_admin_log_changed_emoji_group" = "{from} changed the group's {sticker_set}"; +"lng_admin_log_changed_emoji_set" = "emoji set"; +"lng_admin_log_removed_emoji_group" = "{from} removed the group's emoji set"; "lng_admin_log_changed_linked_chat" = "{from} changed the discussion group to «{chat}»"; "lng_admin_log_removed_linked_chat" = "{from} removed the discussion group"; "lng_admin_log_changed_linked_channel" = "{from} changed the linked channel to «{chat}»"; diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index dc8eb1593..2b0450374 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -1114,6 +1114,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { (d.is_out() ? peerToMTP(_session->userPeerId()) : MTP_peerUser(d.vuser_id())), + MTPint(), // from_boosts_applied MTP_peerUser(d.vuser_id()), MTPPeer(), // saved_peer_id d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(), @@ -1146,6 +1147,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { MTP_flags(flags), d.vid(), MTP_peerUser(d.vfrom_id()), + MTPint(), // from_boosts_applied MTP_peerChat(d.vchat_id()), MTPPeer(), // saved_peer_id d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(), diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index f122f05b9..9ea40996e 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -67,6 +67,7 @@ constexpr auto kRequestTimeLimit = 60 * crl::time(1000); MTP_flags(data.vflags().v | MTPDmessage::Flag::f_from_scheduled), data.vid(), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(), + MTPint(), // from_boosts_applied data.vpeer_id(), data.vsaved_peer_id() ? *data.vsaved_peer_id() : MTPPeer(), data.vfwd_from() ? *data.vfwd_from() : MTPMessageFwdHeader(), @@ -216,6 +217,7 @@ void ScheduledMessages::sendNowSimpleMessage( MTP_flags(flags), update.vid(), peerToMTP(local->from()->id), + MTPint(), // from_boosts_applied peerToMTP(history->peer->id), MTPPeer(), // saved_peer_id MTPMessageFwdHeader(), diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 718421d96..f64717794 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -4449,6 +4449,7 @@ void Session::insertCheckedServiceNotification( MTP_flags(flags), MTP_int(0), // Not used (would've been trimmed to 32 bits). peerToMTP(PeerData::kServiceNotificationsId), + MTPint(), // from_boosts_applied peerToMTP(PeerData::kServiceNotificationsId), MTPPeer(), // saved_peer_id MTPMessageFwdHeader(), diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 7c9910e1e..f7928f006 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -1458,6 +1458,10 @@ ServiceAction ParseServiceAction( content.winners = data.vwinners_count().v; content.unclaimed = data.vunclaimed_count().v; result.content = content; + }, [&](const MTPDmessageActionBoostApply &data) { + auto content = ActionBoostApply(); + content.boosts = data.vboosts().v; + result.content = content; }, [](const MTPDmessageActionEmpty &data) {}); return result; } diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index 20bd15206..5f2c2da39 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -559,6 +559,10 @@ struct ActionGiveawayResults { int unclaimed = 0; }; +struct ActionBoostApply { + int boosts = 0; +}; + struct ServiceAction { std::variant< v::null_t, @@ -599,7 +603,8 @@ struct ServiceAction { ActionSetChatWallPaper, ActionGiftCode, ActionGiveawayLaunch, - ActionGiveawayResults> content; + ActionGiveawayResults, + ActionBoostApply> content; }; ServiceAction ParseServiceAction( diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index c543de8a5..30397aab6 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -1301,6 +1301,11 @@ auto HtmlWriter::Wrap::pushMessage( return QByteArray::number(data.winners) + " of the giveaway were randomly selected by Telegram " "and received private messages with giftcodes."; + }, [&](const ActionBoostApply &data) { + return serviceFrom + + " boosted the group " + + QByteArray::number(data.boosts) + + (data.boosts > 1 ? " times" : " time"); }, [](v::null_t) { return QByteArray(); }); if (!serviceText.isEmpty()) { diff --git a/Telegram/SourceFiles/export/output/export_output_json.cpp b/Telegram/SourceFiles/export/output/export_output_json.cpp index dc23fd38f..dde36a5a3 100644 --- a/Telegram/SourceFiles/export/output/export_output_json.cpp +++ b/Telegram/SourceFiles/export/output/export_output_json.cpp @@ -617,6 +617,10 @@ QByteArray SerializeMessage( ? "set_same_chat_wallpaper" : "set_chat_wallpaper"); pushReplyToMsgId("message_id"); + }, [&](const ActionBoostApply &data) { + pushActor(); + pushAction("boost_apply"); + push("boosts", data.boosts); }, [](v::null_t) {}); if (v::is_null(message.action.content)) { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index f9ece93b0..0642a1568 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -116,6 +116,7 @@ MTPMessage PrepareLogMessage(const MTPMessage &message, TimeId newDate) { MTP_flags(data.vflags().v & ~removeFlags), data.vid(), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(), + MTPint(), // from_boosts_applied data.vpeer_id(), MTPPeer(), // saved_peer_id data.vfwd_from() ? *data.vfwd_from() : MTPMessageFwdHeader(), @@ -734,6 +735,7 @@ void GenerateItems( using LogBan = MTPDchannelAdminLogEventActionParticipantToggleBan; using LogPromote = MTPDchannelAdminLogEventActionParticipantToggleAdmin; using LogSticker = MTPDchannelAdminLogEventActionChangeStickerSet; + using LogEmoji = MTPDchannelAdminLogEventActionChangeEmojiStickerSet; using LogPreHistory = MTPDchannelAdminLogEventActionTogglePreHistoryHidden; using LogPermissions = MTPDchannelAdminLogEventActionDefaultBannedRights; @@ -1151,6 +1153,50 @@ void GenerateItems( } }; + const auto createChangeEmojiSet = [&](const LogEmoji &action) { + const auto set = action.vnew_stickerset(); + const auto removed = (set.type() == mtpc_inputStickerSetEmpty); + if (removed) { + const auto text = tr::lng_admin_log_removed_emoji_group( + tr::now, + lt_from, + fromLinkText, + Ui::Text::WithEntities); + addSimpleServiceMessage(text); + } else { + const auto text = tr::lng_admin_log_changed_emoji_group( + tr::now, + lt_from, + fromLinkText, + lt_sticker_set, + Ui::Text::Link( + tr::lng_admin_log_changed_emoji_set(tr::now), + QString()), + Ui::Text::WithEntities); + const auto setLink = std::make_shared([=]( + ClickContext context) { + const auto my = context.other.value(); + if (const auto controller = my.sessionWindow.get()) { + controller->show( + Box( + controller->uiShow(), + Data::FromInputSet(set), + Data::StickersType::Emoji), + Ui::LayerOption::CloseOther); + } + }); + auto message = PreparedServiceText{ text }; + message.links.push_back(fromLink); + message.links.push_back(setLink); + addPart(history->makeMessage( + history->nextNonHistoryEntryId(), + MessageFlag::AdminLogEntry, + date, + std::move(message), + peerToUser(from->id))); + } + }; + const auto createTogglePreHistoryHidden = [&]( const LogPreHistory &action) { const auto hidden = (action.vnew_value().type() == mtpc_boolTrue); @@ -2003,6 +2049,7 @@ void GenerateItems( createParticipantToggleBan, createParticipantToggleAdmin, createChangeStickerSet, + createChangeEmojiSet, createTogglePreHistoryHidden, createDefaultBannedRights, createStopPoll, diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 5da6e880f..6308e01a3 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -4812,6 +4812,20 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { return result; }; + auto prepareBoostApply = [&](const MTPDmessageActionBoostApply &action) { + auto result = PreparedServiceText(); + const auto boosts = action.vboosts().v; + result.links.push_back(fromLink()); + result.text = tr::lng_action_boost_apply( + tr::now, + lt_count, + boosts, + lt_from, + fromLinkText(), // Link 1. + Ui::Text::WithEntities); + return result; + }; + setServiceText(action.match( prepareChatAddUserText, prepareChatJoinedByLink, @@ -4853,6 +4867,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { prepareGiftCode, prepareGiveawayLaunch, prepareGiveawayResults, + prepareBoostApply, PrepareErrorText)); // Additional information. diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index d22012e17..a1ebf13f6 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -101,7 +101,7 @@ channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5 channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions = ChatFull; -channelFull#f2bcb6f flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper = ChatFull; +channelFull#44c054a7 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -114,7 +114,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto; messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message; -message#76bec211 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int = Message; +message#1e4c8a69 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int = Message; messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message; messageMediaEmpty#3ded6320 = MessageMedia; @@ -175,6 +175,7 @@ messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags. messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction; messageActionGiveawayLaunch#332ba9ed = MessageAction; messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction; +messageActionBoostApply#cc02aa6d boosts:int = MessageAction; dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; @@ -980,6 +981,7 @@ channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_valu channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction; channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction; channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; @@ -1627,7 +1629,7 @@ peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = help.peerColorSet#26219a58 colors:Vector = help.PeerColorSet; help.peerColorProfileSet#767d61eb palette_colors:Vector bg_colors:Vector story_colors:Vector = help.PeerColorSet; -help.peerColorOption#ef8430ab flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int = help.PeerColorOption; +help.peerColorOption#adec6ebe flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int group_min_level:flags.4?int = help.PeerColorOption; help.peerColorsNotModified#2ba1f5ce = help.PeerColors; help.peerColors#f8ed08 hash:int colors:Vector = help.PeerColors; @@ -2111,6 +2113,8 @@ channels.updateColor#d8aa3671 flags:# for_profile:flags.1?true channel:InputChan channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates; channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chats; channels.updateEmojiStatus#f0d3e6a8 channel:InputChannel emoji_status:EmojiStatus = Updates; +channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int = Updates; +channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; @@ -2248,4 +2252,4 @@ premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector peer:InputPeer = p premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus; premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList; -// LAYER 173 +// LAYER 174 diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index a8466de5e..6620c4bbb 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -172,6 +172,7 @@ AdminLog::OwnedItem GenerateForwardedItem( MTP_flags(flags), MTP_int(0), // Not used (would've been trimmed to 32 bits). peerToMTP(history->peer->id), + MTPint(), // from_boosts_applied peerToMTP(history->peer->id), MTPPeer(), // saved_peer_id MTP_messageFwdHeader(