/* message_row.c generated by valac 0.56.19, the Vala compiler
 * generated from message_row.vala, do not modify */

#include <gtk/gtk.h>
#include <glib-object.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <gdk/gdk.h>
#include <float.h>
#include <math.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <pixbuf_animation_compat.h>
#include <pango/pango.h>
#include <gio/gio.h>
#include <stdio.h>
#include <adwaita.h>
#include <gobject/gvaluecollector.h>

#define DC_MESSAGE_ROW_ALIGN_LEFT 0
#define DC_MESSAGE_ROW_ALIGN_RIGHT 1
#define DC_MESSAGE_ROW_ALIGN_CENTER 2
#define DC_MESSAGE_ROW_ACTION_DATA "parla-message-row-action"
#define DC_MESSAGE_ROW_MESSAGE_DATA "parla-message-row-message"
#define DC_MESSAGE_ROW_TASK_RAW_DATA "parla-message-row-task-raw"
#define DC_MESSAGE_ROW_TASK_INDEX_DATA "parla-message-row-task-index"
#define DC_MESSAGE_ROW_REACTION_POPOVER_DATA "parla-message-row-reaction-popover"
#define DC_MESSAGE_ROW_REACTION_HIDE_DATA "parla-message-row-reaction-hide-source"
#define DC_MESSAGE_ROW_STICKER_MAX 200
#define DC_MESSAGE_ROW_PREVIEW_MAX_CHARS ((glong) 1000)
#define DC_WEBXDC_AVAILABLE TRUE
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define DC_TYPE_SCALED_PREVIEW_FRAME (dc_scaled_preview_frame_get_type ())
#define DC_SCALED_PREVIEW_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrame))
#define DC_SCALED_PREVIEW_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrameClass))
#define DC_IS_SCALED_PREVIEW_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_SCALED_PREVIEW_FRAME))
#define DC_IS_SCALED_PREVIEW_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_SCALED_PREVIEW_FRAME))
#define DC_SCALED_PREVIEW_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrameClass))

typedef struct _DcScaledPreviewFrame DcScaledPreviewFrame;
typedef struct _DcScaledPreviewFrameClass DcScaledPreviewFrameClass;
typedef struct _DcScaledPreviewFramePrivate DcScaledPreviewFramePrivate;
enum  {
	DC_SCALED_PREVIEW_FRAME_0_PROPERTY,
	DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY,
	DC_SCALED_PREVIEW_FRAME_NUM_PROPERTIES
};
static GParamSpec* dc_scaled_preview_frame_properties[DC_SCALED_PREVIEW_FRAME_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define DC_TYPE_STICKER_FRAME_PAINTABLE (dc_sticker_frame_paintable_get_type ())
#define DC_STICKER_FRAME_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_STICKER_FRAME_PAINTABLE, DcStickerFramePaintable))
#define DC_STICKER_FRAME_PAINTABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_STICKER_FRAME_PAINTABLE, DcStickerFramePaintableClass))
#define DC_IS_STICKER_FRAME_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_STICKER_FRAME_PAINTABLE))
#define DC_IS_STICKER_FRAME_PAINTABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_STICKER_FRAME_PAINTABLE))
#define DC_STICKER_FRAME_PAINTABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_STICKER_FRAME_PAINTABLE, DcStickerFramePaintableClass))

typedef struct _DcStickerFramePaintable DcStickerFramePaintable;
typedef struct _DcStickerFramePaintableClass DcStickerFramePaintableClass;
typedef struct _DcStickerFramePaintablePrivate DcStickerFramePaintablePrivate;
enum  {
	DC_STICKER_FRAME_PAINTABLE_0_PROPERTY,
	DC_STICKER_FRAME_PAINTABLE_NUM_PROPERTIES
};
static GParamSpec* dc_sticker_frame_paintable_properties[DC_STICKER_FRAME_PAINTABLE_NUM_PROPERTIES];

#define DC_TYPE_STICKER_ANIMATION (dc_sticker_animation_get_type ())
#define DC_STICKER_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_STICKER_ANIMATION, DcStickerAnimation))
#define DC_STICKER_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_STICKER_ANIMATION, DcStickerAnimationClass))
#define DC_IS_STICKER_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_STICKER_ANIMATION))
#define DC_IS_STICKER_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_STICKER_ANIMATION))
#define DC_STICKER_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_STICKER_ANIMATION, DcStickerAnimationClass))

typedef struct _DcStickerAnimation DcStickerAnimation;
typedef struct _DcStickerAnimationClass DcStickerAnimationClass;
typedef struct _DcStickerAnimationPrivate DcStickerAnimationPrivate;
enum  {
	DC_STICKER_ANIMATION_0_PROPERTY,
	DC_STICKER_ANIMATION_NUM_PROPERTIES
};
static GParamSpec* dc_sticker_animation_properties[DC_STICKER_ANIMATION_NUM_PROPERTIES];

#define DC_TYPE_STICKER_VIDEO_ANIMATION (dc_sticker_video_animation_get_type ())
#define DC_STICKER_VIDEO_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_STICKER_VIDEO_ANIMATION, DcStickerVideoAnimation))
#define DC_STICKER_VIDEO_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_STICKER_VIDEO_ANIMATION, DcStickerVideoAnimationClass))
#define DC_IS_STICKER_VIDEO_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_STICKER_VIDEO_ANIMATION))
#define DC_IS_STICKER_VIDEO_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_STICKER_VIDEO_ANIMATION))
#define DC_STICKER_VIDEO_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_STICKER_VIDEO_ANIMATION, DcStickerVideoAnimationClass))

typedef struct _DcStickerVideoAnimation DcStickerVideoAnimation;
typedef struct _DcStickerVideoAnimationClass DcStickerVideoAnimationClass;
typedef struct _DcStickerVideoAnimationPrivate DcStickerVideoAnimationPrivate;
enum  {
	DC_STICKER_VIDEO_ANIMATION_0_PROPERTY,
	DC_STICKER_VIDEO_ANIMATION_NUM_PROPERTIES
};
static GParamSpec* dc_sticker_video_animation_properties[DC_STICKER_VIDEO_ANIMATION_NUM_PROPERTIES];

#define DC_TYPE_MESSAGE_ROW (dc_message_row_get_type ())
#define DC_MESSAGE_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MESSAGE_ROW, DcMessageRow))
#define DC_MESSAGE_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MESSAGE_ROW, DcMessageRowClass))
#define DC_IS_MESSAGE_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MESSAGE_ROW))
#define DC_IS_MESSAGE_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MESSAGE_ROW))
#define DC_MESSAGE_ROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MESSAGE_ROW, DcMessageRowClass))

typedef struct _DcMessageRow DcMessageRow;
typedef struct _DcMessageRowClass DcMessageRowClass;
typedef struct _DcMessageRowPrivate DcMessageRowPrivate;

#define DC_TYPE_AUDIO_PLAYER (dc_audio_player_get_type ())
#define DC_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayer))
#define DC_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))
#define DC_IS_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_AUDIO_PLAYER))
#define DC_IS_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_AUDIO_PLAYER))
#define DC_AUDIO_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))

typedef struct _DcAudioPlayer DcAudioPlayer;
typedef struct _DcAudioPlayerClass DcAudioPlayerClass;

#define DC_TYPE_MENTION_ROSTER (dc_mention_roster_get_type ())
#define DC_MENTION_ROSTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MENTION_ROSTER, DcMentionRoster))
#define DC_MENTION_ROSTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MENTION_ROSTER, DcMentionRosterClass))
#define DC_IS_MENTION_ROSTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MENTION_ROSTER))
#define DC_IS_MENTION_ROSTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MENTION_ROSTER))
#define DC_MENTION_ROSTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MENTION_ROSTER, DcMentionRosterClass))

typedef struct _DcMentionRoster DcMentionRoster;
typedef struct _DcMentionRosterClass DcMentionRosterClass;
enum  {
	DC_MESSAGE_ROW_0_PROPERTY,
	DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY,
	DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY,
	DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY,
	DC_MESSAGE_ROW_NUM_PROPERTIES
};
static GParamSpec* dc_message_row_properties[DC_MESSAGE_ROW_NUM_PROPERTIES];
typedef enum  {
	DC_MESSAGE_STYLE_BUBBLES = 0,
	DC_MESSAGE_STYLE_IRC = 1,
	DC_MESSAGE_STYLE_WORKSPACE = 2
} DcMessageStyle;

#define DC_TYPE_MESSAGE_STYLE (dc_message_style_get_type ())
typedef struct _Block22Data Block22Data;

#define DC_TYPE_MESSAGE (dc_message_get_type ())
#define DC_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MESSAGE, DcMessage))
#define DC_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MESSAGE, DcMessageClass))
#define DC_IS_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MESSAGE))
#define DC_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MESSAGE))
#define DC_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MESSAGE, DcMessageClass))

typedef struct _DcMessage DcMessage;
typedef struct _DcMessageClass DcMessageClass;
typedef enum  {
	DC_BUBBLE_AVATAR_DISPLAY_NONE = 0,
	DC_BUBBLE_AVATAR_DISPLAY_OTHER = 1,
	DC_BUBBLE_AVATAR_DISPLAY_BOTH = 2
} DcBubbleAvatarDisplay;

#define DC_TYPE_BUBBLE_AVATAR_DISPLAY (dc_bubble_avatar_display_get_type ())
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block23Data Block23Data;

#define DC_WEBXDC_TYPE_CARD_INFO (dc_webxdc_card_info_get_type ())
#define DC_WEBXDC_CARD_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_WEBXDC_TYPE_CARD_INFO, DcWebxdcCardInfo))
#define DC_WEBXDC_CARD_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_WEBXDC_TYPE_CARD_INFO, DcWebxdcCardInfoClass))
#define DC_WEBXDC_IS_CARD_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_WEBXDC_TYPE_CARD_INFO))
#define DC_WEBXDC_IS_CARD_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_WEBXDC_TYPE_CARD_INFO))
#define DC_WEBXDC_CARD_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_WEBXDC_TYPE_CARD_INFO, DcWebxdcCardInfoClass))

typedef struct _DcWebxdcCardInfo DcWebxdcCardInfo;
typedef struct _DcWebxdcCardInfoClass DcWebxdcCardInfoClass;
typedef struct _DcWebxdcCardInfoPrivate DcWebxdcCardInfoPrivate;
#define _dc_webxdc_card_info_unref0(var) ((var == NULL) ? NULL : (var = (dc_webxdc_card_info_unref (var), NULL)))
typedef struct _Block24Data Block24Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _Block25Data Block25Data;
typedef enum  {
	DC_MARKDOWN_MODE_ENABLED = 0,
	DC_MARKDOWN_MODE_STRIPPED = 1,
	DC_MARKDOWN_MODE_DISABLED = 2
} DcMarkdownMode;

#define DC_TYPE_MARKDOWN_MODE (dc_markdown_mode_get_type ())
#define _pango_attr_list_unref0(var) ((var == NULL) ? NULL : (var = (pango_attr_list_unref (var), NULL)))

#define DC_TYPE_WINDOW (dc_window_get_type ())
#define DC_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_WINDOW, DcWindow))
#define DC_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_WINDOW, DcWindowClass))
#define DC_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_WINDOW))
#define DC_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_WINDOW))
#define DC_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_WINDOW, DcWindowClass))

typedef struct _DcWindow DcWindow;
typedef struct _DcWindowClass DcWindowClass;

#define DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK (dc_message_row_markdown_table_block_get_type ())
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK, DcMessageRowMarkdownTableBlock))
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_BLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK, DcMessageRowMarkdownTableBlockClass))
#define DC_MESSAGE_ROW_IS_MARKDOWN_TABLE_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK))
#define DC_MESSAGE_ROW_IS_MARKDOWN_TABLE_BLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK))
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_BLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK, DcMessageRowMarkdownTableBlockClass))

typedef struct _DcMessageRowMarkdownTableBlock DcMessageRowMarkdownTableBlock;
typedef struct _DcMessageRowMarkdownTableBlockClass DcMessageRowMarkdownTableBlockClass;
#define _dc_message_row_markdown_table_block_unref0(var) ((var == NULL) ? NULL : (var = (dc_message_row_markdown_table_block_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
typedef struct _DcMessageRowMarkdownTableBlockPrivate DcMessageRowMarkdownTableBlockPrivate;

#define DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW (dc_message_row_markdown_table_row_get_type ())
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW, DcMessageRowMarkdownTableRow))
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW, DcMessageRowMarkdownTableRowClass))
#define DC_MESSAGE_ROW_IS_MARKDOWN_TABLE_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW))
#define DC_MESSAGE_ROW_IS_MARKDOWN_TABLE_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW))
#define DC_MESSAGE_ROW_MARKDOWN_TABLE_ROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW, DcMessageRowMarkdownTableRowClass))

typedef struct _DcMessageRowMarkdownTableRow DcMessageRowMarkdownTableRow;
typedef struct _DcMessageRowMarkdownTableRowClass DcMessageRowMarkdownTableRowClass;
typedef struct _DcMessageRowMarkdownTableRowPrivate DcMessageRowMarkdownTableRowPrivate;
#define _dc_message_row_markdown_table_row_unref0(var) ((var == NULL) ? NULL : (var = (dc_message_row_markdown_table_row_unref (var), NULL)))
typedef struct _DcMessagePrivate DcMessagePrivate;

#define DC_TYPE_MESSAGE_REACTION (dc_message_reaction_get_type ())
#define DC_MESSAGE_REACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MESSAGE_REACTION, DcMessageReaction))
#define DC_MESSAGE_REACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MESSAGE_REACTION, DcMessageReactionClass))
#define DC_IS_MESSAGE_REACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MESSAGE_REACTION))
#define DC_IS_MESSAGE_REACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MESSAGE_REACTION))
#define DC_MESSAGE_REACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MESSAGE_REACTION, DcMessageReactionClass))

typedef struct _DcMessageReaction DcMessageReaction;
typedef struct _DcMessageReactionClass DcMessageReactionClass;
typedef struct _Block26Data Block26Data;
typedef struct _DcMessageReactionPrivate DcMessageReactionPrivate;

#define DC_TYPE_MESSAGE_REACTION_USER (dc_message_reaction_user_get_type ())
#define DC_MESSAGE_REACTION_USER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MESSAGE_REACTION_USER, DcMessageReactionUser))
#define DC_MESSAGE_REACTION_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MESSAGE_REACTION_USER, DcMessageReactionUserClass))
#define DC_IS_MESSAGE_REACTION_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MESSAGE_REACTION_USER))
#define DC_IS_MESSAGE_REACTION_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MESSAGE_REACTION_USER))
#define DC_MESSAGE_REACTION_USER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MESSAGE_REACTION_USER, DcMessageReactionUserClass))

typedef struct _DcMessageReactionUser DcMessageReactionUser;
typedef struct _DcMessageReactionUserClass DcMessageReactionUserClass;

#define DC_TYPE_MENTION_MEMBER (dc_mention_member_get_type ())
#define DC_MENTION_MEMBER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MENTION_MEMBER, DcMentionMember))
#define DC_MENTION_MEMBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MENTION_MEMBER, DcMentionMemberClass))
#define DC_IS_MENTION_MEMBER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MENTION_MEMBER))
#define DC_IS_MENTION_MEMBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MENTION_MEMBER))
#define DC_MENTION_MEMBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MENTION_MEMBER, DcMentionMemberClass))

typedef struct _DcMentionMember DcMentionMember;
typedef struct _DcMentionMemberClass DcMentionMemberClass;
#define _g_date_time_unref0(var) ((var == NULL) ? NULL : (var = (g_date_time_unref (var), NULL)))
typedef struct _DcMessageRowParamSpecMarkdownTableRow DcMessageRowParamSpecMarkdownTableRow;
#define _g_ptr_array_unref0(var) ((var == NULL) ? NULL : (var = (g_ptr_array_unref (var), NULL)))
typedef struct _DcMessageRowParamSpecMarkdownTableBlock DcMessageRowParamSpecMarkdownTableBlock;
enum  {
	DC_MESSAGE_ROW_QUOTE_CLICKED_SIGNAL,
	DC_MESSAGE_ROW_ACTION_REQUESTED_SIGNAL,
	DC_MESSAGE_ROW_FULL_MESSAGE_REQUESTED_SIGNAL,
	DC_MESSAGE_ROW_FULL_MESSAGE_VIEW_REQUESTED_SIGNAL,
	DC_MESSAGE_ROW_SELECTION_TOGGLED_SIGNAL,
	DC_MESSAGE_ROW_CHECKBOX_TOGGLE_REQUESTED_SIGNAL,
	DC_MESSAGE_ROW_NUM_SIGNALS
};
static guint dc_message_row_signals[DC_MESSAGE_ROW_NUM_SIGNALS] = {0};

struct _DcScaledPreviewFrame {
	GtkWidget parent_instance;
	DcScaledPreviewFramePrivate * priv;
};

struct _DcScaledPreviewFrameClass {
	GtkWidgetClass parent_class;
};

struct _DcScaledPreviewFramePrivate {
	gint natural_width;
	gint natural_height;
	GtkWidget* _child;
};

struct _DcStickerFramePaintable {
	GObject parent_instance;
	DcStickerFramePaintablePrivate * priv;
};

struct _DcStickerFramePaintableClass {
	GObjectClass parent_class;
};

struct _DcStickerFramePaintablePrivate {
	GdkTexture* texture;
};

struct _DcStickerAnimation {
	GObject parent_instance;
	DcStickerAnimationPrivate * priv;
};

struct _DcStickerAnimationClass {
	GObjectClass parent_class;
};

struct _DcStickerAnimationPrivate {
	GdkPixbufAnimation* animation;
	GdkPixbufAnimationIter* iter;
	guint timeout_id;
	DcStickerFramePaintable* paintable;
	gboolean playing;
	gboolean mapped;
};

struct _DcStickerVideoAnimation {
	GObject parent_instance;
	DcStickerVideoAnimationPrivate * priv;
};

struct _DcStickerVideoAnimationClass {
	GObjectClass parent_class;
};

struct _DcStickerVideoAnimationPrivate {
	GtkMediaFile* media;
	GtkPicture* picture;
	DcScaledPreviewFrame* frame;
	gboolean playing;
	gint max_size;
};

struct _DcMessageRow {
	GtkBox parent_instance;
	DcMessageRowPrivate * priv;
};

struct _DcMessageRowClass {
	GtkBoxClass parent_class;
};

struct _DcMessageRowPrivate {
	gint _message_id;
	gboolean _is_outgoing;
	DcAudioPlayer* _audio_player;
	DcMentionRoster* mention_roster;
	DcMentionRoster* reaction_roster;
	gint account_id;
};

struct _Block22Data {
	int _ref_count_;
	GWeakRef row_ref;
};

struct _Block23Data {
	int _ref_count_;
	GWeakRef name_ref;
	GWeakRef icon_ref;
};

struct _DcWebxdcCardInfo {
	GTypeInstance parent_instance;
	volatile int ref_count;
	DcWebxdcCardInfoPrivate * priv;
	gchar* name;
	GdkTexture* icon;
};

struct _DcWebxdcCardInfoClass {
	GTypeClass parent_class;
	void (*finalize) (DcWebxdcCardInfo *self);
};

struct _Block24Data {
	int _ref_count_;
	DcStickerAnimation* sticker;
};

struct _Block25Data {
	int _ref_count_;
	DcStickerVideoAnimation* sticker;
};

struct _DcMessageRowMarkdownTableBlock {
	GTypeInstance parent_instance;
	volatile int ref_count;
	DcMessageRowMarkdownTableBlockPrivate * priv;
	GPtrArray* rows;
	gint* aligns;
	gint aligns_length1;
	gint _aligns_size_;
};

struct _DcMessageRowMarkdownTableBlockClass {
	GTypeClass parent_class;
	void (*finalize) (DcMessageRowMarkdownTableBlock *self);
};

struct _DcMessageRowMarkdownTableRow {
	GTypeInstance parent_instance;
	volatile int ref_count;
	DcMessageRowMarkdownTableRowPrivate * priv;
	gchar** cells;
	gint cells_length1;
	gint _cells_size_;
	gboolean header;
};

struct _DcMessageRowMarkdownTableRowClass {
	GTypeClass parent_class;
	void (*finalize) (DcMessageRowMarkdownTableRow *self);
};

struct _DcMessage {
	GObject parent_instance;
	DcMessagePrivate * priv;
	GPtrArray* reaction_details;
};

struct _DcMessageClass {
	GObjectClass parent_class;
};

struct _Block26Data {
	int _ref_count_;
	GWeakRef popover_ref;
};

struct _DcMessageReaction {
	GObject parent_instance;
	DcMessageReactionPrivate * priv;
	GPtrArray* users;
};

struct _DcMessageReactionClass {
	GObjectClass parent_class;
};

struct _DcMessageRowParamSpecMarkdownTableRow {
	GParamSpec parent_instance;
};

struct _DcMessageRowParamSpecMarkdownTableBlock {
	GParamSpec parent_instance;
};

static gint DcScaledPreviewFrame_private_offset;
static gpointer dc_scaled_preview_frame_parent_class = NULL;
static gint DcStickerFramePaintable_private_offset;
static gpointer dc_sticker_frame_paintable_parent_class = NULL;
static GdkPaintableInterface * dc_sticker_frame_paintable_gdk_paintable_parent_iface = NULL;
static gint DcStickerAnimation_private_offset;
static gpointer dc_sticker_animation_parent_class = NULL;
static gint DcStickerVideoAnimation_private_offset;
static gpointer dc_sticker_video_animation_parent_class = NULL;
static gint DcMessageRow_private_offset;
static gpointer dc_message_row_parent_class = NULL;
VALA_EXTERN DcMessageStyle dc_message_row_style;
DcMessageStyle dc_message_row_style = DC_MESSAGE_STYLE_BUBBLES;
VALA_EXTERN gboolean dc_message_row_animate_stickers;
gboolean dc_message_row_animate_stickers = TRUE;
VALA_EXTERN gchar* dc_message_row_self_display_name;
gchar* dc_message_row_self_display_name = NULL;
VALA_EXTERN gchar* dc_message_row_self_avatar_path;
gchar* dc_message_row_self_avatar_path = NULL;
VALA_EXTERN DcMarkdownMode dc_markdown_mode;
static gpointer dc_message_row_markdown_table_row_parent_class = NULL;
static gpointer dc_message_row_markdown_table_block_parent_class = NULL;

VALA_EXTERN GType dc_scaled_preview_frame_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcScaledPreviewFrame, g_object_unref)
VALA_EXTERN DcScaledPreviewFrame* dc_scaled_preview_frame_new (gint natural_width,
                                                   gint natural_height,
                                                   const gchar* css_class);
VALA_EXTERN DcScaledPreviewFrame* dc_scaled_preview_frame_construct (GType object_type,
                                                         gint natural_width,
                                                         gint natural_height,
                                                         const gchar* css_class);
VALA_EXTERN void dc_scaled_preview_frame_set_natural_size (DcScaledPreviewFrame* self,
                                               gint width,
                                               gint height);
static void dc_scaled_preview_frame_real_dispose (GObject* base);
static GtkSizeRequestMode dc_scaled_preview_frame_real_get_request_mode (GtkWidget* base);
static void dc_scaled_preview_frame_real_measure (GtkWidget* base,
                                           GtkOrientation orientation,
                                           gint for_size,
                                           gint* minimum,
                                           gint* natural,
                                           gint* minimum_baseline,
                                           gint* natural_baseline);
static void dc_scaled_preview_frame_real_size_allocate (GtkWidget* base,
                                                 gint width,
                                                 gint height,
                                                 gint baseline);
static void dc_scaled_preview_frame_real_snapshot (GtkWidget* base,
                                            GtkSnapshot* snapshot);
VALA_EXTERN GtkWidget* dc_scaled_preview_frame_get_child (DcScaledPreviewFrame* self);
VALA_EXTERN void dc_scaled_preview_frame_set_child (DcScaledPreviewFrame* self,
                                        GtkWidget* value);
static void dc_scaled_preview_frame_finalize (GObject * obj);
static GType dc_scaled_preview_frame_get_type_once (void);
static void _vala_dc_scaled_preview_frame_get_property (GObject * object,
                                                 guint property_id,
                                                 GValue * value,
                                                 GParamSpec * pspec);
static void _vala_dc_scaled_preview_frame_set_property (GObject * object,
                                                 guint property_id,
                                                 const GValue * value,
                                                 GParamSpec * pspec);
VALA_EXTERN GType dc_sticker_frame_paintable_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcStickerFramePaintable, g_object_unref)
VALA_EXTERN DcStickerFramePaintable* dc_sticker_frame_paintable_new (GdkTexture* texture);
VALA_EXTERN DcStickerFramePaintable* dc_sticker_frame_paintable_construct (GType object_type,
                                                               GdkTexture* texture);
VALA_EXTERN void dc_sticker_frame_paintable_set_texture (DcStickerFramePaintable* self,
                                             GdkTexture* texture);
static void dc_sticker_frame_paintable_real_snapshot (GdkPaintable* base,
                                               GdkSnapshot* snapshot,
                                               gdouble width,
                                               gdouble height);
static GdkPaintable* dc_sticker_frame_paintable_real_get_current_image (GdkPaintable* base);
static GdkPaintableFlags dc_sticker_frame_paintable_real_get_flags (GdkPaintable* base);
static gint dc_sticker_frame_paintable_real_get_intrinsic_width (GdkPaintable* base);
static gint dc_sticker_frame_paintable_real_get_intrinsic_height (GdkPaintable* base);
static void dc_sticker_frame_paintable_finalize (GObject * obj);
static GType dc_sticker_frame_paintable_get_type_once (void);
VALA_EXTERN GType dc_sticker_animation_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcStickerAnimation, g_object_unref)
VALA_EXTERN DcStickerAnimation* dc_sticker_animation_new (GtkPicture* picture,
                                              GdkPixbufAnimation* animation,
                                              gboolean playing);
VALA_EXTERN DcStickerAnimation* dc_sticker_animation_construct (GType object_type,
                                                    GtkPicture* picture,
                                                    GdkPixbufAnimation* animation,
                                                    gboolean playing);
VALA_EXTERN GdkTexture* dc_texture_from_pixbuf (GdkPixbuf* pixbuf);
static void dc_sticker_animation_on_map (DcStickerAnimation* self);
static void _dc_sticker_animation_on_map_gtk_widget_map (GtkWidget* _sender,
                                                  gpointer self);
static void dc_sticker_animation_on_unmap (DcStickerAnimation* self);
static void _dc_sticker_animation_on_unmap_gtk_widget_unmap (GtkWidget* _sender,
                                                      gpointer self);
VALA_EXTERN void dc_sticker_animation_toggle_playing (DcStickerAnimation* self);
static void dc_sticker_animation_start (DcStickerAnimation* self);
static void dc_sticker_animation_stop (DcStickerAnimation* self);
static void dc_sticker_animation_show_current_frame (DcStickerAnimation* self);
static void dc_sticker_animation_schedule_next_frame (DcStickerAnimation* self);
static gboolean __lambda15_ (DcStickerAnimation* self);
static gboolean ___lambda15__gsource_func (gpointer self);
static void dc_sticker_animation_finalize (GObject * obj);
static GType dc_sticker_animation_get_type_once (void);
VALA_EXTERN GType dc_sticker_video_animation_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcStickerVideoAnimation, g_object_unref)
VALA_EXTERN DcStickerVideoAnimation* dc_sticker_video_animation_new (GtkPicture* picture,
                                                         DcScaledPreviewFrame* frame,
                                                         const gchar* path,
                                                         gboolean playing,
                                                         gint max_size);
VALA_EXTERN DcStickerVideoAnimation* dc_sticker_video_animation_construct (GType object_type,
                                                               GtkPicture* picture,
                                                               DcScaledPreviewFrame* frame,
                                                               const gchar* path,
                                                               gboolean playing,
                                                               gint max_size);
static void dc_sticker_video_animation_update_size (DcStickerVideoAnimation* self);
static void _dc_sticker_video_animation_update_size_g_object_notify (GObject* _sender,
                                                              GParamSpec* pspec,
                                                              gpointer self);
static void dc_sticker_video_animation_on_map (DcStickerVideoAnimation* self);
static void _dc_sticker_video_animation_on_map_gtk_widget_map (GtkWidget* _sender,
                                                        gpointer self);
static void dc_sticker_video_animation_on_unmap (DcStickerVideoAnimation* self);
static void _dc_sticker_video_animation_on_unmap_gtk_widget_unmap (GtkWidget* _sender,
                                                            gpointer self);
VALA_EXTERN void dc_sticker_video_animation_toggle_playing (DcStickerVideoAnimation* self);
static void dc_sticker_video_animation_finalize (GObject * obj);
static GType dc_sticker_video_animation_get_type_once (void);
VALA_EXTERN GType dc_message_row_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessageRow, g_object_unref)
VALA_EXTERN GType dc_audio_player_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcAudioPlayer, g_object_unref)
VALA_EXTERN GType dc_mention_roster_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMentionRoster, g_object_unref)
VALA_EXTERN GType dc_message_style_get_type (void) G_GNUC_CONST ;
VALA_EXTERN void dc_message_row_highlight (DcMessageRow* self);
static void dc_message_row_clear_highlight_later (DcMessageRow* row);
static Block22Data* block22_data_ref (Block22Data* _data22_);
static void block22_data_unref (void * _userdata_);
static gboolean __lambda13_ (Block22Data* _data22_);
static gboolean ___lambda13__gsource_func (gpointer self);
VALA_EXTERN gboolean dc_message_row_has_selectable_text (DcMessageRow* self);
static gboolean dc_message_row_has_selectable_text_in (GtkWidget* widget);
VALA_EXTERN gboolean dc_message_row_select_all_text (DcMessageRow* self);
static void dc_message_row_select_all_text_in (GtkWidget* widget,
                                        gboolean* selected,
                                        gboolean* focused);
VALA_EXTERN GType dc_message_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessage, g_object_unref)
VALA_EXTERN GType dc_bubble_avatar_display_get_type (void) G_GNUC_CONST ;
VALA_EXTERN DcMessageRow* dc_message_row_new (DcMessage* msg,
                                  DcMessage* prev,
                                  GPtrArray* trailing_images,
                                  gboolean is_image_continuation,
                                  DcBubbleAvatarDisplay avatar_display,
                                  gboolean avatar_scope_enabled,
                                  gboolean show_sender_name,
                                  DcMentionRoster* mention_roster,
                                  DcMentionRoster* reaction_roster,
                                  gint account_id);
VALA_EXTERN DcMessageRow* dc_message_row_construct (GType object_type,
                                        DcMessage* msg,
                                        DcMessage* prev,
                                        GPtrArray* trailing_images,
                                        gboolean is_image_continuation,
                                        DcBubbleAvatarDisplay avatar_display,
                                        gboolean avatar_scope_enabled,
                                        gboolean show_sender_name,
                                        DcMentionRoster* mention_roster,
                                        DcMentionRoster* reaction_roster,
                                        gint account_id);
VALA_EXTERN gint dc_message_get_id (DcMessage* self);
static void dc_message_row_set_message_id (DcMessageRow* self,
                                    gint value);
VALA_EXTERN gboolean dc_message_get_is_outgoing (DcMessage* self);
static void dc_message_row_set_is_outgoing (DcMessageRow* self,
                                     gboolean value);
static void dc_message_row_build_irc_row (DcMessageRow* self,
                                   DcMessage* msg,
                                   GPtrArray* trailing_images,
                                   gboolean is_image_continuation);
static void dc_message_row_append_selection_checkbox (DcMessageRow* self,
                                               DcMessage* msg);
VALA_EXTERN gboolean dc_message_get_is_info (DcMessage* self);
static void dc_message_row_build_info_row (DcMessageRow* self,
                                    DcMessage* msg);
static void dc_message_row_build_workspace_row (DcMessageRow* self,
                                         DcMessage* msg,
                                         DcMessage* prev);
static void dc_message_row_build_bubble_row (DcMessageRow* self,
                                      DcMessage* msg,
                                      DcBubbleAvatarDisplay avatar_display,
                                      gboolean avatar_scope_enabled,
                                      gboolean show_sender_name);
static void dc_message_row_append_content (DcMessageRow* self,
                                    GtkBox* box,
                                    DcMessage* msg,
                                    gint quote_width,
                                    gint quote_lines,
                                    gboolean irc,
                                    GPtrArray* trailing,
                                    gint text_width);
VALA_EXTERN gboolean dc_message_get_is_forwarded (DcMessage* self);
static GtkLabel* dc_message_row_build_forwarded_indicator (DcMessage* msg);
VALA_EXTERN const gchar* dc_message_get_quote_text (DcMessage* self);
static GtkButton* dc_message_row_build_quote_block (DcMessageRow* self,
                                             DcMessage* msg,
                                             gint max_width_chars,
                                             gint lines);
static void dc_message_row_append_attachment (DcMessageRow* self,
                                       GtkBox* box,
                                       DcMessage* msg,
                                       gboolean irc,
                                       GPtrArray* trailing_images);
VALA_EXTERN const gchar* dc_message_get_text (DcMessage* self);
static GtkWidget* dc_message_row_build_text_widget (DcMessageRow* self,
                                             DcMessage* msg,
                                             gint max_width_chars);
static void dc_message_row_append_meta_indicators (DcMessageRow* self,
                                            GtkBox* box,
                                            DcMessage* msg,
                                            GtkAlign align);
VALA_EXTERN gboolean dc_message_get_is_edited (DcMessage* self);
static GtkLabel* dc_message_row_build_edited_indicator (const gchar* text);
static GtkLabel* dc_message_row_build_tick_indicator (DcMessage* msg);
static GtkLabel* dc_message_row_build_pin_indicator (DcMessage* msg);
static void dc_message_row_flag_self_mention (DcMessageRow* self,
                                       DcMessage* msg);
VALA_EXTERN gboolean dc_mentions_has_self_mention (const gchar* raw,
                                       DcMentionRoster* roster);
static gboolean dc_message_row_should_show_bubble_avatar (DcMessage* msg,
                                                   DcBubbleAvatarDisplay display,
                                                   gboolean scope_enabled);
VALA_EXTERN gboolean dc_message_get_is_image_only (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_has_local_file (DcMessage* self);
VALA_EXTERN gboolean dc_message_is_sticker_file (DcMessage* self);
static gchar* dc_message_row_effective_author_name (DcMessage* msg);
VALA_EXTERN const gchar* dc_message_get_sender_address (DcMessage* self);
static gchar* dc_message_row_format_timestamp (gint64 ts);
VALA_EXTERN gint64 dc_message_get_timestamp (DcMessage* self);
static GtkBox* dc_message_row_build_reactions_box (DcMessageRow* self,
                                            DcMessage* msg);
static GtkWidget* dc_message_row_build_bubble_avatar (DcMessage* msg);
VALA_EXTERN gchar* dc_message_row_effective_sender_name (DcMessage* msg);
VALA_EXTERN gboolean dc_message_row_same_sender (DcMessage* a,
                                     DcMessage* b);
VALA_EXTERN gboolean dc_message_row_same_day (gint64 ts1,
                                  gint64 ts2);
VALA_EXTERN const gchar* dc_message_get_sender_avatar_path (DcMessage* self);
VALA_EXTERN GtkWidget* dc_presence_avatar (gint size,
                               const gchar* text,
                               const gchar* path,
                               gboolean online,
                               const gchar* avatar_css,
                               const gchar* ring_css);
static GtkWidget* dc_message_row_build_hover_actions (DcMessageRow* self);
static void dc_message_row_connect_hover_visibility (GtkEventControllerMotion* motion,
                                              GtkWidget* bar);
static void dc_message_row_on_hover_enter (GtkEventControllerMotion* motion,
                                    gdouble x,
                                    gdouble y,
                                    GtkWidget* bar);
static void dc_message_row_on_hover_leave (GtkEventControllerMotion* motion,
                                    GtkWidget* bar);
static void dc_message_row_connect_action_button (DcMessageRow* self,
                                           GtkButton* button,
                                           const gchar* action);
static void dc_message_row_on_action_button_clicked (GtkButton* button,
                                              DcMessageRow* row);
static void dc_message_row_on_selection_toggled (GtkCheckButton* check,
                                          DcMessageRow* row);
VALA_EXTERN gboolean dc_message_get_selected (DcMessage* self);
VALA_EXTERN void dc_message_set_selected (DcMessage* self,
                              gboolean value);
VALA_EXTERN gboolean dc_message_get_has_file (DcMessage* self);
VALA_EXTERN gboolean dc_message_is_image_file (DcMessage* self);
static void dc_message_row_append_irc_images (GtkBox* body,
                                       DcMessage* msg,
                                       GPtrArray* trailing_images);
static void dc_message_row_append_bubble_image (GtkBox* bubble,
                                         DcMessage* msg);
VALA_EXTERN gboolean dc_message_is_video_file (DcMessage* self);
static GtkWidget* dc_message_row_build_video_preview (DcMessage* msg);
VALA_EXTERN gboolean dc_message_is_audio_file (DcMessage* self);
static GtkWidget* dc_message_row_build_audio_player (DcMessageRow* self,
                                              DcMessage* msg);
static void dc_message_row_set_audio_player (DcMessageRow* self,
                                      DcAudioPlayer* value);
VALA_EXTERN gboolean dc_message_is_webxdc (DcMessage* self);
static GtkWidget* dc_message_row_build_webxdc_card (DcMessageRow* self,
                                             DcMessage* msg);
static GtkBox* dc_message_row_build_file_indicator (DcMessage* msg);
VALA_EXTERN gchar* dc_message_display_file_name (DcMessage* self,
                                     const gchar* fallback);
VALA_EXTERN gboolean dc_webxdc_enabled (void);
static void dc_message_row_load_webxdc_card_info (gint msg_id,
                                           GtkLabel* name,
                                           GtkImage* icon);
static Block23Data* block23_data_ref (Block23Data* _data23_);
static void block23_data_unref (void * _userdata_);
VALA_EXTERN void dc_webxdc_card_info (gint msg_id,
                          GAsyncReadyCallback _callback_,
                          gpointer _user_data_);
VALA_EXTERN gpointer dc_webxdc_card_info_ref (gpointer instance);
VALA_EXTERN void dc_webxdc_card_info_unref (gpointer instance);
VALA_EXTERN GParamSpec* dc_webxdc_param_spec_card_info (const gchar* name,
                                            const gchar* nick,
                                            const gchar* blurb,
                                            GType object_type,
                                            GParamFlags flags);
VALA_EXTERN void dc_webxdc_value_set_card_info (GValue* value,
                                    gpointer v_object);
VALA_EXTERN void dc_webxdc_value_take_card_info (GValue* value,
                                     gpointer v_object);
VALA_EXTERN gpointer dc_webxdc_value_get_card_info (const GValue* value);
VALA_EXTERN GType dc_webxdc_card_info_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcWebxdcCardInfo, dc_webxdc_card_info_unref)
VALA_EXTERN DcWebxdcCardInfo* dc_webxdc_card_info_finish (GAsyncResult* _res_);
static void __lambda17_ (Block23Data* _data23_,
                  GObject* obj,
                  GAsyncResult* res);
static void ___lambda17__gasync_ready_callback (GObject* source_object,
                                         GAsyncResult* res,
                                         gpointer self);
VALA_EXTERN const gchar* dc_message_get_sender_name (DcMessage* self);
static GtkWidget* dc_message_row_load_sticker (const gchar* path,
                                        gboolean video);
VALA_EXTERN const gchar* dc_message_get_file_path (DcMessage* self);
VALA_EXTERN gboolean dc_message_is_video_sticker_file (DcMessage* self);
static GtkWidget* dc_message_row_load_picture (const gchar* path,
                                        gint max_w,
                                        gint max_h,
                                        gint min_w,
                                        gint min_h,
                                        const gchar* css_class);
static void dc_message_row_append_irc_image (GtkBox* strip,
                                      DcMessage* m);
static GtkWidget* dc_message_row_load_video_sticker (const gchar* path);
static Block24Data* block24_data_ref (Block24Data* _data24_);
static void block24_data_unref (void * _userdata_);
static GtkGestureClick* dc_message_row_add_play_toggle (GtkWidget* widget);
static void _____lambda16_ (Block24Data* _data24_);
static void ______lambda16__gtk_gesture_click_released (GtkGestureClick* _sender,
                                                 gint n_press,
                                                 gdouble x,
                                                 gdouble y,
                                                 gpointer self);
static Block25Data* block25_data_ref (Block25Data* _data25_);
static void block25_data_unref (void * _userdata_);
static void __lambda14_ (Block25Data* _data25_);
static void ___lambda14__gtk_gesture_click_released (GtkGestureClick* _sender,
                                              gint n_press,
                                              gdouble x,
                                              gdouble y,
                                              gpointer self);
static void dc_message_row_fit_size (gint* dw,
                              gint* dh,
                              gint max_w,
                              gint max_h,
                              gint min_w,
                              gint min_h);
static gdouble dc_message_row_scale_ratio (gint limit,
                                    gint size,
                                    gdouble fallback);
VALA_EXTERN gint dc_message_get_sender_contact_id (DcMessage* self);
VALA_EXTERN const gchar* dc_message_get_override_sender_name (DcMessage* self);
static GtkWidget* dc_message_row_build_video_paintable (DcMessage* msg);
VALA_EXTERN const gchar* dc_message_get_file_name (DcMessage* self);
VALA_EXTERN DcAudioPlayer* dc_audio_player_new (DcMessage* message,
                                    gint account_id);
VALA_EXTERN DcAudioPlayer* dc_audio_player_construct (GType object_type,
                                          DcMessage* message,
                                          gint account_id);
VALA_EXTERN gboolean dc_message_get_is_failed (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_is_read (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_is_delivered (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_is_pending (DcMessage* self);
VALA_EXTERN gint dc_message_get_quote_msg_id (DcMessage* self);
static void dc_message_row_on_quote_clicked (GtkButton* button,
                                      DcMessageRow* row);
VALA_EXTERN const gchar* dc_message_get_quote_sender_name (DcMessage* self);
static gchar* dc_message_row_collapsed_preview (const gchar* text);
VALA_EXTERN gboolean dc_message_get_full_message_expanded (DcMessage* self);
VALA_EXTERN const gchar* dc_message_get_full_message_text (DcMessage* self);
static GtkLabel* dc_message_row_build_markup_label (const gchar* raw,
                                             gint max_width_chars,
                                             gint emoji_count,
                                             DcMentionRoster* roster);
VALA_EXTERN gboolean dc_message_get_has_full_message_action (DcMessage* self);
VALA_EXTERN GType dc_markdown_mode_get_type (void) G_GNUC_CONST ;
static GtkWidget* dc_message_row_build_text_with_markdown_blocks (DcMessageRow* self,
                                                           DcMessage* msg,
                                                           gint max_width_chars);
static gint dc_message_row_emoji_only_count (const gchar* raw);
VALA_EXTERN gboolean dc_message_get_is_downloading_full_message (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_full_message_loading (DcMessage* self);
VALA_EXTERN gboolean dc_message_get_can_download_full_message (DcMessage* self);
static void dc_message_row_on_full_message_clicked (GtkButton* button,
                                             DcMessageRow* row);
static void dc_message_row_on_full_message_view_clicked (GtkButton* button,
                                                  DcMessageRow* row);
VALA_EXTERN gint dc_message_row_get_message_id (DcMessageRow* self);
VALA_EXTERN gchar* dc_message_row_spread_adjacent_emoji (const gchar* raw);
VALA_EXTERN gchar* dc_mentions_render_markup (const gchar* raw,
                                  DcMentionRoster* roster);
VALA_EXTERN gchar* dc_markdown_format (const gchar* input);
static void dc_message_row_connect_label_links (GtkLabel* text);
static gboolean dc_message_row_on_label_activate_link (GtkLabel* sender,
                                                const gchar* uri,
                                                GtkLabel* text);
VALA_EXTERN GType dc_window_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcWindow, g_object_unref)
VALA_EXTERN void dc_window_open_mention (DcWindow* self,
                             const gchar* uri);
VALA_EXTERN gboolean dc_is_delta_invite_uri (const gchar* uri);
VALA_EXTERN void dc_window_handle_invite_uri (DcWindow* self,
                                  const gchar* uri);
static gchar* dc_message_row_code_fence_marker (const gchar* line);
static gpointer dc_message_row_markdown_table_block_ref (gpointer instance);
static void dc_message_row_markdown_table_block_unref (gpointer instance);
static GParamSpec* dc_message_row_param_spec_markdown_table_block (const gchar* name,
                                                            const gchar* nick,
                                                            const gchar* blurb,
                                                            GType object_type,
                                                            GParamFlags flags) G_GNUC_UNUSED ;
static void dc_message_row_value_set_markdown_table_block (GValue* value,
                                                    gpointer v_object) G_GNUC_UNUSED ;
static void dc_message_row_value_take_markdown_table_block (GValue* value,
                                                     gpointer v_object) G_GNUC_UNUSED ;
static gpointer dc_message_row_value_get_markdown_table_block (const GValue* value) G_GNUC_UNUSED ;
static GType dc_message_row_markdown_table_block_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessageRowMarkdownTableBlock, dc_message_row_markdown_table_block_unref)
static DcMessageRowMarkdownTableBlock* dc_message_row_parse_table_at (gchar** lines,
                                                               gint lines_length1,
                                                               gint start,
                                                               gint* end);
static void dc_message_row_append_text_block (DcMessageRow* self,
                                       GtkBox* body,
                                       gchar** lines,
                                       gint lines_length1,
                                       gint start,
                                       gint end,
                                       gint max_width_chars);
static GtkWidget* dc_message_row_build_table_grid (DcMessageRowMarkdownTableBlock* table,
                                            gint max_width_chars);
VALA_EXTERN gboolean dc_markdown_parse_task_checkbox (const gchar* line,
                                          gboolean* checked,
                                          gint* marker_start,
                                          gint* content_start);
static GtkWidget* dc_message_row_build_task_line (DcMessageRow* self,
                                           DcMessage* msg,
                                           gint line_index,
                                           gboolean checked,
                                           gint content_start,
                                           gint max_width_chars);
static gchar* dc_message_row_join_lines (gchar** lines,
                                  gint lines_length1,
                                  gint start,
                                  gint end);
VALA_EXTERN gboolean dc_message_get_can_edit_text (DcMessage* self);
static void dc_message_row_on_task_toggle_clicked (GtkButton* button,
                                            DcMessageRow* row);
static gchar* dc_message_row_toggled_task_text (const gchar* raw,
                                         gint line_index);
static gchar** dc_message_row_parse_table_row (const gchar* line,
                                        gint* result_length1);
static gboolean dc_message_row_is_table_separator (gchar** cells,
                                            gint cells_length1);
static DcMessageRowMarkdownTableBlock* dc_message_row_markdown_table_block_new (gint columns);
static DcMessageRowMarkdownTableBlock* dc_message_row_markdown_table_block_construct (GType object_type,
                                                                               gint columns);
static gpointer dc_message_row_markdown_table_row_ref (gpointer instance);
static void dc_message_row_markdown_table_row_unref (gpointer instance);
static GParamSpec* dc_message_row_param_spec_markdown_table_row (const gchar* name,
                                                          const gchar* nick,
                                                          const gchar* blurb,
                                                          GType object_type,
                                                          GParamFlags flags) G_GNUC_UNUSED ;
static void dc_message_row_value_set_markdown_table_row (GValue* value,
                                                  gpointer v_object) G_GNUC_UNUSED ;
static void dc_message_row_value_take_markdown_table_row (GValue* value,
                                                   gpointer v_object) G_GNUC_UNUSED ;
static gpointer dc_message_row_value_get_markdown_table_row (const GValue* value) G_GNUC_UNUSED ;
static GType dc_message_row_markdown_table_row_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessageRowMarkdownTableRow, dc_message_row_markdown_table_row_unref)
static gint dc_message_row_table_separator_align (const gchar* cell);
static DcMessageRowMarkdownTableRow* dc_message_row_markdown_table_row_new (gchar** cells,
                                                                     gint cells_length1,
                                                                     gboolean header);
static DcMessageRowMarkdownTableRow* dc_message_row_markdown_table_row_construct (GType object_type,
                                                                           gchar** cells,
                                                                           gint cells_length1,
                                                                           gboolean header);
static gint dc_message_row_table_cell_width_chars (gint columns,
                                            gint max_width_chars);
static GtkWidget* dc_message_row_build_table_cell (const gchar* raw,
                                            gint width_chars,
                                            gint align,
                                            gboolean header);
static gboolean dc_message_row_consume_emoji_sequence (const gchar* text,
                                                gint* index);
static void dc_message_row_consume_whitespace (const gchar* text,
                                        gint* index);
VALA_EXTERN gboolean dc_platform_is_macos (void);
static gboolean dc_message_row_is_keycap_base (gunichar c);
static gboolean dc_message_row_consume_variation_selectors (const gchar* text,
                                                     gint* index);
static gboolean dc_message_row_consume_char (const gchar* text,
                                      gint* index,
                                      gunichar expected);
static gboolean dc_message_row_is_regional_indicator (gunichar c);
static gboolean dc_message_row_is_emoji_base (gunichar c);
static void dc_message_row_consume_emoji_modifiers (const gchar* text,
                                             gint* index);
static gboolean dc_message_row_consume_emoji_modifier (const gchar* text,
                                                gint* index);
static void dc_message_row_consume_tag_sequence (const gchar* text,
                                          gint* index);
VALA_EXTERN GType dc_message_reaction_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessageReaction, g_object_unref)
VALA_EXTERN const gchar* dc_message_get_reactions (DcMessage* self);
static GtkWidget* dc_message_row_build_reaction_badge (DcMessageRow* self,
                                                DcMessage* msg,
                                                DcMessageReaction* reaction);
VALA_EXTERN DcMessageReaction* dc_message_reaction_new (const gchar* emoji);
VALA_EXTERN DcMessageReaction* dc_message_reaction_construct (GType object_type,
                                                  const gchar* emoji);
VALA_EXTERN void dc_message_reaction_set_count (DcMessageReaction* self,
                                    gint value);
VALA_EXTERN gint dc_message_reaction_get_count (DcMessageReaction* self);
VALA_EXTERN const gchar* dc_message_reaction_get_emoji (DcMessageReaction* self);
static GtkPopover* dc_message_row_build_reaction_popover (DcMessageRow* self,
                                                   DcMessage* msg,
                                                   DcMessageReaction* reaction);
static void dc_message_row_connect_reaction_popover (GtkButton* badge,
                                              GtkEventControllerMotion* motion,
                                              GtkPopover* popover);
static void dc_message_row_on_reaction_clicked (GtkButton* badge,
                                         GtkPopover* popover);
static void dc_message_row_on_reaction_enter (GtkEventControllerMotion* motion,
                                       gdouble x,
                                       gdouble y,
                                       GtkPopover* popover);
static void dc_message_row_on_reaction_leave (GtkEventControllerMotion* motion,
                                       GtkPopover* popover);
static void dc_message_row_on_reaction_badge_destroy (GtkButton* badge,
                                               GtkPopover* popover);
static void dc_message_row_on_reaction_popover_closed (GtkPopover* popover,
                                                GtkButton* badge);
static void dc_message_row_cancel_reaction_popdown (GtkPopover* popover);
static void dc_message_row_show_reaction_popover (GtkButton* badge,
                                           GtkPopover* popover);
static void dc_message_row_schedule_reaction_popdown (GtkPopover* popover);
static Block26Data* block26_data_ref (Block26Data* _data26_);
static void block26_data_unref (void * _userdata_);
static gboolean __lambda436_ (Block26Data* _data26_);
static gboolean ___lambda436__gsource_func (gpointer self);
VALA_EXTERN GType dc_message_reaction_user_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessageReactionUser, g_object_unref)
static GtkWidget* dc_message_row_build_reaction_user_row (DcMessageRow* self,
                                                   DcMessage* msg,
                                                   gint contact_id);
VALA_EXTERN gint dc_message_reaction_user_get_contact_id (DcMessageReactionUser* self);
static void dc_message_row_reaction_user_identity (DcMessageRow* self,
                                            DcMessage* msg,
                                            gint contact_id,
                                            gchar** name,
                                            gchar** avatar_path);
VALA_EXTERN GType dc_mention_member_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMentionMember, g_object_unref)
VALA_EXTERN DcMentionMember* dc_mention_roster_lookup_contact (DcMentionRoster* self,
                                                   gint contact_id);
VALA_EXTERN const gchar* dc_mention_member_get_display_name (DcMentionMember* self);
VALA_EXTERN const gchar* dc_mention_member_get_address (DcMentionMember* self);
VALA_EXTERN const gchar* dc_mention_member_get_avatar_path (DcMentionMember* self);
VALA_EXTERN GtkWidget* dc_message_row_build_date_separator (gint64 ts);
VALA_EXTERN gchar* dc_message_row_format_date_label (gint64 ts);
VALA_EXTERN gboolean dc_message_row_get_is_outgoing (DcMessageRow* self);
VALA_EXTERN DcAudioPlayer* dc_message_row_get_audio_player (DcMessageRow* self);
static void g_cclosure_user_marshal_VOID__STRING_OBJECT (GClosure * closure,
                                                  GValue * return_value,
                                                  guint n_param_values,
                                                  const GValue * param_values,
                                                  gpointer invocation_hint,
                                                  gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__INT_BOOLEAN (GClosure * closure,
                                                GValue * return_value,
                                                guint n_param_values,
                                                const GValue * param_values,
                                                gpointer invocation_hint,
                                                gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__INT_STRING (GClosure * closure,
                                               GValue * return_value,
                                               guint n_param_values,
                                               const GValue * param_values,
                                               gpointer invocation_hint,
                                               gpointer marshal_data);
static gchar** _vala_array_dup7 (gchar** self,
                          gssize length);
static void dc_message_row_markdown_table_row_finalize (DcMessageRowMarkdownTableRow * obj);
static GType dc_message_row_markdown_table_row_get_type_once (void);
static void _dc_message_row_markdown_table_row_unref0_ (gpointer var);
static void dc_message_row_markdown_table_block_finalize (DcMessageRowMarkdownTableBlock * obj);
static GType dc_message_row_markdown_table_block_get_type_once (void);
static void dc_message_row_finalize (GObject * obj);
static GType dc_message_row_get_type_once (void);
static void _vala_dc_message_row_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec);
static void _vala_dc_message_row_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static GRegex* _tmp_regex_0 = NULL;

static inline gpointer
dc_scaled_preview_frame_get_instance_private (DcScaledPreviewFrame* self)
{
	return G_STRUCT_MEMBER_P (self, DcScaledPreviewFrame_private_offset);
}

DcScaledPreviewFrame*
dc_scaled_preview_frame_construct (GType object_type,
                                   gint natural_width,
                                   gint natural_height,
                                   const gchar* css_class)
{
	DcScaledPreviewFrame * self = NULL;
	self = (DcScaledPreviewFrame*) g_object_new (object_type, NULL);
	self->priv->natural_width = MAX (1, natural_width);
	self->priv->natural_height = MAX (1, natural_height);
	gtk_widget_set_overflow ((GtkWidget*) self, GTK_OVERFLOW_HIDDEN);
	if (css_class != NULL) {
		gtk_widget_add_css_class ((GtkWidget*) self, css_class);
	}
	return self;
}

DcScaledPreviewFrame*
dc_scaled_preview_frame_new (gint natural_width,
                             gint natural_height,
                             const gchar* css_class)
{
	return dc_scaled_preview_frame_construct (DC_TYPE_SCALED_PREVIEW_FRAME, natural_width, natural_height, css_class);
}

void
dc_scaled_preview_frame_set_natural_size (DcScaledPreviewFrame* self,
                                          gint width,
                                          gint height)
{
	g_return_if_fail (self != NULL);
	self->priv->natural_width = MAX (1, width);
	self->priv->natural_height = MAX (1, height);
	gtk_widget_queue_resize ((GtkWidget*) self);
}

static void
dc_scaled_preview_frame_real_dispose (GObject* base)
{
	DcScaledPreviewFrame * self;
	GtkWidget* _tmp0_;
	self = (DcScaledPreviewFrame*) base;
	_tmp0_ = self->priv->_child;
	if (_tmp0_ != NULL) {
		GtkWidget* _tmp1_;
		_tmp1_ = self->priv->_child;
		gtk_widget_unparent (_tmp1_);
		_g_object_unref0 (self->priv->_child);
		self->priv->_child = NULL;
	}
	G_OBJECT_CLASS (dc_scaled_preview_frame_parent_class)->dispose ((GObject*) G_TYPE_CHECK_INSTANCE_CAST (self, gtk_widget_get_type (), GtkWidget));
}

static GtkSizeRequestMode
dc_scaled_preview_frame_real_get_request_mode (GtkWidget* base)
{
	DcScaledPreviewFrame * self;
	GtkSizeRequestMode result;
	self = (DcScaledPreviewFrame*) base;
	result = GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
	return result;
}

static void
dc_scaled_preview_frame_real_measure (GtkWidget* base,
                                      GtkOrientation orientation,
                                      gint for_size,
                                      gint* minimum,
                                      gint* natural,
                                      gint* minimum_baseline,
                                      gint* natural_baseline)
{
	DcScaledPreviewFrame * self;
	gint _vala_minimum = 0;
	gint _vala_natural = 0;
	gint _vala_minimum_baseline = 0;
	gint _vala_natural_baseline = 0;
	gint width = 0;
	gint height = 0;
	self = (DcScaledPreviewFrame*) base;
	_vala_natural_baseline = -1;
	_vala_minimum_baseline = _vala_natural_baseline;
	width = self->priv->natural_width;
	height = self->priv->natural_height;
	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
		_vala_minimum = 1;
		_vala_natural = width;
		if (minimum) {
			*minimum = _vala_minimum;
		}
		if (natural) {
			*natural = _vala_natural;
		}
		if (minimum_baseline) {
			*minimum_baseline = _vala_minimum_baseline;
		}
		if (natural_baseline) {
			*natural_baseline = _vala_natural_baseline;
		}
		return;
	}
	if (for_size > 0) {
		gint allocated_width = 0;
		gint h = 0;
		allocated_width = MIN (for_size, width);
		h = MAX (1, (gint) (((((gint64) height) * allocated_width) + (width / 2)) / width));
		_vala_natural = h;
		_vala_minimum = _vala_natural;
	} else {
		_vala_natural = height;
		_vala_minimum = _vala_natural;
	}
	if (minimum) {
		*minimum = _vala_minimum;
	}
	if (natural) {
		*natural = _vala_natural;
	}
	if (minimum_baseline) {
		*minimum_baseline = _vala_minimum_baseline;
	}
	if (natural_baseline) {
		*natural_baseline = _vala_natural_baseline;
	}
}

static void
dc_scaled_preview_frame_real_size_allocate (GtkWidget* base,
                                            gint width,
                                            gint height,
                                            gint baseline)
{
	DcScaledPreviewFrame * self;
	GtkWidget* _tmp0_;
	self = (DcScaledPreviewFrame*) base;
	_tmp0_ = self->priv->_child;
	if (_tmp0_ != NULL) {
		GtkWidget* _tmp1_;
		_tmp1_ = self->priv->_child;
		gtk_widget_allocate (_tmp1_, width, height, baseline, NULL);
	}
}

static void
dc_scaled_preview_frame_real_snapshot (GtkWidget* base,
                                       GtkSnapshot* snapshot)
{
	DcScaledPreviewFrame * self;
	GtkWidget* _tmp0_;
	self = (DcScaledPreviewFrame*) base;
	g_return_if_fail (snapshot != NULL);
	_tmp0_ = self->priv->_child;
	if (_tmp0_ != NULL) {
		GtkWidget* _tmp1_;
		_tmp1_ = self->priv->_child;
		gtk_widget_snapshot_child ((GtkWidget*) self, _tmp1_, snapshot);
	}
}

GtkWidget*
dc_scaled_preview_frame_get_child (DcScaledPreviewFrame* self)
{
	GtkWidget* result;
	GtkWidget* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_child;
	result = _tmp0_;
	return result;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

void
dc_scaled_preview_frame_set_child (DcScaledPreviewFrame* self,
                                   GtkWidget* value)
{
	GtkWidget* _tmp0_;
	GtkWidget* _tmp2_;
	GtkWidget* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_child;
	if (_tmp0_ != NULL) {
		GtkWidget* _tmp1_;
		_tmp1_ = self->priv->_child;
		gtk_widget_unparent (_tmp1_);
	}
	_tmp2_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_child);
	self->priv->_child = _tmp2_;
	_tmp3_ = self->priv->_child;
	if (_tmp3_ != NULL) {
		GtkWidget* _tmp4_;
		_tmp4_ = self->priv->_child;
		gtk_widget_set_parent (_tmp4_, (GtkWidget*) self);
	}
	gtk_widget_queue_resize ((GtkWidget*) self);
	g_object_notify_by_pspec ((GObject *) self, dc_scaled_preview_frame_properties[DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY]);
}

static void
dc_scaled_preview_frame_class_init (DcScaledPreviewFrameClass * klass,
                                    gpointer klass_data)
{
	dc_scaled_preview_frame_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcScaledPreviewFrame_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) dc_scaled_preview_frame_real_dispose;
	((GtkWidgetClass *) klass)->get_request_mode = (GtkSizeRequestMode (*) (GtkWidget*)) dc_scaled_preview_frame_real_get_request_mode;
	((GtkWidgetClass *) klass)->measure = (void (*) (GtkWidget*, GtkOrientation, gint, gint*, gint*, gint*, gint*)) dc_scaled_preview_frame_real_measure;
	((GtkWidgetClass *) klass)->size_allocate = (void (*) (GtkWidget*, gint, gint, gint)) dc_scaled_preview_frame_real_size_allocate;
	((GtkWidgetClass *) klass)->snapshot = (void (*) (GtkWidget*, GtkSnapshot*)) dc_scaled_preview_frame_real_snapshot;
	G_OBJECT_CLASS (klass)->get_property = _vala_dc_scaled_preview_frame_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_dc_scaled_preview_frame_set_property;
	G_OBJECT_CLASS (klass)->finalize = dc_scaled_preview_frame_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY, dc_scaled_preview_frame_properties[DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY] = g_param_spec_object ("child", "child", "child", gtk_widget_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
dc_scaled_preview_frame_instance_init (DcScaledPreviewFrame * self,
                                       gpointer klass)
{
	self->priv = dc_scaled_preview_frame_get_instance_private (self);
	self->priv->_child = NULL;
}

static void
dc_scaled_preview_frame_finalize (GObject * obj)
{
	DcScaledPreviewFrame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrame);
	_g_object_unref0 (self->priv->_child);
	G_OBJECT_CLASS (dc_scaled_preview_frame_parent_class)->finalize (obj);
}

static GType
dc_scaled_preview_frame_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcScaledPreviewFrameClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_scaled_preview_frame_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcScaledPreviewFrame), 0, (GInstanceInitFunc) dc_scaled_preview_frame_instance_init, NULL };
	GType dc_scaled_preview_frame_type_id;
	dc_scaled_preview_frame_type_id = g_type_register_static (gtk_widget_get_type (), "DcScaledPreviewFrame", &g_define_type_info, 0);
	DcScaledPreviewFrame_private_offset = g_type_add_instance_private (dc_scaled_preview_frame_type_id, sizeof (DcScaledPreviewFramePrivate));
	return dc_scaled_preview_frame_type_id;
}

GType
dc_scaled_preview_frame_get_type (void)
{
	static volatile gsize dc_scaled_preview_frame_type_id__once = 0;
	if (g_once_init_enter (&dc_scaled_preview_frame_type_id__once)) {
		GType dc_scaled_preview_frame_type_id;
		dc_scaled_preview_frame_type_id = dc_scaled_preview_frame_get_type_once ();
		g_once_init_leave (&dc_scaled_preview_frame_type_id__once, dc_scaled_preview_frame_type_id);
	}
	return dc_scaled_preview_frame_type_id__once;
}

static void
_vala_dc_scaled_preview_frame_get_property (GObject * object,
                                            guint property_id,
                                            GValue * value,
                                            GParamSpec * pspec)
{
	DcScaledPreviewFrame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrame);
	switch (property_id) {
		case DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY:
		g_value_set_object (value, dc_scaled_preview_frame_get_child (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_dc_scaled_preview_frame_set_property (GObject * object,
                                            guint property_id,
                                            const GValue * value,
                                            GParamSpec * pspec)
{
	DcScaledPreviewFrame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_SCALED_PREVIEW_FRAME, DcScaledPreviewFrame);
	switch (property_id) {
		case DC_SCALED_PREVIEW_FRAME_CHILD_PROPERTY:
		dc_scaled_preview_frame_set_child (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
dc_sticker_frame_paintable_get_instance_private (DcStickerFramePaintable* self)
{
	return G_STRUCT_MEMBER_P (self, DcStickerFramePaintable_private_offset);
}

DcStickerFramePaintable*
dc_sticker_frame_paintable_construct (GType object_type,
                                      GdkTexture* texture)
{
	DcStickerFramePaintable * self = NULL;
	GdkTexture* _tmp0_;
	g_return_val_if_fail (texture != NULL, NULL);
	self = (DcStickerFramePaintable*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (texture);
	_g_object_unref0 (self->priv->texture);
	self->priv->texture = _tmp0_;
	return self;
}

DcStickerFramePaintable*
dc_sticker_frame_paintable_new (GdkTexture* texture)
{
	return dc_sticker_frame_paintable_construct (DC_TYPE_STICKER_FRAME_PAINTABLE, texture);
}

void
dc_sticker_frame_paintable_set_texture (DcStickerFramePaintable* self,
                                        GdkTexture* texture)
{
	GdkTexture* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (texture != NULL);
	_tmp0_ = _g_object_ref0 (texture);
	_g_object_unref0 (self->priv->texture);
	self->priv->texture = _tmp0_;
	gdk_paintable_invalidate_contents ((GdkPaintable*) self);
}

static void
dc_sticker_frame_paintable_real_snapshot (GdkPaintable* base,
                                          GdkSnapshot* snapshot,
                                          gdouble width,
                                          gdouble height)
{
	DcStickerFramePaintable * self;
	GdkTexture* _tmp0_;
	self = (DcStickerFramePaintable*) base;
	g_return_if_fail (snapshot != NULL);
	_tmp0_ = self->priv->texture;
	gdk_paintable_snapshot ((GdkPaintable*) _tmp0_, snapshot, width, height);
}

static GdkPaintable*
dc_sticker_frame_paintable_real_get_current_image (GdkPaintable* base)
{
	DcStickerFramePaintable * self;
	GdkTexture* _tmp0_;
	GdkPaintable* _tmp1_;
	GdkPaintable* result;
	self = (DcStickerFramePaintable*) base;
	_tmp0_ = self->priv->texture;
	_tmp1_ = _g_object_ref0 ((GdkPaintable*) _tmp0_);
	result = _tmp1_;
	return result;
}

static GdkPaintableFlags
dc_sticker_frame_paintable_real_get_flags (GdkPaintable* base)
{
	DcStickerFramePaintable * self;
	GdkPaintableFlags result;
	self = (DcStickerFramePaintable*) base;
	result = GDK_PAINTABLE_STATIC_SIZE;
	return result;
}

static gint
dc_sticker_frame_paintable_real_get_intrinsic_width (GdkPaintable* base)
{
	DcStickerFramePaintable * self;
	GdkTexture* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint result;
	self = (DcStickerFramePaintable*) base;
	_tmp0_ = self->priv->texture;
	_tmp1_ = gdk_texture_get_width (_tmp0_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

static gint
dc_sticker_frame_paintable_real_get_intrinsic_height (GdkPaintable* base)
{
	DcStickerFramePaintable * self;
	GdkTexture* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint result;
	self = (DcStickerFramePaintable*) base;
	_tmp0_ = self->priv->texture;
	_tmp1_ = gdk_texture_get_height (_tmp0_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

static void
dc_sticker_frame_paintable_class_init (DcStickerFramePaintableClass * klass,
                                       gpointer klass_data)
{
	dc_sticker_frame_paintable_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcStickerFramePaintable_private_offset);
	G_OBJECT_CLASS (klass)->finalize = dc_sticker_frame_paintable_finalize;
}

static void
dc_sticker_frame_paintable_gdk_paintable_interface_init (GdkPaintableInterface * iface,
                                                         gpointer iface_data)
{
	dc_sticker_frame_paintable_gdk_paintable_parent_iface = g_type_interface_peek_parent (iface);
	iface->snapshot = (void (*) (GdkPaintable*, GdkSnapshot*, gdouble, gdouble)) dc_sticker_frame_paintable_real_snapshot;
	iface->get_current_image = (GdkPaintable* (*) (GdkPaintable*)) dc_sticker_frame_paintable_real_get_current_image;
	iface->get_flags = (GdkPaintableFlags (*) (GdkPaintable*)) dc_sticker_frame_paintable_real_get_flags;
	iface->get_intrinsic_width = (gint (*) (GdkPaintable*)) dc_sticker_frame_paintable_real_get_intrinsic_width;
	iface->get_intrinsic_height = (gint (*) (GdkPaintable*)) dc_sticker_frame_paintable_real_get_intrinsic_height;
}

static void
dc_sticker_frame_paintable_instance_init (DcStickerFramePaintable * self,
                                          gpointer klass)
{
	self->priv = dc_sticker_frame_paintable_get_instance_private (self);
}

static void
dc_sticker_frame_paintable_finalize (GObject * obj)
{
	DcStickerFramePaintable * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_STICKER_FRAME_PAINTABLE, DcStickerFramePaintable);
	_g_object_unref0 (self->priv->texture);
	G_OBJECT_CLASS (dc_sticker_frame_paintable_parent_class)->finalize (obj);
}

/**
     * Holds the current frame of a sticker animation. Gtk.Picture reacts to
     * set_paintable (and to invalidate-size) with queue_resize, which would
     * relayout the whole window once per frame — breaking clicks and
     * popovers while an animated sticker is visible — so frames must be
     * swapped behind one long-lived paintable that only invalidates its
     * contents. All frames of a PixbufAnimation share the animation's size,
     * so the intrinsic size never changes.
     */
static GType
dc_sticker_frame_paintable_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcStickerFramePaintableClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_sticker_frame_paintable_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcStickerFramePaintable), 0, (GInstanceInitFunc) dc_sticker_frame_paintable_instance_init, NULL };
	static const GInterfaceInfo gdk_paintable_info = { (GInterfaceInitFunc) dc_sticker_frame_paintable_gdk_paintable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType dc_sticker_frame_paintable_type_id;
	dc_sticker_frame_paintable_type_id = g_type_register_static (G_TYPE_OBJECT, "DcStickerFramePaintable", &g_define_type_info, 0);
	g_type_add_interface_static (dc_sticker_frame_paintable_type_id, gdk_paintable_get_type (), &gdk_paintable_info);
	DcStickerFramePaintable_private_offset = g_type_add_instance_private (dc_sticker_frame_paintable_type_id, sizeof (DcStickerFramePaintablePrivate));
	return dc_sticker_frame_paintable_type_id;
}

GType
dc_sticker_frame_paintable_get_type (void)
{
	static volatile gsize dc_sticker_frame_paintable_type_id__once = 0;
	if (g_once_init_enter (&dc_sticker_frame_paintable_type_id__once)) {
		GType dc_sticker_frame_paintable_type_id;
		dc_sticker_frame_paintable_type_id = dc_sticker_frame_paintable_get_type_once ();
		g_once_init_leave (&dc_sticker_frame_paintable_type_id__once, dc_sticker_frame_paintable_type_id);
	}
	return dc_sticker_frame_paintable_type_id__once;
}

static inline gpointer
dc_sticker_animation_get_instance_private (DcStickerAnimation* self)
{
	return G_STRUCT_MEMBER_P (self, DcStickerAnimation_private_offset);
}

static void
_dc_sticker_animation_on_map_gtk_widget_map (GtkWidget* _sender,
                                             gpointer self)
{
	dc_sticker_animation_on_map ((DcStickerAnimation*) self);
}

static void
_dc_sticker_animation_on_unmap_gtk_widget_unmap (GtkWidget* _sender,
                                                 gpointer self)
{
	dc_sticker_animation_on_unmap ((DcStickerAnimation*) self);
}

DcStickerAnimation*
dc_sticker_animation_construct (GType object_type,
                                GtkPicture* picture,
                                GdkPixbufAnimation* animation,
                                gboolean playing)
{
	DcStickerAnimation * self = NULL;
	GdkPixbufAnimation* _tmp0_;
	GdkPixbuf* _tmp1_;
	GdkTexture* _tmp2_;
	GdkTexture* _tmp3_;
	DcStickerFramePaintable* _tmp4_;
	DcStickerFramePaintable* _tmp5_;
	g_return_val_if_fail (picture != NULL, NULL);
	g_return_val_if_fail (animation != NULL, NULL);
	self = (DcStickerAnimation*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (animation);
	_g_object_unref0 (self->priv->animation);
	self->priv->animation = _tmp0_;
	self->priv->playing = playing;
	_tmp1_ = parla_pixbuf_animation_get_static_image (animation);
	_tmp2_ = dc_texture_from_pixbuf (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = dc_sticker_frame_paintable_new (_tmp3_);
	_g_object_unref0 (self->priv->paintable);
	self->priv->paintable = _tmp4_;
	_g_object_unref0 (_tmp3_);
	_tmp5_ = self->priv->paintable;
	gtk_picture_set_paintable (picture, (GdkPaintable*) _tmp5_);
	g_signal_connect_object ((GtkWidget*) picture, "map", (GCallback) _dc_sticker_animation_on_map_gtk_widget_map, self, 0);
	g_signal_connect_object ((GtkWidget*) picture, "unmap", (GCallback) _dc_sticker_animation_on_unmap_gtk_widget_unmap, self, 0);
	return self;
}

DcStickerAnimation*
dc_sticker_animation_new (GtkPicture* picture,
                          GdkPixbufAnimation* animation,
                          gboolean playing)
{
	return dc_sticker_animation_construct (DC_TYPE_STICKER_ANIMATION, picture, animation, playing);
}

void
dc_sticker_animation_toggle_playing (DcStickerAnimation* self)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	self->priv->playing = !self->priv->playing;
	if (self->priv->playing) {
		_tmp0_ = self->priv->mapped;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		dc_sticker_animation_start (self);
	} else {
		dc_sticker_animation_stop (self);
	}
}

static void
dc_sticker_animation_on_map (DcStickerAnimation* self)
{
	g_return_if_fail (self != NULL);
	self->priv->mapped = TRUE;
	if (self->priv->playing) {
		dc_sticker_animation_start (self);
	}
}

static void
dc_sticker_animation_on_unmap (DcStickerAnimation* self)
{
	g_return_if_fail (self != NULL);
	self->priv->mapped = FALSE;
	dc_sticker_animation_stop (self);
}

static void
dc_sticker_animation_start (DcStickerAnimation* self)
{
	GdkPixbufAnimationIter* _tmp0_;
	g_return_if_fail (self != NULL);
	if (self->priv->timeout_id != ((guint) 0)) {
		return;
	}
	_tmp0_ = self->priv->iter;
	if (_tmp0_ == NULL) {
		GdkPixbufAnimation* _tmp1_;
		GdkPixbufAnimationIter* _tmp2_;
		_tmp1_ = self->priv->animation;
		_tmp2_ = parla_pixbuf_animation_get_iter (_tmp1_);
		_g_object_unref0 (self->priv->iter);
		self->priv->iter = _tmp2_;
	}
	dc_sticker_animation_show_current_frame (self);
	dc_sticker_animation_schedule_next_frame (self);
}

static void
dc_sticker_animation_stop (DcStickerAnimation* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->timeout_id);
		self->priv->timeout_id = (guint) 0;
	}
}

static void
dc_sticker_animation_show_current_frame (DcStickerAnimation* self)
{
	DcStickerFramePaintable* _tmp0_;
	GdkPixbufAnimationIter* _tmp1_;
	GdkPixbuf* _tmp2_;
	GdkTexture* _tmp3_;
	GdkTexture* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->paintable;
	_tmp1_ = self->priv->iter;
	_tmp2_ = parla_pixbuf_animation_iter_get_pixbuf (_tmp1_);
	_tmp3_ = dc_texture_from_pixbuf (_tmp2_);
	_tmp4_ = _tmp3_;
	dc_sticker_frame_paintable_set_texture (_tmp0_, _tmp4_);
	_g_object_unref0 (_tmp4_);
}

static gboolean
__lambda15_ (DcStickerAnimation* self)
{
	GdkPixbufAnimationIter* _tmp0_;
	gboolean result;
	self->priv->timeout_id = (guint) 0;
	_tmp0_ = self->priv->iter;
	parla_pixbuf_animation_iter_advance (_tmp0_);
	dc_sticker_animation_show_current_frame (self);
	dc_sticker_animation_schedule_next_frame (self);
	result = G_SOURCE_REMOVE;
	return result;
}

static gboolean
___lambda15__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda15_ ((DcStickerAnimation*) self);
	return result;
}

static void
dc_sticker_animation_schedule_next_frame (DcStickerAnimation* self)
{
	gint delay = 0;
	GdkPixbufAnimationIter* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->iter;
	delay = parla_pixbuf_animation_iter_get_delay_time (_tmp0_);
	if (delay < 0) {
		return;
	}
	self->priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) MAX (delay, 20), ___lambda15__gsource_func, g_object_ref (self), g_object_unref);
}

static void
dc_sticker_animation_class_init (DcStickerAnimationClass * klass,
                                 gpointer klass_data)
{
	dc_sticker_animation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcStickerAnimation_private_offset);
	G_OBJECT_CLASS (klass)->finalize = dc_sticker_animation_finalize;
}

static void
dc_sticker_animation_instance_init (DcStickerAnimation * self,
                                    gpointer klass)
{
	self->priv = dc_sticker_animation_get_instance_private (self);
	self->priv->iter = NULL;
	self->priv->timeout_id = (guint) 0;
	self->priv->mapped = FALSE;
}

static void
dc_sticker_animation_finalize (GObject * obj)
{
	DcStickerAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_STICKER_ANIMATION, DcStickerAnimation);
	_g_object_unref0 (self->priv->animation);
	_g_object_unref0 (self->priv->iter);
	_g_object_unref0 (self->priv->paintable);
	G_OBJECT_CLASS (dc_sticker_animation_parent_class)->finalize (obj);
}

/**
     * Steps a Gtk.Picture through a Gdk.PixbufAnimation while the picture is
     * mapped. Frame delays come from the animation itself; the timer stops
     * whenever the widget leaves the visible tree, so off-screen stickers
     * cost nothing. Owned by the picture via object data (see
     * MessageRow.load_sticker), which keeps it alive exactly as long as the
     * widget.
     */
static GType
dc_sticker_animation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcStickerAnimationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_sticker_animation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcStickerAnimation), 0, (GInstanceInitFunc) dc_sticker_animation_instance_init, NULL };
	GType dc_sticker_animation_type_id;
	dc_sticker_animation_type_id = g_type_register_static (G_TYPE_OBJECT, "DcStickerAnimation", &g_define_type_info, 0);
	DcStickerAnimation_private_offset = g_type_add_instance_private (dc_sticker_animation_type_id, sizeof (DcStickerAnimationPrivate));
	return dc_sticker_animation_type_id;
}

GType
dc_sticker_animation_get_type (void)
{
	static volatile gsize dc_sticker_animation_type_id__once = 0;
	if (g_once_init_enter (&dc_sticker_animation_type_id__once)) {
		GType dc_sticker_animation_type_id;
		dc_sticker_animation_type_id = dc_sticker_animation_get_type_once ();
		g_once_init_leave (&dc_sticker_animation_type_id__once, dc_sticker_animation_type_id);
	}
	return dc_sticker_animation_type_id__once;
}

static inline gpointer
dc_sticker_video_animation_get_instance_private (DcStickerVideoAnimation* self)
{
	return G_STRUCT_MEMBER_P (self, DcStickerVideoAnimation_private_offset);
}

static void
_dc_sticker_video_animation_update_size_g_object_notify (GObject* _sender,
                                                         GParamSpec* pspec,
                                                         gpointer self)
{
	dc_sticker_video_animation_update_size ((DcStickerVideoAnimation*) self);
}

static void
_dc_sticker_video_animation_on_map_gtk_widget_map (GtkWidget* _sender,
                                                   gpointer self)
{
	dc_sticker_video_animation_on_map ((DcStickerVideoAnimation*) self);
}

static void
_dc_sticker_video_animation_on_unmap_gtk_widget_unmap (GtkWidget* _sender,
                                                       gpointer self)
{
	dc_sticker_video_animation_on_unmap ((DcStickerVideoAnimation*) self);
}

DcStickerVideoAnimation*
dc_sticker_video_animation_construct (GType object_type,
                                      GtkPicture* picture,
                                      DcScaledPreviewFrame* frame,
                                      const gchar* path,
                                      gboolean playing,
                                      gint max_size)
{
	DcStickerVideoAnimation * self = NULL;
	GtkMediaFile* _tmp0_;
	GtkMediaFile* _tmp1_;
	GtkMediaFile* _tmp2_;
	GtkMediaFile* _tmp3_;
	GtkMediaFile* _tmp4_;
	g_return_val_if_fail (picture != NULL, NULL);
	g_return_val_if_fail (frame != NULL, NULL);
	g_return_val_if_fail (path != NULL, NULL);
	self = (DcStickerVideoAnimation*) g_object_new (object_type, NULL);
	self->priv->picture = picture;
	self->priv->frame = frame;
	self->priv->playing = playing;
	self->priv->max_size = max_size;
	_tmp0_ = (GtkMediaFile*) gtk_media_file_new_for_filename (path);
	_g_object_unref0 (self->priv->media);
	self->priv->media = _tmp0_;
	_tmp1_ = self->priv->media;
	gtk_media_stream_set_loop ((GtkMediaStream*) _tmp1_, TRUE);
	_tmp2_ = self->priv->media;
	gtk_media_stream_set_muted ((GtkMediaStream*) _tmp2_, TRUE);
	_tmp3_ = self->priv->media;
	gtk_picture_set_paintable (picture, (GdkPaintable*) _tmp3_);
	_tmp4_ = self->priv->media;
	g_signal_connect_object ((GObject*) _tmp4_, "notify::prepared", (GCallback) _dc_sticker_video_animation_update_size_g_object_notify, self, 0);
	dc_sticker_video_animation_update_size (self);
	g_signal_connect_object ((GtkWidget*) picture, "map", (GCallback) _dc_sticker_video_animation_on_map_gtk_widget_map, self, 0);
	g_signal_connect_object ((GtkWidget*) picture, "unmap", (GCallback) _dc_sticker_video_animation_on_unmap_gtk_widget_unmap, self, 0);
	return self;
}

DcStickerVideoAnimation*
dc_sticker_video_animation_new (GtkPicture* picture,
                                DcScaledPreviewFrame* frame,
                                const gchar* path,
                                gboolean playing,
                                gint max_size)
{
	return dc_sticker_video_animation_construct (DC_TYPE_STICKER_VIDEO_ANIMATION, picture, frame, path, playing, max_size);
}

static void
dc_sticker_video_animation_update_size (DcStickerVideoAnimation* self)
{
	gint width = 0;
	GtkMediaFile* _tmp0_;
	gint height = 0;
	GtkMediaFile* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gdouble scale = 0.0;
	DcScaledPreviewFrame* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->media;
	width = gdk_paintable_get_intrinsic_width ((GdkPaintable*) _tmp0_);
	_tmp1_ = self->priv->media;
	height = gdk_paintable_get_intrinsic_height ((GdkPaintable*) _tmp1_);
	if (width <= 0) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = height <= 0;
	}
	if (_tmp2_) {
		return;
	}
	scale = MIN (1.0, MIN (((gdouble) self->priv->max_size) / width, ((gdouble) self->priv->max_size) / height));
	width = MAX (1, (gint) ((width * scale) + 0.5));
	height = MAX (1, (gint) ((height * scale) + 0.5));
	_tmp3_ = self->priv->frame;
	dc_scaled_preview_frame_set_natural_size (_tmp3_, width, height);
}

void
dc_sticker_video_animation_toggle_playing (DcStickerVideoAnimation* self)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	self->priv->playing = !self->priv->playing;
	if (self->priv->playing) {
		GtkPicture* _tmp1_;
		_tmp1_ = self->priv->picture;
		_tmp0_ = gtk_widget_get_mapped ((GtkWidget*) _tmp1_);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		GtkMediaFile* _tmp2_;
		_tmp2_ = self->priv->media;
		G_TYPE_INSTANCE_GET_CLASS ((GtkMediaStream*) _tmp2_, gtk_media_stream_get_type (), GtkMediaStreamClass)->play ((GtkMediaStream*) _tmp2_);
	} else {
		GtkMediaFile* _tmp3_;
		_tmp3_ = self->priv->media;
		gtk_media_stream_pause ((GtkMediaStream*) _tmp3_);
	}
}

static void
dc_sticker_video_animation_on_map (DcStickerVideoAnimation* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->playing) {
		GtkMediaFile* _tmp0_;
		_tmp0_ = self->priv->media;
		G_TYPE_INSTANCE_GET_CLASS ((GtkMediaStream*) _tmp0_, gtk_media_stream_get_type (), GtkMediaStreamClass)->play ((GtkMediaStream*) _tmp0_);
	}
}

static void
dc_sticker_video_animation_on_unmap (DcStickerVideoAnimation* self)
{
	GtkMediaFile* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->media;
	gtk_media_stream_pause ((GtkMediaStream*) _tmp0_);
}

static void
dc_sticker_video_animation_class_init (DcStickerVideoAnimationClass * klass,
                                       gpointer klass_data)
{
	dc_sticker_video_animation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcStickerVideoAnimation_private_offset);
	G_OBJECT_CLASS (klass)->finalize = dc_sticker_video_animation_finalize;
}

static void
dc_sticker_video_animation_instance_init (DcStickerVideoAnimation * self,
                                          gpointer klass)
{
	self->priv = dc_sticker_video_animation_get_instance_private (self);
}

static void
dc_sticker_video_animation_finalize (GObject * obj)
{
	DcStickerVideoAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_STICKER_VIDEO_ANIMATION, DcStickerVideoAnimation);
	_g_object_unref0 (self->priv->media);
	G_OBJECT_CLASS (dc_sticker_video_animation_parent_class)->finalize (obj);
}

/**
     * Presents a WebM sticker as a muted, looping media paintable. Playback
     * follows the picture's mapped state so stickers outside the viewport do
     * not consume decoding resources.
     */
static GType
dc_sticker_video_animation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcStickerVideoAnimationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_sticker_video_animation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcStickerVideoAnimation), 0, (GInstanceInitFunc) dc_sticker_video_animation_instance_init, NULL };
	GType dc_sticker_video_animation_type_id;
	dc_sticker_video_animation_type_id = g_type_register_static (G_TYPE_OBJECT, "DcStickerVideoAnimation", &g_define_type_info, 0);
	DcStickerVideoAnimation_private_offset = g_type_add_instance_private (dc_sticker_video_animation_type_id, sizeof (DcStickerVideoAnimationPrivate));
	return dc_sticker_video_animation_type_id;
}

GType
dc_sticker_video_animation_get_type (void)
{
	static volatile gsize dc_sticker_video_animation_type_id__once = 0;
	if (g_once_init_enter (&dc_sticker_video_animation_type_id__once)) {
		GType dc_sticker_video_animation_type_id;
		dc_sticker_video_animation_type_id = dc_sticker_video_animation_get_type_once ();
		g_once_init_leave (&dc_sticker_video_animation_type_id__once, dc_sticker_video_animation_type_id);
	}
	return dc_sticker_video_animation_type_id__once;
}

static inline gpointer
dc_message_row_get_instance_private (DcMessageRow* self)
{
	return G_STRUCT_MEMBER_P (self, DcMessageRow_private_offset);
}

void
dc_message_row_highlight (DcMessageRow* self)
{
	g_return_if_fail (self != NULL);
	gtk_widget_add_css_class ((GtkWidget*) self, "message-new");
	dc_message_row_clear_highlight_later (self);
}

static Block22Data*
block22_data_ref (Block22Data* _data22_)
{
	g_atomic_int_inc (&_data22_->_ref_count_);
	return _data22_;
}

static void
block22_data_unref (void * _userdata_)
{
	Block22Data* _data22_;
	_data22_ = (Block22Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data22_->_ref_count_)) {
		g_weak_ref_clear (&_data22_->row_ref);
		g_slice_free (Block22Data, _data22_);
	}
}

static gboolean
__lambda13_ (Block22Data* _data22_)
{
	DcMessageRow* live_row = NULL;
	GObject* _tmp0_;
	DcMessageRow* _tmp1_;
	DcMessageRow* _tmp2_;
	gboolean result;
	_tmp0_ = g_weak_ref_get (&_data22_->row_ref);
	_tmp1_ = DC_IS_MESSAGE_ROW (_tmp0_) ? ((DcMessageRow*) _tmp0_) : NULL;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (_tmp0_);
	}
	live_row = _tmp1_;
	_tmp2_ = live_row;
	if (_tmp2_ != NULL) {
		DcMessageRow* _tmp3_;
		_tmp3_ = live_row;
		gtk_widget_remove_css_class ((GtkWidget*) _tmp3_, "message-new");
	}
	result = G_SOURCE_REMOVE;
	_g_object_unref0 (live_row);
	return result;
}

static gboolean
___lambda13__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda13_ (self);
	return result;
}

static void
dc_message_row_clear_highlight_later (DcMessageRow* row)
{
	Block22Data* _data22_;
	g_return_if_fail (row != NULL);
	_data22_ = g_slice_new0 (Block22Data);
	_data22_->_ref_count_ = 1;
	g_weak_ref_init (&_data22_->row_ref, (GObject*) row);
	g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 2000, ___lambda13__gsource_func, block22_data_ref (_data22_), block22_data_unref);
	block22_data_unref (_data22_);
	_data22_ = NULL;
}

gboolean
dc_message_row_has_selectable_text (DcMessageRow* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = dc_message_row_has_selectable_text_in ((GtkWidget*) self);
	return result;
}

gboolean
dc_message_row_select_all_text (DcMessageRow* self)
{
	gboolean selected = FALSE;
	gboolean focused = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	selected = FALSE;
	focused = FALSE;
	dc_message_row_select_all_text_in ((GtkWidget*) self, &selected, &focused);
	result = selected;
	return result;
}

static gboolean
dc_message_row_has_selectable_text_in (GtkWidget* widget)
{
	GtkLabel* label = NULL;
	GtkLabel* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GtkLabel* _tmp3_;
	gboolean result;
	if (widget == NULL) {
		result = FALSE;
		return result;
	}
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (widget, gtk_label_get_type ()) ? ((GtkLabel*) widget) : NULL);
	label = _tmp0_;
	_tmp3_ = label;
	if (_tmp3_ != NULL) {
		GtkLabel* _tmp4_;
		gboolean _tmp5_;
		gboolean _tmp6_;
		_tmp4_ = label;
		_tmp5_ = gtk_label_get_selectable (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp2_ = _tmp6_;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GtkLabel* _tmp7_;
		const gchar* _tmp8_;
		gint _tmp9_;
		gint _tmp10_;
		_tmp7_ = label;
		_tmp8_ = gtk_label_get_text (_tmp7_);
		_tmp9_ = strlen (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp1_ = _tmp10_ > 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		result = TRUE;
		_g_object_unref0 (label);
		return result;
	}
	{
		GtkWidget* child = NULL;
		GtkWidget* _tmp11_;
		GtkWidget* _tmp12_;
		_tmp11_ = gtk_widget_get_first_child (widget);
		_tmp12_ = _g_object_ref0 (_tmp11_);
		child = _tmp12_;
		{
			gboolean _tmp13_ = FALSE;
			_tmp13_ = TRUE;
			while (TRUE) {
				GtkWidget* _tmp17_;
				GtkWidget* _tmp18_;
				if (!_tmp13_) {
					GtkWidget* _tmp14_;
					GtkWidget* _tmp15_;
					GtkWidget* _tmp16_;
					_tmp14_ = child;
					_tmp15_ = gtk_widget_get_next_sibling (_tmp14_);
					_tmp16_ = _g_object_ref0 (_tmp15_);
					_g_object_unref0 (child);
					child = _tmp16_;
				}
				_tmp13_ = FALSE;
				_tmp17_ = child;
				if (!(_tmp17_ != NULL)) {
					break;
				}
				_tmp18_ = child;
				if (dc_message_row_has_selectable_text_in (_tmp18_)) {
					result = TRUE;
					_g_object_unref0 (child);
					_g_object_unref0 (label);
					return result;
				}
			}
		}
		_g_object_unref0 (child);
	}
	result = FALSE;
	_g_object_unref0 (label);
	return result;
}

static void
dc_message_row_select_all_text_in (GtkWidget* widget,
                                   gboolean* selected,
                                   gboolean* focused)
{
	GtkLabel* label = NULL;
	GtkLabel* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GtkLabel* _tmp3_;
	if (widget == NULL) {
		return;
	}
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (widget, gtk_label_get_type ()) ? ((GtkLabel*) widget) : NULL);
	label = _tmp0_;
	_tmp3_ = label;
	if (_tmp3_ != NULL) {
		GtkLabel* _tmp4_;
		gboolean _tmp5_;
		gboolean _tmp6_;
		_tmp4_ = label;
		_tmp5_ = gtk_label_get_selectable (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp2_ = _tmp6_;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GtkLabel* _tmp7_;
		const gchar* _tmp8_;
		gint _tmp9_;
		gint _tmp10_;
		_tmp7_ = label;
		_tmp8_ = gtk_label_get_text (_tmp7_);
		_tmp9_ = strlen (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp1_ = _tmp10_ > 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GtkLabel* _tmp12_;
		if (!(*focused)) {
			GtkLabel* _tmp11_;
			_tmp11_ = label;
			gtk_widget_grab_focus ((GtkWidget*) _tmp11_);
			*focused = TRUE;
		}
		_tmp12_ = label;
		gtk_label_select_region (_tmp12_, 0, -1);
		*selected = TRUE;
	}
	{
		GtkWidget* child = NULL;
		GtkWidget* _tmp13_;
		GtkWidget* _tmp14_;
		_tmp13_ = gtk_widget_get_first_child (widget);
		_tmp14_ = _g_object_ref0 (_tmp13_);
		child = _tmp14_;
		{
			gboolean _tmp15_ = FALSE;
			_tmp15_ = TRUE;
			while (TRUE) {
				GtkWidget* _tmp19_;
				GtkWidget* _tmp20_;
				if (!_tmp15_) {
					GtkWidget* _tmp16_;
					GtkWidget* _tmp17_;
					GtkWidget* _tmp18_;
					_tmp16_ = child;
					_tmp17_ = gtk_widget_get_next_sibling (_tmp16_);
					_tmp18_ = _g_object_ref0 (_tmp17_);
					_g_object_unref0 (child);
					child = _tmp18_;
				}
				_tmp15_ = FALSE;
				_tmp19_ = child;
				if (!(_tmp19_ != NULL)) {
					break;
				}
				_tmp20_ = child;
				dc_message_row_select_all_text_in (_tmp20_, selected, focused);
			}
		}
		_g_object_unref0 (child);
	}
	_g_object_unref0 (label);
}

DcMessageRow*
dc_message_row_construct (GType object_type,
                          DcMessage* msg,
                          DcMessage* prev,
                          GPtrArray* trailing_images,
                          gboolean is_image_continuation,
                          DcBubbleAvatarDisplay avatar_display,
                          gboolean avatar_scope_enabled,
                          gboolean show_sender_name,
                          DcMentionRoster* mention_roster,
                          DcMentionRoster* reaction_roster,
                          gint account_id)
{
	DcMessageRow * self = NULL;
	gint _tmp0_;
	gint _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp3_;
	DcMentionRoster* _tmp4_;
	DcMentionRoster* _tmp5_;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp7_;
	gboolean _tmp8_;
	g_return_val_if_fail (msg != NULL, NULL);
	self = (DcMessageRow*) g_object_new (object_type, "orientation", GTK_ORIENTATION_HORIZONTAL, "spacing", 0, NULL);
	_tmp0_ = dc_message_get_id (msg);
	_tmp1_ = _tmp0_;
	dc_message_row_set_message_id (self, _tmp1_);
	_tmp2_ = dc_message_get_is_outgoing (msg);
	_tmp3_ = _tmp2_;
	dc_message_row_set_is_outgoing (self, _tmp3_);
	_tmp4_ = _g_object_ref0 (mention_roster);
	_g_object_unref0 (self->priv->mention_roster);
	self->priv->mention_roster = _tmp4_;
	_tmp5_ = _g_object_ref0 (reaction_roster);
	_g_object_unref0 (self->priv->reaction_roster);
	self->priv->reaction_roster = _tmp5_;
	self->priv->account_id = account_id;
	gtk_widget_set_hexpand ((GtkWidget*) self, TRUE);
	gtk_widget_set_halign ((GtkWidget*) self, GTK_ALIGN_FILL);
	if (dc_message_row_style == DC_MESSAGE_STYLE_IRC) {
		_tmp6_ = is_image_continuation;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		dc_message_row_build_irc_row (self, msg, trailing_images, TRUE);
		return self;
	}
	dc_message_row_append_selection_checkbox (self, msg);
	_tmp7_ = dc_message_get_is_info (msg);
	_tmp8_ = _tmp7_;
	if (_tmp8_) {
		dc_message_row_build_info_row (self, msg);
		return self;
	}
	switch (dc_message_row_style) {
		case DC_MESSAGE_STYLE_IRC:
		{
			dc_message_row_build_irc_row (self, msg, trailing_images, FALSE);
			break;
		}
		case DC_MESSAGE_STYLE_WORKSPACE:
		{
			dc_message_row_build_workspace_row (self, msg, prev);
			break;
		}
		default:
		{
			dc_message_row_build_bubble_row (self, msg, avatar_display, avatar_scope_enabled, show_sender_name);
			break;
		}
	}
	return self;
}

DcMessageRow*
dc_message_row_new (DcMessage* msg,
                    DcMessage* prev,
                    GPtrArray* trailing_images,
                    gboolean is_image_continuation,
                    DcBubbleAvatarDisplay avatar_display,
                    gboolean avatar_scope_enabled,
                    gboolean show_sender_name,
                    DcMentionRoster* mention_roster,
                    DcMentionRoster* reaction_roster,
                    gint account_id)
{
	return dc_message_row_construct (DC_TYPE_MESSAGE_ROW, msg, prev, trailing_images, is_image_continuation, avatar_display, avatar_scope_enabled, show_sender_name, mention_roster, reaction_roster, account_id);
}

/**
         * Forwarded marker, quote block, attachment and body text — the
         * shared middle of every message style. The forwarded indicator
         * replaces the plain sender line in bubbles: it already names the
         * forwarder (incoming) or just reads "Forwarded".
         */
static void
dc_message_row_append_content (DcMessageRow* self,
                               GtkBox* box,
                               DcMessage* msg,
                               gint quote_width,
                               gint quote_lines,
                               gboolean irc,
                               GPtrArray* trailing,
                               gint text_width)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp4_ = FALSE;
	const gchar* _tmp5_;
	const gchar* _tmp6_;
	gboolean _tmp13_ = FALSE;
	const gchar* _tmp14_;
	const gchar* _tmp15_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (box != NULL);
	g_return_if_fail (msg != NULL);
	_tmp0_ = dc_message_get_is_forwarded (msg);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		GtkLabel* _tmp2_;
		GtkLabel* _tmp3_;
		_tmp2_ = dc_message_row_build_forwarded_indicator (msg);
		_tmp3_ = _tmp2_;
		gtk_box_append (box, (GtkWidget*) _tmp3_);
		_g_object_unref0 (_tmp3_);
	}
	_tmp5_ = dc_message_get_quote_text (msg);
	_tmp6_ = _tmp5_;
	if (_tmp6_ != NULL) {
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		gint _tmp9_;
		gint _tmp10_;
		_tmp7_ = dc_message_get_quote_text (msg);
		_tmp8_ = _tmp7_;
		_tmp9_ = strlen (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp4_ = _tmp10_ > 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		GtkButton* _tmp11_;
		GtkButton* _tmp12_;
		_tmp11_ = dc_message_row_build_quote_block (self, msg, quote_width, quote_lines);
		_tmp12_ = _tmp11_;
		gtk_box_append (box, (GtkWidget*) _tmp12_);
		_g_object_unref0 (_tmp12_);
	}
	dc_message_row_append_attachment (self, box, msg, irc, trailing);
	_tmp14_ = dc_message_get_text (msg);
	_tmp15_ = _tmp14_;
	if (_tmp15_ != NULL) {
		const gchar* _tmp16_;
		const gchar* _tmp17_;
		gint _tmp18_;
		gint _tmp19_;
		_tmp16_ = dc_message_get_text (msg);
		_tmp17_ = _tmp16_;
		_tmp18_ = strlen (_tmp17_);
		_tmp19_ = _tmp18_;
		_tmp13_ = _tmp19_ > 0;
	} else {
		_tmp13_ = FALSE;
	}
	if (_tmp13_) {
		GtkWidget* _tmp20_;
		GtkWidget* _tmp21_;
		_tmp20_ = dc_message_row_build_text_widget (self, msg, text_width);
		_tmp21_ = _tmp20_;
		gtk_box_append (box, _tmp21_);
		_g_object_unref0 (_tmp21_);
	}
}

/** Edited marker, delivery tick and pin icon, laid inline at the end
            of a compact (IRC / Workspace) row. Bubbles keep them in their own
            footer under the text instead. Workspace bottom-aligns them so the
            hover action bar (top-right) does not cover them. */
static void
dc_message_row_append_meta_indicators (DcMessageRow* self,
                                       GtkBox* box,
                                       DcMessage* msg,
                                       GtkAlign align)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	GtkLabel* pin = NULL;
	GtkLabel* _tmp11_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (box != NULL);
	g_return_if_fail (msg != NULL);
	_tmp0_ = dc_message_get_is_edited (msg);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		GtkLabel* edited = NULL;
		GtkLabel* _tmp2_;
		GtkLabel* _tmp3_;
		GtkLabel* _tmp4_;
		_tmp2_ = dc_message_row_build_edited_indicator ("(edited)");
		edited = _tmp2_;
		_tmp3_ = edited;
		gtk_widget_set_valign ((GtkWidget*) _tmp3_, align);
		_tmp4_ = edited;
		gtk_box_append (box, (GtkWidget*) _tmp4_);
		_g_object_unref0 (edited);
	}
	_tmp5_ = dc_message_get_is_outgoing (msg);
	_tmp6_ = _tmp5_;
	if (_tmp6_) {
		GtkLabel* tick = NULL;
		GtkLabel* _tmp7_;
		GtkLabel* _tmp8_;
		_tmp7_ = dc_message_row_build_tick_indicator (msg);
		tick = _tmp7_;
		_tmp8_ = tick;
		if (_tmp8_ != NULL) {
			GtkLabel* _tmp9_;
			GtkLabel* _tmp10_;
			_tmp9_ = tick;
			gtk_widget_set_valign ((GtkWidget*) _tmp9_, align);
			_tmp10_ = tick;
			gtk_box_append (box, (GtkWidget*) _tmp10_);
		}
		_g_object_unref0 (tick);
	}
	_tmp11_ = dc_message_row_build_pin_indicator (msg);
	pin = _tmp11_;
	gtk_widget_set_valign ((GtkWidget*) pin, align);
	gtk_box_append (box, (GtkWidget*) pin);
	_g_object_unref0 (pin);
}

static void
dc_message_row_flag_self_mention (DcMessageRow* self,
                                  DcMessage* msg)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_tmp1_ = dc_message_get_is_outgoing (msg);
	_tmp2_ = _tmp1_;
	if (!_tmp2_) {
		const gchar* _tmp3_;
		const gchar* _tmp4_;
		DcMentionRoster* _tmp5_;
		_tmp3_ = dc_message_get_text (msg);
		_tmp4_ = _tmp3_;
		_tmp5_ = self->priv->mention_roster;
		_tmp0_ = dc_mentions_has_self_mention (_tmp4_, _tmp5_);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gtk_widget_add_css_class ((GtkWidget*) self, "mentions-me");
	}
}

static void
dc_message_row_build_bubble_row (DcMessageRow* self,
                                 DcMessage* msg,
                                 DcBubbleAvatarDisplay avatar_display,
                                 gboolean avatar_scope_enabled,
                                 gboolean show_sender_name)
{
	gboolean outgoing = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean show_avatar = FALSE;
	GtkBox* bubble = NULL;
	GtkBox* _tmp2_;
	GtkBox* _tmp3_;
	const gchar* _tmp4_ = NULL;
	GtkBox* _tmp5_;
	gboolean _tmp6_ = FALSE;
	GtkBox* _tmp11_;
	gboolean _tmp12_ = FALSE;
	gboolean _tmp13_ = FALSE;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_;
	gboolean _tmp16_;
	gboolean _tmp27_ = FALSE;
	gboolean _tmp28_ = FALSE;
	gboolean _tmp29_;
	gboolean _tmp30_;
	GtkBox* _tmp51_;
	GtkBox* footer = NULL;
	GtkBox* _tmp52_;
	GtkBox* _tmp53_;
	gboolean _tmp54_;
	gboolean _tmp55_;
	GtkLabel* time_lbl = NULL;
	gint64 _tmp59_;
	gint64 _tmp60_;
	gchar* _tmp61_;
	gchar* _tmp62_;
	GtkLabel* _tmp63_;
	GtkLabel* _tmp64_;
	GtkLabel* _tmp65_;
	GtkBox* _tmp66_;
	GtkLabel* _tmp67_;
	GtkBox* _tmp72_;
	GtkLabel* _tmp73_;
	GtkLabel* _tmp74_;
	GtkBox* _tmp75_;
	GtkBox* _tmp76_;
	GtkBox* reactions_box = NULL;
	GtkBox* _tmp77_;
	GtkBox* _tmp78_;
	gboolean _tmp84_ = FALSE;
	GtkBox* _tmp87_;
	gboolean _tmp88_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_tmp0_ = dc_message_get_is_outgoing (msg);
	_tmp1_ = _tmp0_;
	outgoing = _tmp1_;
	show_avatar = dc_message_row_should_show_bubble_avatar (msg, avatar_display, avatar_scope_enabled);
	gtk_widget_set_margin_start ((GtkWidget*) self, 8);
	gtk_widget_set_margin_end ((GtkWidget*) self, 8);
	gtk_widget_set_margin_top ((GtkWidget*) self, 2);
	gtk_widget_set_margin_bottom ((GtkWidget*) self, 2);
	_tmp2_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
	g_object_ref_sink (_tmp2_);
	bubble = _tmp2_;
	_tmp3_ = bubble;
	gtk_widget_add_css_class ((GtkWidget*) _tmp3_, "message-bubble");
	if (outgoing) {
		_tmp4_ = "outgoing";
	} else {
		_tmp4_ = "incoming";
	}
	_tmp5_ = bubble;
	gtk_widget_add_css_class ((GtkWidget*) _tmp5_, _tmp4_);
	if (!outgoing) {
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		DcMentionRoster* _tmp9_;
		_tmp7_ = dc_message_get_text (msg);
		_tmp8_ = _tmp7_;
		_tmp9_ = self->priv->mention_roster;
		_tmp6_ = dc_mentions_has_self_mention (_tmp8_, _tmp9_);
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		GtkBox* _tmp10_;
		_tmp10_ = bubble;
		gtk_widget_add_css_class ((GtkWidget*) _tmp10_, "mentions-me");
	}
	_tmp11_ = bubble;
	gtk_widget_set_valign ((GtkWidget*) _tmp11_, GTK_ALIGN_START);
	_tmp15_ = dc_message_get_is_image_only (msg);
	_tmp16_ = _tmp15_;
	if (_tmp16_) {
		gboolean _tmp17_;
		gboolean _tmp18_;
		_tmp17_ = dc_message_get_has_local_file (msg);
		_tmp18_ = _tmp17_;
		_tmp14_ = _tmp18_;
	} else {
		_tmp14_ = FALSE;
	}
	if (_tmp14_) {
		_tmp13_ = dc_message_is_sticker_file (msg);
	} else {
		_tmp13_ = FALSE;
	}
	if (_tmp13_) {
		gboolean _tmp19_ = FALSE;
		const gchar* _tmp20_;
		const gchar* _tmp21_;
		_tmp20_ = dc_message_get_quote_text (msg);
		_tmp21_ = _tmp20_;
		if (_tmp21_ == NULL) {
			_tmp19_ = TRUE;
		} else {
			const gchar* _tmp22_;
			const gchar* _tmp23_;
			gint _tmp24_;
			gint _tmp25_;
			_tmp22_ = dc_message_get_quote_text (msg);
			_tmp23_ = _tmp22_;
			_tmp24_ = strlen (_tmp23_);
			_tmp25_ = _tmp24_;
			_tmp19_ = _tmp25_ == 0;
		}
		_tmp12_ = _tmp19_;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		GtkBox* _tmp26_;
		_tmp26_ = bubble;
		gtk_widget_add_css_class ((GtkWidget*) _tmp26_, "sticker");
	}
	_tmp29_ = dc_message_get_is_forwarded (msg);
	_tmp30_ = _tmp29_;
	if (!_tmp30_) {
		_tmp28_ = !outgoing;
	} else {
		_tmp28_ = FALSE;
	}
	if (_tmp28_) {
		_tmp27_ = show_sender_name;
	} else {
		_tmp27_ = FALSE;
	}
	if (_tmp27_) {
		gchar* author = NULL;
		gchar* _tmp31_;
		const gchar* _tmp32_;
		_tmp31_ = dc_message_row_effective_author_name (msg);
		author = _tmp31_;
		_tmp32_ = author;
		if (_tmp32_ != NULL) {
			GtkLabel* sender = NULL;
			const gchar* _tmp33_;
			GtkLabel* _tmp34_;
			GtkLabel* _tmp35_;
			GtkLabel* _tmp36_;
			GtkLabel* _tmp37_;
			GtkLabel* _tmp38_;
			gboolean _tmp39_ = FALSE;
			const gchar* _tmp40_;
			const gchar* _tmp41_;
			GtkBox* _tmp49_;
			GtkLabel* _tmp50_;
			_tmp33_ = author;
			_tmp34_ = (GtkLabel*) gtk_label_new (_tmp33_);
			g_object_ref_sink (_tmp34_);
			sender = _tmp34_;
			_tmp35_ = sender;
			gtk_widget_add_css_class ((GtkWidget*) _tmp35_, "message-sender");
			_tmp36_ = sender;
			gtk_widget_set_halign ((GtkWidget*) _tmp36_, GTK_ALIGN_START);
			_tmp37_ = sender;
			gtk_label_set_xalign (_tmp37_, (gfloat) 0);
			_tmp38_ = sender;
			gtk_label_set_ellipsize (_tmp38_, PANGO_ELLIPSIZE_END);
			_tmp40_ = dc_message_get_sender_address (msg);
			_tmp41_ = _tmp40_;
			if (_tmp41_ != NULL) {
				const gchar* _tmp42_;
				const gchar* _tmp43_;
				gint _tmp44_;
				gint _tmp45_;
				_tmp42_ = dc_message_get_sender_address (msg);
				_tmp43_ = _tmp42_;
				_tmp44_ = strlen (_tmp43_);
				_tmp45_ = _tmp44_;
				_tmp39_ = _tmp45_ > 0;
			} else {
				_tmp39_ = FALSE;
			}
			if (_tmp39_) {
				GtkLabel* _tmp46_;
				const gchar* _tmp47_;
				const gchar* _tmp48_;
				_tmp46_ = sender;
				_tmp47_ = dc_message_get_sender_address (msg);
				_tmp48_ = _tmp47_;
				gtk_widget_set_tooltip_text ((GtkWidget*) _tmp46_, _tmp48_);
			}
			_tmp49_ = bubble;
			_tmp50_ = sender;
			gtk_box_append (_tmp49_, (GtkWidget*) _tmp50_);
			_g_object_unref0 (sender);
		}
		_g_free0 (author);
	}
	_tmp51_ = bubble;
	dc_message_row_append_content (self, _tmp51_, msg, 40, 2, FALSE, NULL, 50);
	_tmp52_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
	g_object_ref_sink (_tmp52_);
	footer = _tmp52_;
	_tmp53_ = footer;
	gtk_widget_set_halign ((GtkWidget*) _tmp53_, GTK_ALIGN_END);
	_tmp54_ = dc_message_get_is_edited (msg);
	_tmp55_ = _tmp54_;
	if (_tmp55_) {
		GtkBox* _tmp56_;
		GtkLabel* _tmp57_;
		GtkLabel* _tmp58_;
		_tmp56_ = footer;
		_tmp57_ = dc_message_row_build_edited_indicator ("Edited");
		_tmp58_ = _tmp57_;
		gtk_box_append (_tmp56_, (GtkWidget*) _tmp58_);
		_g_object_unref0 (_tmp58_);
	}
	_tmp59_ = dc_message_get_timestamp (msg);
	_tmp60_ = _tmp59_;
	_tmp61_ = dc_message_row_format_timestamp (_tmp60_);
	_tmp62_ = _tmp61_;
	_tmp63_ = (GtkLabel*) gtk_label_new (_tmp62_);
	g_object_ref_sink (_tmp63_);
	_tmp64_ = _tmp63_;
	_g_free0 (_tmp62_);
	time_lbl = _tmp64_;
	_tmp65_ = time_lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp65_, "message-time");
	_tmp66_ = footer;
	_tmp67_ = time_lbl;
	gtk_box_append (_tmp66_, (GtkWidget*) _tmp67_);
	if (outgoing) {
		GtkLabel* tick = NULL;
		GtkLabel* _tmp68_;
		GtkLabel* _tmp69_;
		_tmp68_ = dc_message_row_build_tick_indicator (msg);
		tick = _tmp68_;
		_tmp69_ = tick;
		if (_tmp69_ != NULL) {
			GtkBox* _tmp70_;
			GtkLabel* _tmp71_;
			_tmp70_ = footer;
			_tmp71_ = tick;
			gtk_box_append (_tmp70_, (GtkWidget*) _tmp71_);
		}
		_g_object_unref0 (tick);
	}
	_tmp72_ = footer;
	_tmp73_ = dc_message_row_build_pin_indicator (msg);
	_tmp74_ = _tmp73_;
	gtk_box_append (_tmp72_, (GtkWidget*) _tmp74_);
	_g_object_unref0 (_tmp74_);
	_tmp75_ = bubble;
	_tmp76_ = footer;
	gtk_box_append (_tmp75_, (GtkWidget*) _tmp76_);
	_tmp77_ = dc_message_row_build_reactions_box (self, msg);
	reactions_box = _tmp77_;
	_tmp78_ = reactions_box;
	if (_tmp78_ != NULL) {
		GtkBox* _tmp79_;
		GtkBox* _tmp80_;
		_tmp79_ = bubble;
		_tmp80_ = reactions_box;
		gtk_box_append (_tmp79_, (GtkWidget*) _tmp80_);
	}
	if (outgoing) {
		GtkBox* spacer = NULL;
		GtkBox* _tmp81_;
		GtkBox* _tmp82_;
		GtkBox* _tmp83_;
		_tmp81_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
		g_object_ref_sink (_tmp81_);
		spacer = _tmp81_;
		_tmp82_ = spacer;
		gtk_widget_set_hexpand ((GtkWidget*) _tmp82_, TRUE);
		_tmp83_ = spacer;
		gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp83_);
		_g_object_unref0 (spacer);
	}
	if (!outgoing) {
		_tmp84_ = show_avatar;
	} else {
		_tmp84_ = FALSE;
	}
	if (_tmp84_) {
		GtkWidget* _tmp85_;
		GtkWidget* _tmp86_;
		_tmp85_ = dc_message_row_build_bubble_avatar (msg);
		_tmp86_ = _tmp85_;
		gtk_box_append ((GtkBox*) self, _tmp86_);
		_g_object_unref0 (_tmp86_);
	}
	_tmp87_ = bubble;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp87_);
	if (outgoing) {
		_tmp88_ = show_avatar;
	} else {
		_tmp88_ = FALSE;
	}
	if (_tmp88_) {
		GtkWidget* _tmp89_;
		GtkWidget* _tmp90_;
		_tmp89_ = dc_message_row_build_bubble_avatar (msg);
		_tmp90_ = _tmp89_;
		gtk_box_append ((GtkBox*) self, _tmp90_);
		_g_object_unref0 (_tmp90_);
	}
	if (!outgoing) {
		GtkBox* spacer = NULL;
		GtkBox* _tmp91_;
		GtkBox* _tmp92_;
		GtkBox* _tmp93_;
		_tmp91_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
		g_object_ref_sink (_tmp91_);
		spacer = _tmp91_;
		_tmp92_ = spacer;
		gtk_widget_set_hexpand ((GtkWidget*) _tmp92_, TRUE);
		_tmp93_ = spacer;
		gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp93_);
		_g_object_unref0 (spacer);
	}
	_g_object_unref0 (reactions_box);
	_g_object_unref0 (time_lbl);
	_g_object_unref0 (footer);
	_g_object_unref0 (bubble);
}

static void
dc_message_row_build_irc_row (DcMessageRow* self,
                              DcMessage* msg,
                              GPtrArray* trailing_images,
                              gboolean is_image_continuation)
{
	gchar* time_str = NULL;
	gint64 _tmp0_;
	gint64 _tmp1_;
	gchar* _tmp2_;
	GtkLabel* time_lbl = NULL;
	const gchar* _tmp3_;
	GtkLabel* _tmp4_;
	GtkLabel* _tmp5_;
	GtkLabel* _tmp6_;
	GtkLabel* _tmp7_;
	GtkLabel* _tmp8_;
	GtkLabel* _tmp9_;
	const gchar* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	GtkLabel* _tmp13_;
	gchar* sender = NULL;
	gchar* _tmp14_;
	GtkLabel* sender_lbl = NULL;
	const gchar* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	gchar* _tmp19_;
	GtkLabel* _tmp20_;
	GtkLabel* _tmp21_;
	GtkLabel* _tmp22_;
	const gchar* _tmp23_ = NULL;
	gboolean _tmp24_;
	gboolean _tmp25_;
	GtkLabel* _tmp26_;
	GtkLabel* _tmp27_;
	GtkLabel* _tmp28_;
	GtkLabel* _tmp29_;
	GtkLabel* _tmp30_;
	GtkBox* body = NULL;
	GtkBox* _tmp31_;
	GtkBox* _tmp32_;
	GtkBox* _tmp33_;
	GtkBox* reactions_box = NULL;
	GtkBox* _tmp34_;
	GtkBox* _tmp35_;
	GtkBox* _tmp38_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	if (is_image_continuation) {
		gtk_widget_add_css_class ((GtkWidget*) self, "message-irc");
		gtk_widget_add_css_class ((GtkWidget*) self, "message-irc-continuation");
		g_object_set ((GtkWidget*) self, "height-request", 0, NULL);
		gtk_widget_set_visible ((GtkWidget*) self, FALSE);
		return;
	}
	gtk_widget_set_margin_start ((GtkWidget*) self, 8);
	gtk_widget_set_margin_end ((GtkWidget*) self, 8);
	gtk_box_set_spacing ((GtkBox*) self, 6);
	gtk_widget_add_css_class ((GtkWidget*) self, "message-irc");
	dc_message_row_flag_self_mention (self, msg);
	_tmp0_ = dc_message_get_timestamp (msg);
	_tmp1_ = _tmp0_;
	_tmp2_ = dc_message_row_format_timestamp (_tmp1_);
	time_str = _tmp2_;
	_tmp3_ = time_str;
	_tmp4_ = (GtkLabel*) gtk_label_new (_tmp3_);
	g_object_ref_sink (_tmp4_);
	time_lbl = _tmp4_;
	_tmp5_ = time_lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp5_, "message-time");
	_tmp6_ = time_lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp6_, "irc-time");
	_tmp7_ = time_lbl;
	gtk_widget_set_valign ((GtkWidget*) _tmp7_, GTK_ALIGN_START);
	_tmp8_ = time_lbl;
	gtk_label_set_xalign (_tmp8_, (gfloat) 1);
	_tmp9_ = time_lbl;
	_tmp10_ = time_str;
	_tmp11_ = strlen (_tmp10_);
	_tmp12_ = _tmp11_;
	gtk_widget_set_visible ((GtkWidget*) _tmp9_, _tmp12_ > 0);
	_tmp13_ = time_lbl;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp13_);
	_tmp14_ = dc_message_row_effective_sender_name (msg);
	sender = _tmp14_;
	_tmp15_ = sender;
	_tmp16_ = g_strconcat ("<", _tmp15_, NULL);
	_tmp17_ = _tmp16_;
	_tmp18_ = g_strconcat (_tmp17_, ">", NULL);
	_tmp19_ = _tmp18_;
	_tmp20_ = (GtkLabel*) gtk_label_new (_tmp19_);
	g_object_ref_sink (_tmp20_);
	_tmp21_ = _tmp20_;
	_g_free0 (_tmp19_);
	_g_free0 (_tmp17_);
	sender_lbl = _tmp21_;
	_tmp22_ = sender_lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp22_, "message-sender");
	_tmp24_ = dc_message_get_is_outgoing (msg);
	_tmp25_ = _tmp24_;
	if (_tmp25_) {
		_tmp23_ = "message-sender-self";
	} else {
		_tmp23_ = "message-sender-other";
	}
	_tmp26_ = sender_lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp26_, _tmp23_);
	_tmp27_ = sender_lbl;
	gtk_widget_set_valign ((GtkWidget*) _tmp27_, GTK_ALIGN_START);
	_tmp28_ = sender_lbl;
	gtk_label_set_xalign (_tmp28_, (gfloat) 0);
	_tmp29_ = sender_lbl;
	gtk_label_set_ellipsize (_tmp29_, PANGO_ELLIPSIZE_NONE);
	_tmp30_ = sender_lbl;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp30_);
	_tmp31_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
	g_object_ref_sink (_tmp31_);
	body = _tmp31_;
	_tmp32_ = body;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp32_, TRUE);
	_tmp33_ = body;
	dc_message_row_append_content (self, _tmp33_, msg, 60, 1, TRUE, trailing_images, -1);
	_tmp34_ = dc_message_row_build_reactions_box (self, msg);
	reactions_box = _tmp34_;
	_tmp35_ = reactions_box;
	if (_tmp35_ != NULL) {
		GtkBox* _tmp36_;
		GtkBox* _tmp37_;
		_tmp36_ = body;
		_tmp37_ = reactions_box;
		gtk_box_append (_tmp36_, (GtkWidget*) _tmp37_);
	}
	_tmp38_ = body;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp38_);
	dc_message_row_append_meta_indicators (self, (GtkBox*) self, msg, GTK_ALIGN_START);
	_g_object_unref0 (reactions_box);
	_g_object_unref0 (body);
	_g_object_unref0 (sender_lbl);
	_g_free0 (sender);
	_g_object_unref0 (time_lbl);
	_g_free0 (time_str);
}

static void
dc_message_row_build_workspace_row (DcMessageRow* self,
                                    DcMessage* msg,
                                    DcMessage* prev)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean grouped = FALSE;
	gchar* sender = NULL;
	gchar* _tmp11_;
	GtkBox* content = NULL;
	GtkBox* _tmp12_;
	GtkBox* body = NULL;
	GtkBox* _tmp33_;
	GtkBox* _tmp34_;
	GtkBox* _tmp55_;
	GtkBox* reactions_box = NULL;
	GtkBox* _tmp56_;
	GtkBox* _tmp57_;
	GtkBox* _tmp60_;
	GtkBox* _tmp61_;
	GtkBox* _tmp62_;
	GtkWidget* bar = NULL;
	GtkWidget* _tmp63_;
	GtkEventControllerMotion* motion = NULL;
	GtkEventControllerMotion* _tmp64_;
	GtkEventController* _tmp65_;
	GtkOverlay* overlay = NULL;
	GtkOverlay* _tmp66_;
	GtkBox* _tmp67_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	gtk_widget_add_css_class ((GtkWidget*) self, "message-workspace");
	dc_message_row_flag_self_mention (self, msg);
	gtk_widget_set_margin_start ((GtkWidget*) self, 4);
	gtk_widget_set_margin_end ((GtkWidget*) self, 4);
	if (prev != NULL) {
		_tmp2_ = dc_message_row_same_sender (prev, msg);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		gint64 _tmp3_;
		gint64 _tmp4_;
		gint64 _tmp5_;
		gint64 _tmp6_;
		_tmp3_ = dc_message_get_timestamp (msg);
		_tmp4_ = _tmp3_;
		_tmp5_ = dc_message_get_timestamp (prev);
		_tmp6_ = _tmp5_;
		_tmp1_ = (_tmp4_ - _tmp6_) < ((gint64) 300);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gint64 _tmp7_;
		gint64 _tmp8_;
		gint64 _tmp9_;
		gint64 _tmp10_;
		_tmp7_ = dc_message_get_timestamp (msg);
		_tmp8_ = _tmp7_;
		_tmp9_ = dc_message_get_timestamp (prev);
		_tmp10_ = _tmp9_;
		_tmp0_ = dc_message_row_same_day (_tmp8_, _tmp10_);
	} else {
		_tmp0_ = FALSE;
	}
	grouped = _tmp0_;
	_tmp11_ = dc_message_row_effective_sender_name (msg);
	sender = _tmp11_;
	_tmp12_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	g_object_ref_sink (_tmp12_);
	content = _tmp12_;
	if (grouped) {
		GtkBox* gutter = NULL;
		GtkBox* _tmp13_;
		GtkBox* _tmp14_;
		GtkBox* _tmp15_;
		GtkBox* _tmp16_;
		_tmp13_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
		g_object_ref_sink (_tmp13_);
		gutter = _tmp13_;
		_tmp14_ = gutter;
		g_object_set ((GtkWidget*) _tmp14_, "width-request", 36, NULL);
		_tmp15_ = content;
		_tmp16_ = gutter;
		gtk_box_append (_tmp15_, (GtkWidget*) _tmp16_);
		_g_object_unref0 (gutter);
	} else {
		const gchar* _tmp17_ = NULL;
		gboolean _tmp18_;
		gboolean _tmp19_;
		GtkWidget* avatar = NULL;
		const gchar* _tmp23_;
		GtkWidget* _tmp24_;
		GtkWidget* _tmp25_;
		const gchar* _tmp26_ = NULL;
		const gchar* _tmp27_;
		const gchar* _tmp28_;
		GtkWidget* _tmp30_;
		GtkBox* _tmp31_;
		GtkWidget* _tmp32_;
		_tmp18_ = dc_message_get_is_outgoing (msg);
		_tmp19_ = _tmp18_;
		if (_tmp19_) {
			const gchar* _tmp20_;
			_tmp20_ = dc_message_row_self_avatar_path;
			_tmp17_ = _tmp20_;
		} else {
			const gchar* _tmp21_;
			const gchar* _tmp22_;
			_tmp21_ = dc_message_get_sender_avatar_path (msg);
			_tmp22_ = _tmp21_;
			_tmp17_ = _tmp22_;
		}
		_tmp23_ = sender;
		_tmp24_ = dc_presence_avatar (36, _tmp23_, _tmp17_, FALSE, "message-avatar", NULL);
		avatar = _tmp24_;
		_tmp25_ = avatar;
		gtk_widget_set_valign (_tmp25_, GTK_ALIGN_START);
		_tmp27_ = dc_message_get_sender_address (msg);
		_tmp28_ = _tmp27_;
		_tmp26_ = _tmp28_;
		if (_tmp26_ == NULL) {
			const gchar* _tmp29_;
			_tmp29_ = sender;
			_tmp26_ = _tmp29_;
		}
		_tmp30_ = avatar;
		gtk_widget_set_tooltip_text (_tmp30_, _tmp26_);
		_tmp31_ = content;
		_tmp32_ = avatar;
		gtk_box_append (_tmp31_, _tmp32_);
		_g_object_unref0 (avatar);
	}
	_tmp33_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
	g_object_ref_sink (_tmp33_);
	body = _tmp33_;
	_tmp34_ = body;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp34_, TRUE);
	if (!grouped) {
		GtkBox* header = NULL;
		GtkBox* _tmp35_;
		GtkLabel* sender_lbl = NULL;
		const gchar* _tmp36_;
		GtkLabel* _tmp37_;
		GtkLabel* _tmp38_;
		GtkLabel* _tmp39_;
		GtkLabel* _tmp40_;
		GtkBox* _tmp41_;
		GtkLabel* _tmp42_;
		GtkLabel* time_lbl = NULL;
		gint64 _tmp43_;
		gint64 _tmp44_;
		gchar* _tmp45_;
		gchar* _tmp46_;
		GtkLabel* _tmp47_;
		GtkLabel* _tmp48_;
		GtkLabel* _tmp49_;
		GtkLabel* _tmp50_;
		GtkBox* _tmp51_;
		GtkLabel* _tmp52_;
		GtkBox* _tmp53_;
		GtkBox* _tmp54_;
		_tmp35_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
		g_object_ref_sink (_tmp35_);
		header = _tmp35_;
		_tmp36_ = sender;
		_tmp37_ = (GtkLabel*) gtk_label_new (_tmp36_);
		g_object_ref_sink (_tmp37_);
		sender_lbl = _tmp37_;
		_tmp38_ = sender_lbl;
		gtk_widget_add_css_class ((GtkWidget*) _tmp38_, "message-sender");
		_tmp39_ = sender_lbl;
		gtk_label_set_xalign (_tmp39_, (gfloat) 0);
		_tmp40_ = sender_lbl;
		gtk_label_set_ellipsize (_tmp40_, PANGO_ELLIPSIZE_END);
		_tmp41_ = header;
		_tmp42_ = sender_lbl;
		gtk_box_append (_tmp41_, (GtkWidget*) _tmp42_);
		_tmp43_ = dc_message_get_timestamp (msg);
		_tmp44_ = _tmp43_;
		_tmp45_ = dc_message_row_format_timestamp (_tmp44_);
		_tmp46_ = _tmp45_;
		_tmp47_ = (GtkLabel*) gtk_label_new (_tmp46_);
		g_object_ref_sink (_tmp47_);
		_tmp48_ = _tmp47_;
		_g_free0 (_tmp46_);
		time_lbl = _tmp48_;
		_tmp49_ = time_lbl;
		gtk_widget_add_css_class ((GtkWidget*) _tmp49_, "message-time");
		_tmp50_ = time_lbl;
		gtk_widget_set_valign ((GtkWidget*) _tmp50_, GTK_ALIGN_END);
		_tmp51_ = header;
		_tmp52_ = time_lbl;
		gtk_box_append (_tmp51_, (GtkWidget*) _tmp52_);
		_tmp53_ = body;
		_tmp54_ = header;
		gtk_box_append (_tmp53_, (GtkWidget*) _tmp54_);
		_g_object_unref0 (time_lbl);
		_g_object_unref0 (sender_lbl);
		_g_object_unref0 (header);
	}
	_tmp55_ = body;
	dc_message_row_append_content (self, _tmp55_, msg, 60, 1, FALSE, NULL, -1);
	_tmp56_ = dc_message_row_build_reactions_box (self, msg);
	reactions_box = _tmp56_;
	_tmp57_ = reactions_box;
	if (_tmp57_ != NULL) {
		GtkBox* _tmp58_;
		GtkBox* _tmp59_;
		_tmp58_ = body;
		_tmp59_ = reactions_box;
		gtk_box_append (_tmp58_, (GtkWidget*) _tmp59_);
	}
	_tmp60_ = content;
	_tmp61_ = body;
	gtk_box_append (_tmp60_, (GtkWidget*) _tmp61_);
	_tmp62_ = content;
	dc_message_row_append_meta_indicators (self, _tmp62_, msg, GTK_ALIGN_END);
	_tmp63_ = dc_message_row_build_hover_actions (self);
	bar = _tmp63_;
	gtk_widget_set_visible (bar, FALSE);
	_tmp64_ = (GtkEventControllerMotion*) gtk_event_controller_motion_new ();
	motion = _tmp64_;
	dc_message_row_connect_hover_visibility (motion, bar);
	_tmp65_ = _g_object_ref0 ((GtkEventController*) motion);
	gtk_widget_add_controller ((GtkWidget*) self, _tmp65_);
	_tmp66_ = (GtkOverlay*) gtk_overlay_new ();
	g_object_ref_sink (_tmp66_);
	overlay = _tmp66_;
	gtk_widget_set_hexpand ((GtkWidget*) overlay, TRUE);
	_tmp67_ = content;
	gtk_overlay_set_child (overlay, (GtkWidget*) _tmp67_);
	gtk_overlay_add_overlay (overlay, bar);
	gtk_box_append ((GtkBox*) self, (GtkWidget*) overlay);
	_g_object_unref0 (overlay);
	_g_object_unref0 (motion);
	_g_object_unref0 (bar);
	_g_object_unref0 (reactions_box);
	_g_object_unref0 (body);
	_g_object_unref0 (content);
	_g_free0 (sender);
}

static void
dc_message_row_connect_hover_visibility (GtkEventControllerMotion* motion,
                                         GtkWidget* bar)
{
	g_return_if_fail (motion != NULL);
	g_return_if_fail (bar != NULL);
	g_signal_connect_object (motion, "enter", (GCallback) dc_message_row_on_hover_enter, (GObject*) bar, (GConnectFlags) 0);
	g_signal_connect_object (motion, "leave", (GCallback) dc_message_row_on_hover_leave, (GObject*) bar, (GConnectFlags) 0);
}

static void
dc_message_row_on_hover_enter (GtkEventControllerMotion* motion,
                               gdouble x,
                               gdouble y,
                               GtkWidget* bar)
{
	g_return_if_fail (motion != NULL);
	g_return_if_fail (bar != NULL);
	gtk_widget_set_visible (bar, TRUE);
}

static void
dc_message_row_on_hover_leave (GtkEventControllerMotion* motion,
                               GtkWidget* bar)
{
	g_return_if_fail (motion != NULL);
	g_return_if_fail (bar != NULL);
	gtk_widget_set_visible (bar, FALSE);
}

/** Quick-action buttons shown while the pointer is over a Workspace
            row. */
static GtkWidget*
dc_message_row_build_hover_actions (DcMessageRow* self)
{
	GtkBox* bar = NULL;
	GtkBox* _tmp0_;
	GtkBox* _tmp1_;
	GtkBox* _tmp2_;
	GtkBox* _tmp3_;
	gchar** actions = NULL;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	gchar* _tmp14_;
	gchar* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	gchar** _tmp19_;
	gint actions_length1;
	gint actions_length2;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	g_object_ref_sink (_tmp0_);
	bar = _tmp0_;
	_tmp1_ = bar;
	gtk_widget_add_css_class ((GtkWidget*) _tmp1_, "message-actions-bar");
	_tmp2_ = bar;
	gtk_widget_set_halign ((GtkWidget*) _tmp2_, GTK_ALIGN_END);
	_tmp3_ = bar;
	gtk_widget_set_valign ((GtkWidget*) _tmp3_, GTK_ALIGN_START);
	_tmp4_ = g_strdup ("react");
	_tmp5_ = g_strdup ("face-smile-symbolic");
	_tmp6_ = g_strdup ("React");
	_tmp7_ = g_strdup ("reply");
	_tmp8_ = g_strdup ("mail-reply-sender-symbolic");
	_tmp9_ = g_strdup ("Reply");
	_tmp10_ = g_strdup ("forward");
	_tmp11_ = g_strdup ("mail-forward-symbolic");
	_tmp12_ = g_strdup ("Forward");
	_tmp13_ = g_strdup ("pin");
	_tmp14_ = g_strdup ("view-pin-symbolic");
	_tmp15_ = g_strdup ("Pin / Unpin");
	_tmp16_ = g_strdup ("more");
	_tmp17_ = g_strdup ("view-more-symbolic");
	_tmp18_ = g_strdup ("More actions");
	_tmp19_ = g_new0 (gchar*, (5 * 3) + 1);
	_tmp19_[0] = _tmp4_;
	_tmp19_[1] = _tmp5_;
	_tmp19_[2] = _tmp6_;
	_tmp19_[3] = _tmp7_;
	_tmp19_[4] = _tmp8_;
	_tmp19_[5] = _tmp9_;
	_tmp19_[6] = _tmp10_;
	_tmp19_[7] = _tmp11_;
	_tmp19_[8] = _tmp12_;
	_tmp19_[9] = _tmp13_;
	_tmp19_[10] = _tmp14_;
	_tmp19_[11] = _tmp15_;
	_tmp19_[12] = _tmp16_;
	_tmp19_[13] = _tmp17_;
	_tmp19_[14] = _tmp18_;
	actions = _tmp19_;
	actions_length1 = 5;
	actions_length2 = 3;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp20_ = FALSE;
			_tmp20_ = TRUE;
			while (TRUE) {
				gchar** _tmp22_;
				gint _tmp22__length1;
				gint _tmp22__length2;
				gint _tmp23_;
				gchar* action = NULL;
				gchar** _tmp24_;
				gint _tmp24__length1;
				gint _tmp24__length2;
				const gchar* _tmp25_;
				gchar* _tmp26_;
				GtkButton* btn = NULL;
				gchar** _tmp27_;
				gint _tmp27__length1;
				gint _tmp27__length2;
				const gchar* _tmp28_;
				GtkButton* _tmp29_;
				GtkButton* _tmp30_;
				GtkButton* _tmp31_;
				gchar** _tmp32_;
				gint _tmp32__length1;
				gint _tmp32__length2;
				const gchar* _tmp33_;
				GtkButton* _tmp34_;
				const gchar* _tmp35_;
				GtkBox* _tmp36_;
				GtkButton* _tmp37_;
				if (!_tmp20_) {
					gint _tmp21_;
					_tmp21_ = i;
					i = _tmp21_ + 1;
				}
				_tmp20_ = FALSE;
				_tmp22_ = actions;
				_tmp22__length1 = actions_length1;
				_tmp22__length2 = actions_length2;
				_tmp23_ = _tmp22__length1;
				if (!(i < _tmp23_)) {
					break;
				}
				_tmp24_ = actions;
				_tmp24__length1 = actions_length1;
				_tmp24__length2 = actions_length2;
				_tmp25_ = _tmp24_[(i * _tmp24__length2) + 0];
				_tmp26_ = g_strdup (_tmp25_);
				action = _tmp26_;
				_tmp27_ = actions;
				_tmp27__length1 = actions_length1;
				_tmp27__length2 = actions_length2;
				_tmp28_ = _tmp27_[(i * _tmp27__length2) + 1];
				_tmp29_ = (GtkButton*) gtk_button_new_from_icon_name (_tmp28_);
				g_object_ref_sink (_tmp29_);
				btn = _tmp29_;
				_tmp30_ = btn;
				gtk_widget_add_css_class ((GtkWidget*) _tmp30_, "flat");
				_tmp31_ = btn;
				_tmp32_ = actions;
				_tmp32__length1 = actions_length1;
				_tmp32__length2 = actions_length2;
				_tmp33_ = _tmp32_[(i * _tmp32__length2) + 2];
				gtk_widget_set_tooltip_text ((GtkWidget*) _tmp31_, _tmp33_);
				_tmp34_ = btn;
				_tmp35_ = action;
				dc_message_row_connect_action_button (self, _tmp34_, _tmp35_);
				_tmp36_ = bar;
				_tmp37_ = btn;
				gtk_box_append (_tmp36_, (GtkWidget*) _tmp37_);
				_g_object_unref0 (btn);
				_g_free0 (action);
			}
		}
	}
	result = (GtkWidget*) bar;
	actions = (_vala_array_free (actions, actions_length1 * actions_length2, (GDestroyNotify) g_free), NULL);
	return result;
}

static void
dc_message_row_connect_action_button (DcMessageRow* self,
                                      GtkButton* button,
                                      const gchar* action)
{
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (button != NULL);
	g_return_if_fail (action != NULL);
	_tmp0_ = g_strdup (action);
	g_object_set_data_full ((GObject*) button, DC_MESSAGE_ROW_ACTION_DATA, _tmp0_, g_free);
	g_signal_connect_object (button, "clicked", (GCallback) dc_message_row_on_action_button_clicked, (GObject*) self, (GConnectFlags) 0);
}

static void
dc_message_row_on_action_button_clicked (GtkButton* button,
                                         DcMessageRow* row)
{
	gchar* action = NULL;
	gconstpointer _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	g_return_if_fail (button != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = g_object_get_data ((GObject*) button, DC_MESSAGE_ROW_ACTION_DATA);
	_tmp1_ = g_strdup ((const gchar*) _tmp0_);
	action = _tmp1_;
	_tmp2_ = action;
	if (_tmp2_ != NULL) {
		const gchar* _tmp3_;
		_tmp3_ = action;
		g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_ACTION_REQUESTED_SIGNAL], 0, _tmp3_, (GtkWidget*) button);
	}
	_g_free0 (action);
}

static void
dc_message_row_append_selection_checkbox (DcMessageRow* self,
                                          DcMessage* msg)
{
	GtkCheckButton* check = NULL;
	GtkCheckButton* _tmp0_;
	DcMessage* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_tmp0_ = (GtkCheckButton*) gtk_check_button_new ();
	g_object_ref_sink (_tmp0_);
	check = _tmp0_;
	gtk_widget_add_css_class ((GtkWidget*) check, "message-select-check");
	gtk_widget_set_valign ((GtkWidget*) check, GTK_ALIGN_CENTER);
	gtk_widget_set_margin_end ((GtkWidget*) check, 6);
	g_object_bind_property_with_closures ((GObject*) msg, "selection-visible", (GObject*) check, "visible", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
	g_object_bind_property_with_closures ((GObject*) msg, "selected", (GObject*) check, "active", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
	_tmp1_ = _g_object_ref0 (msg);
	g_object_set_data_full ((GObject*) check, DC_MESSAGE_ROW_MESSAGE_DATA, _tmp1_, g_object_unref);
	g_signal_connect_object (check, "toggled", (GCallback) dc_message_row_on_selection_toggled, (GObject*) self, (GConnectFlags) 0);
	gtk_box_append ((GtkBox*) self, (GtkWidget*) check);
	_g_object_unref0 (check);
}

static void
dc_message_row_on_selection_toggled (GtkCheckButton* check,
                                     DcMessageRow* row)
{
	DcMessage* msg = NULL;
	gconstpointer _tmp0_;
	DcMessage* _tmp1_;
	DcMessage* _tmp2_;
	DcMessage* _tmp3_;
	gboolean _tmp4_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	gboolean _tmp7_;
	DcMessage* _tmp11_;
	gint _tmp12_;
	gint _tmp13_;
	gboolean _tmp14_;
	gboolean _tmp15_;
	g_return_if_fail (check != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = g_object_get_data ((GObject*) check, DC_MESSAGE_ROW_MESSAGE_DATA);
	_tmp1_ = _g_object_ref0 ((DcMessage*) _tmp0_);
	msg = _tmp1_;
	_tmp2_ = msg;
	if (_tmp2_ == NULL) {
		_g_object_unref0 (msg);
		return;
	}
	_tmp3_ = msg;
	_tmp4_ = dc_message_get_selected (_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = gtk_check_button_get_active (check);
	_tmp7_ = _tmp6_;
	if (_tmp5_ != _tmp7_) {
		DcMessage* _tmp8_;
		gboolean _tmp9_;
		gboolean _tmp10_;
		_tmp8_ = msg;
		_tmp9_ = gtk_check_button_get_active (check);
		_tmp10_ = _tmp9_;
		dc_message_set_selected (_tmp8_, _tmp10_);
	}
	_tmp11_ = msg;
	_tmp12_ = dc_message_get_id (_tmp11_);
	_tmp13_ = _tmp12_;
	_tmp14_ = gtk_check_button_get_active (check);
	_tmp15_ = _tmp14_;
	g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_SELECTION_TOGGLED_SIGNAL], 0, _tmp13_, _tmp15_);
	_g_object_unref0 (msg);
}

static void
dc_message_row_append_attachment (DcMessageRow* self,
                                  GtkBox* box,
                                  DcMessage* msg,
                                  gboolean irc,
                                  GPtrArray* trailing_images)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_;
	gboolean _tmp4_;
	GtkBox* fi = NULL;
	GtkBox* _tmp14_;
	GtkBox* _tmp16_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (box != NULL);
	g_return_if_fail (msg != NULL);
	_tmp0_ = dc_message_get_has_file (msg);
	_tmp1_ = _tmp0_;
	if (!_tmp1_) {
		return;
	}
	_tmp3_ = dc_message_get_has_local_file (msg);
	_tmp4_ = _tmp3_;
	if (_tmp4_) {
		gboolean _tmp5_ = FALSE;
		if (dc_message_is_sticker_file (msg)) {
			_tmp5_ = TRUE;
		} else {
			_tmp5_ = dc_message_is_image_file (msg);
		}
		_tmp2_ = _tmp5_;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		if (irc) {
			dc_message_row_append_irc_images (box, msg, trailing_images);
		} else {
			dc_message_row_append_bubble_image (box, msg);
		}
		return;
	}
	if (dc_message_is_video_file (msg)) {
		GtkWidget* _tmp6_;
		GtkWidget* _tmp7_;
		_tmp6_ = dc_message_row_build_video_preview (msg);
		_tmp7_ = _tmp6_;
		gtk_box_append (box, _tmp7_);
		_g_object_unref0 (_tmp7_);
		return;
	}
	if (dc_message_is_audio_file (msg)) {
		GtkWidget* widget = NULL;
		GtkWidget* _tmp8_;
		GtkWidget* _tmp9_;
		GtkWidget* _tmp10_;
		_tmp8_ = dc_message_row_build_audio_player (self, msg);
		widget = _tmp8_;
		_tmp9_ = widget;
		dc_message_row_set_audio_player (self, DC_IS_AUDIO_PLAYER (_tmp9_) ? ((DcAudioPlayer*) _tmp9_) : NULL);
		_tmp10_ = widget;
		gtk_box_append (box, _tmp10_);
		_g_object_unref0 (widget);
		return;
	}
	if (dc_message_is_webxdc (msg)) {
		GtkWidget* card = NULL;
		GtkWidget* _tmp11_;
		GtkWidget* _tmp12_;
		GtkWidget* _tmp13_;
		_tmp11_ = dc_message_row_build_webxdc_card (self, msg);
		card = _tmp11_;
		_tmp12_ = card;
		gtk_widget_set_halign (_tmp12_, GTK_ALIGN_START);
		_tmp13_ = card;
		gtk_box_append (box, _tmp13_);
		_g_object_unref0 (card);
		return;
	}
	_tmp14_ = dc_message_row_build_file_indicator (msg);
	fi = _tmp14_;
	if (irc) {
		GtkBox* _tmp15_;
		_tmp15_ = fi;
		gtk_widget_set_halign ((GtkWidget*) _tmp15_, GTK_ALIGN_START);
	}
	_tmp16_ = fi;
	gtk_box_append (box, (GtkWidget*) _tmp16_);
	_g_object_unref0 (fi);
}

/** Webxdc apps show as one accent-colored control. Both the icon
            and name open the same capability-aware options dialog. */
static glong
string_strnlen (gchar* str,
                glong maxlen)
{
	gchar* end = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	glong result;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	_tmp1_ = end;
	if (_tmp1_ == NULL) {
		result = maxlen;
		return result;
	} else {
		gchar* _tmp2_;
		_tmp2_ = end;
		result = (glong) (_tmp2_ - str);
		return result;
	}
}

static gchar*
string_substring (const gchar* self,
                  glong offset,
                  glong len)
{
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= ((glong) 0)) {
		_tmp0_ = len >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		string_length = string_strnlen ((gchar*) self, offset + len);
	} else {
		gint _tmp1_;
		gint _tmp2_;
		_tmp1_ = strlen (self);
		_tmp2_ = _tmp1_;
		string_length = (glong) _tmp2_;
	}
	if (offset < ((glong) 0)) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= ((glong) 0), NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < ((glong) 0)) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}

static GtkWidget*
dc_message_row_build_webxdc_card (DcMessageRow* self,
                                  DcMessage* msg)
{
	gboolean ready = FALSE;
	gboolean _tmp0_;
	gboolean _tmp1_;
	GtkButton* btn = NULL;
	GtkButton* _tmp2_;
	GtkButton* _tmp3_;
	GtkButton* _tmp4_;
	GtkButton* _tmp5_;
	GtkBox* inner = NULL;
	GtkBox* _tmp6_;
	GtkImage* icon = NULL;
	GtkImage* _tmp7_;
	GtkImage* _tmp8_;
	GtkImage* _tmp9_;
	GtkBox* _tmp10_;
	GtkImage* _tmp11_;
	GtkBox* text = NULL;
	GtkBox* _tmp12_;
	GtkBox* _tmp13_;
	gchar* fallback = NULL;
	gchar* _tmp14_;
	const gchar* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gboolean _tmp18_;
	GtkLabel* name = NULL;
	const gchar* _tmp24_;
	GtkLabel* _tmp25_;
	GtkLabel* _tmp26_;
	GtkLabel* _tmp27_;
	GtkLabel* _tmp28_;
	GtkLabel* _tmp29_;
	GtkLabel* _tmp30_;
	GtkBox* _tmp31_;
	GtkLabel* _tmp32_;
	const gchar* _tmp33_ = NULL;
	gchar* status = NULL;
	gchar* _tmp35_;
	GtkLabel* subtitle = NULL;
	const gchar* _tmp36_;
	GtkLabel* _tmp37_;
	GtkLabel* _tmp38_;
	GtkLabel* _tmp39_;
	GtkLabel* _tmp40_;
	GtkLabel* _tmp41_;
	GtkLabel* _tmp42_;
	GtkBox* _tmp43_;
	GtkLabel* _tmp44_;
	GtkBox* _tmp45_;
	GtkBox* _tmp46_;
	GtkButton* _tmp47_;
	GtkBox* _tmp48_;
	gboolean _tmp49_ = FALSE;
	GtkButton* _tmp54_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = dc_message_get_has_local_file (msg);
	_tmp1_ = _tmp0_;
	ready = _tmp1_;
	_tmp2_ = (GtkButton*) gtk_button_new ();
	g_object_ref_sink (_tmp2_);
	btn = _tmp2_;
	_tmp3_ = btn;
	gtk_widget_add_css_class ((GtkWidget*) _tmp3_, "webxdc-card");
	_tmp4_ = btn;
	gtk_widget_set_focus_on_click ((GtkWidget*) _tmp4_, FALSE);
	_tmp5_ = btn;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp5_, "Webxdc app options");
	_tmp6_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
	g_object_ref_sink (_tmp6_);
	inner = _tmp6_;
	_tmp7_ = (GtkImage*) gtk_image_new_from_icon_name ("application-x-executable-symbolic");
	g_object_ref_sink (_tmp7_);
	icon = _tmp7_;
	_tmp8_ = icon;
	gtk_image_set_pixel_size (_tmp8_, 48);
	_tmp9_ = icon;
	gtk_widget_add_css_class ((GtkWidget*) _tmp9_, "webxdc-card-icon");
	_tmp10_ = inner;
	_tmp11_ = icon;
	gtk_box_append (_tmp10_, (GtkWidget*) _tmp11_);
	_tmp12_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
	g_object_ref_sink (_tmp12_);
	text = _tmp12_;
	_tmp13_ = text;
	gtk_widget_set_valign ((GtkWidget*) _tmp13_, GTK_ALIGN_CENTER);
	_tmp14_ = dc_message_display_file_name (msg, "app");
	fallback = _tmp14_;
	_tmp15_ = fallback;
	_tmp16_ = g_utf8_strdown (_tmp15_, (gssize) -1);
	_tmp17_ = _tmp16_;
	_tmp18_ = g_str_has_suffix (_tmp17_, ".xdc");
	_g_free0 (_tmp17_);
	if (_tmp18_) {
		const gchar* _tmp19_;
		const gchar* _tmp20_;
		gint _tmp21_;
		gint _tmp22_;
		gchar* _tmp23_;
		_tmp19_ = fallback;
		_tmp20_ = fallback;
		_tmp21_ = strlen (_tmp20_);
		_tmp22_ = _tmp21_;
		_tmp23_ = string_substring (_tmp19_, (glong) 0, (glong) (_tmp22_ - 4));
		_g_free0 (fallback);
		fallback = _tmp23_;
	}
	_tmp24_ = fallback;
	_tmp25_ = (GtkLabel*) gtk_label_new (_tmp24_);
	g_object_ref_sink (_tmp25_);
	name = _tmp25_;
	_tmp26_ = name;
	gtk_widget_add_css_class ((GtkWidget*) _tmp26_, "webxdc-card-title");
	_tmp27_ = name;
	gtk_widget_set_halign ((GtkWidget*) _tmp27_, GTK_ALIGN_START);
	_tmp28_ = name;
	gtk_label_set_xalign (_tmp28_, (gfloat) 0);
	_tmp29_ = name;
	gtk_label_set_ellipsize (_tmp29_, PANGO_ELLIPSIZE_END);
	_tmp30_ = name;
	gtk_label_set_max_width_chars (_tmp30_, 24);
	_tmp31_ = text;
	_tmp32_ = name;
	gtk_box_append (_tmp31_, (GtkWidget*) _tmp32_);
	if (!DC_WEBXDC_AVAILABLE) {
		_tmp33_ = "Webxdc app · download only";
	} else {
		const gchar* _tmp34_ = NULL;
		if (!dc_webxdc_enabled ()) {
			_tmp34_ = "Webxdc app · disabled in Settings";
		} else {
			_tmp34_ = "Webxdc app · choose an action";
		}
		_tmp33_ = _tmp34_;
	}
	_tmp35_ = g_strdup (_tmp33_);
	status = _tmp35_;
	_tmp36_ = status;
	_tmp37_ = (GtkLabel*) gtk_label_new (_tmp36_);
	g_object_ref_sink (_tmp37_);
	subtitle = _tmp37_;
	_tmp38_ = subtitle;
	gtk_widget_add_css_class ((GtkWidget*) _tmp38_, "webxdc-card-subtitle");
	_tmp39_ = subtitle;
	gtk_widget_set_halign ((GtkWidget*) _tmp39_, GTK_ALIGN_START);
	_tmp40_ = subtitle;
	gtk_label_set_xalign (_tmp40_, (gfloat) 0);
	_tmp41_ = subtitle;
	gtk_label_set_ellipsize (_tmp41_, PANGO_ELLIPSIZE_END);
	_tmp42_ = subtitle;
	gtk_label_set_max_width_chars (_tmp42_, 30);
	_tmp43_ = text;
	_tmp44_ = subtitle;
	gtk_box_append (_tmp43_, (GtkWidget*) _tmp44_);
	_tmp45_ = inner;
	_tmp46_ = text;
	gtk_box_append (_tmp45_, (GtkWidget*) _tmp46_);
	_tmp47_ = btn;
	_tmp48_ = inner;
	gtk_button_set_child (_tmp47_, (GtkWidget*) _tmp48_);
	if (ready) {
		_tmp49_ = DC_WEBXDC_AVAILABLE;
	} else {
		_tmp49_ = FALSE;
	}
	if (_tmp49_) {
		gint _tmp50_;
		gint _tmp51_;
		GtkLabel* _tmp52_;
		GtkImage* _tmp53_;
		_tmp50_ = dc_message_get_id (msg);
		_tmp51_ = _tmp50_;
		_tmp52_ = name;
		_tmp53_ = icon;
		dc_message_row_load_webxdc_card_info (_tmp51_, _tmp52_, _tmp53_);
	}
	_tmp54_ = btn;
	dc_message_row_connect_action_button (self, _tmp54_, "webxdc");
	result = (GtkWidget*) btn;
	_g_object_unref0 (subtitle);
	_g_free0 (status);
	_g_object_unref0 (name);
	_g_free0 (fallback);
	_g_object_unref0 (text);
	_g_object_unref0 (icon);
	_g_object_unref0 (inner);
	return result;
}

static Block23Data*
block23_data_ref (Block23Data* _data23_)
{
	g_atomic_int_inc (&_data23_->_ref_count_);
	return _data23_;
}

static void
block23_data_unref (void * _userdata_)
{
	Block23Data* _data23_;
	_data23_ = (Block23Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data23_->_ref_count_)) {
		g_weak_ref_clear (&_data23_->icon_ref);
		g_weak_ref_clear (&_data23_->name_ref);
		g_slice_free (Block23Data, _data23_);
	}
}

static void
__lambda17_ (Block23Data* _data23_,
             GObject* obj,
             GAsyncResult* res)
{
	DcWebxdcCardInfo* info = NULL;
	DcWebxdcCardInfo* _tmp0_;
	GtkLabel* live_name = NULL;
	GObject* _tmp1_;
	GtkLabel* _tmp2_;
	GtkImage* live_icon = NULL;
	GObject* _tmp3_;
	GtkImage* _tmp4_;
	gboolean _tmp5_ = FALSE;
	GtkLabel* _tmp6_;
	gboolean _tmp12_ = FALSE;
	GtkImage* _tmp13_;
	g_return_if_fail (res != NULL);
	_tmp0_ = dc_webxdc_card_info_finish (res);
	info = _tmp0_;
	_tmp1_ = g_weak_ref_get (&_data23_->name_ref);
	_tmp2_ = G_TYPE_CHECK_INSTANCE_TYPE (_tmp1_, gtk_label_get_type ()) ? ((GtkLabel*) _tmp1_) : NULL;
	if (_tmp2_ == NULL) {
		_g_object_unref0 (_tmp1_);
	}
	live_name = _tmp2_;
	_tmp3_ = g_weak_ref_get (&_data23_->icon_ref);
	_tmp4_ = G_TYPE_CHECK_INSTANCE_TYPE (_tmp3_, gtk_image_get_type ()) ? ((GtkImage*) _tmp3_) : NULL;
	if (_tmp4_ == NULL) {
		_g_object_unref0 (_tmp3_);
	}
	live_icon = _tmp4_;
	_tmp6_ = live_name;
	if (_tmp6_ != NULL) {
		DcWebxdcCardInfo* _tmp7_;
		const gchar* _tmp8_;
		_tmp7_ = info;
		_tmp8_ = _tmp7_->name;
		_tmp5_ = _tmp8_ != NULL;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		GtkLabel* _tmp9_;
		DcWebxdcCardInfo* _tmp10_;
		const gchar* _tmp11_;
		_tmp9_ = live_name;
		_tmp10_ = info;
		_tmp11_ = _tmp10_->name;
		gtk_label_set_label (_tmp9_, _tmp11_);
	}
	_tmp13_ = live_icon;
	if (_tmp13_ != NULL) {
		DcWebxdcCardInfo* _tmp14_;
		GdkTexture* _tmp15_;
		_tmp14_ = info;
		_tmp15_ = _tmp14_->icon;
		_tmp12_ = _tmp15_ != NULL;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		GtkImage* _tmp16_;
		DcWebxdcCardInfo* _tmp17_;
		GdkTexture* _tmp18_;
		_tmp16_ = live_icon;
		_tmp17_ = info;
		_tmp18_ = _tmp17_->icon;
		g_object_set (_tmp16_, "paintable", (GdkPaintable*) _tmp18_, NULL);
	}
	_g_object_unref0 (live_icon);
	_g_object_unref0 (live_name);
	_dc_webxdc_card_info_unref0 (info);
}

static void
___lambda17__gasync_ready_callback (GObject* source_object,
                                    GAsyncResult* res,
                                    gpointer self)
{
	__lambda17_ (self, source_object, res);
	block23_data_unref (self);
}

static void
dc_message_row_load_webxdc_card_info (gint msg_id,
                                      GtkLabel* name,
                                      GtkImage* icon)
{
	Block23Data* _data23_;
	g_return_if_fail (name != NULL);
	g_return_if_fail (icon != NULL);
	_data23_ = g_slice_new0 (Block23Data);
	_data23_->_ref_count_ = 1;
	g_weak_ref_init (&_data23_->name_ref, (GObject*) name);
	g_weak_ref_init (&_data23_->icon_ref, (GObject*) icon);
	dc_webxdc_card_info (msg_id, ___lambda17__gasync_ready_callback, block23_data_ref (_data23_));
	block23_data_unref (_data23_);
	_data23_ = NULL;
}

static gboolean
dc_message_row_should_show_bubble_avatar (DcMessage* msg,
                                          DcBubbleAvatarDisplay display,
                                          gboolean scope_enabled)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (msg != NULL, FALSE);
	if (!scope_enabled) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp1_;
		gboolean _tmp2_;
		_tmp1_ = dc_message_get_is_info (msg);
		_tmp2_ = _tmp1_;
		_tmp0_ = _tmp2_;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	switch (display) {
		case DC_BUBBLE_AVATAR_DISPLAY_NONE:
		{
			result = FALSE;
			return result;
		}
		case DC_BUBBLE_AVATAR_DISPLAY_OTHER:
		{
			gboolean _tmp3_;
			gboolean _tmp4_;
			_tmp3_ = dc_message_get_is_outgoing (msg);
			_tmp4_ = _tmp3_;
			result = !_tmp4_;
			return result;
		}
		case DC_BUBBLE_AVATAR_DISPLAY_BOTH:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

static GtkWidget*
dc_message_row_build_bubble_avatar (DcMessage* msg)
{
	const gchar* _tmp0_ = NULL;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gchar* text = NULL;
	gchar* _tmp16_;
	const gchar* _tmp17_ = NULL;
	gboolean _tmp18_;
	gboolean _tmp19_;
	GtkWidget* avatar = NULL;
	const gchar* _tmp23_;
	GtkWidget* _tmp24_;
	GtkWidget* _tmp25_;
	GtkWidget* _tmp26_;
	const gchar* _tmp27_;
	gboolean _tmp28_;
	gboolean _tmp29_;
	GtkWidget* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_is_outgoing (msg);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		const gchar* _tmp3_ = NULL;
		gboolean _tmp4_ = FALSE;
		const gchar* _tmp5_;
		_tmp5_ = dc_message_row_self_display_name;
		if (_tmp5_ != NULL) {
			const gchar* _tmp6_;
			gint _tmp7_;
			gint _tmp8_;
			_tmp6_ = dc_message_row_self_display_name;
			_tmp7_ = strlen (_tmp6_);
			_tmp8_ = _tmp7_;
			_tmp4_ = _tmp8_ > 0;
		} else {
			_tmp4_ = FALSE;
		}
		if (_tmp4_) {
			const gchar* _tmp9_;
			_tmp9_ = dc_message_row_self_display_name;
			_tmp3_ = _tmp9_;
		} else {
			_tmp3_ = "me";
		}
		_tmp0_ = _tmp3_;
	} else {
		const gchar* _tmp10_ = NULL;
		const gchar* _tmp11_;
		const gchar* _tmp12_;
		_tmp11_ = dc_message_get_sender_name (msg);
		_tmp12_ = _tmp11_;
		_tmp10_ = _tmp12_;
		if (_tmp10_ == NULL) {
			const gchar* _tmp13_ = NULL;
			const gchar* _tmp14_;
			const gchar* _tmp15_;
			_tmp14_ = dc_message_get_sender_address (msg);
			_tmp15_ = _tmp14_;
			_tmp13_ = _tmp15_;
			if (_tmp13_ == NULL) {
				_tmp13_ = "?";
			}
			_tmp10_ = _tmp13_;
		}
		_tmp0_ = _tmp10_;
	}
	_tmp16_ = g_strdup (_tmp0_);
	text = _tmp16_;
	_tmp18_ = dc_message_get_is_outgoing (msg);
	_tmp19_ = _tmp18_;
	if (_tmp19_) {
		const gchar* _tmp20_;
		_tmp20_ = dc_message_row_self_avatar_path;
		_tmp17_ = _tmp20_;
	} else {
		const gchar* _tmp21_;
		const gchar* _tmp22_;
		_tmp21_ = dc_message_get_sender_avatar_path (msg);
		_tmp22_ = _tmp21_;
		_tmp17_ = _tmp22_;
	}
	_tmp23_ = text;
	_tmp24_ = dc_presence_avatar (20, _tmp23_, _tmp17_, FALSE, "message-avatar", NULL);
	avatar = _tmp24_;
	_tmp25_ = avatar;
	gtk_widget_set_valign (_tmp25_, GTK_ALIGN_END);
	_tmp26_ = avatar;
	_tmp27_ = text;
	gtk_widget_set_tooltip_text (_tmp26_, _tmp27_);
	_tmp28_ = dc_message_get_is_outgoing (msg);
	_tmp29_ = _tmp28_;
	if (_tmp29_) {
		GtkWidget* _tmp30_;
		_tmp30_ = avatar;
		gtk_widget_set_margin_start (_tmp30_, 4);
	} else {
		GtkWidget* _tmp31_;
		_tmp31_ = avatar;
		gtk_widget_set_margin_end (_tmp31_, 4);
	}
	result = avatar;
	_g_free0 (text);
	return result;
}

static void
dc_message_row_append_bubble_image (GtkBox* bubble,
                                    DcMessage* msg)
{
	GtkWidget* _tmp0_ = NULL;
	GtkWidget* image = NULL;
	GtkWidget* _tmp7_;
	GtkWidget* _tmp8_;
	g_return_if_fail (bubble != NULL);
	g_return_if_fail (msg != NULL);
	if (dc_message_is_sticker_file (msg)) {
		const gchar* _tmp1_;
		const gchar* _tmp2_;
		GtkWidget* _tmp3_;
		_tmp1_ = dc_message_get_file_path (msg);
		_tmp2_ = _tmp1_;
		_tmp3_ = dc_message_row_load_sticker (_tmp2_, dc_message_is_video_sticker_file (msg));
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		GtkWidget* _tmp6_;
		_tmp4_ = dc_message_get_file_path (msg);
		_tmp5_ = _tmp4_;
		_tmp6_ = dc_message_row_load_picture (_tmp5_, 400, 400, 260, 0, "message-image");
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp6_;
	}
	_tmp7_ = _tmp0_;
	_tmp0_ = NULL;
	image = _tmp7_;
	_tmp8_ = image;
	if (_tmp8_ == NULL) {
		GtkBox* _tmp9_;
		GtkBox* _tmp10_;
		_tmp9_ = dc_message_row_build_file_indicator (msg);
		_tmp10_ = _tmp9_;
		gtk_box_append (bubble, (GtkWidget*) _tmp10_);
		_g_object_unref0 (_tmp10_);
	} else {
		GtkWidget* _tmp11_;
		_tmp11_ = image;
		gtk_box_append (bubble, _tmp11_);
	}
	_g_object_unref0 (image);
	_g_object_unref0 (_tmp0_);
}

static gint
vala_g_ptr_array_get_length (GPtrArray* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = (gint) self->len;
	return result;
}

static void
dc_message_row_append_irc_images (GtkBox* body,
                                  DcMessage* msg,
                                  GPtrArray* trailing_images)
{
	gint _tmp0_ = 0;
	gboolean _tmp1_ = FALSE;
	GtkBox* strip = NULL;
	GtkBox* _tmp4_;
	GtkBox* _tmp5_;
	GtkBox* _tmp6_;
	GtkBox* _tmp13_;
	g_return_if_fail (body != NULL);
	g_return_if_fail (msg != NULL);
	if (trailing_images != NULL) {
		gint _tmp2_;
		gint _tmp3_;
		_tmp2_ = vala_g_ptr_array_get_length (trailing_images);
		_tmp3_ = _tmp2_;
		_tmp1_ = _tmp3_ > 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = 4;
	} else {
		_tmp0_ = 0;
	}
	_tmp4_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, _tmp0_);
	g_object_ref_sink (_tmp4_);
	strip = _tmp4_;
	_tmp5_ = strip;
	gtk_widget_set_halign ((GtkWidget*) _tmp5_, GTK_ALIGN_START);
	_tmp6_ = strip;
	dc_message_row_append_irc_image (_tmp6_, msg);
	if (trailing_images != NULL) {
		{
			guint i = 0U;
			i = (guint) 0;
			{
				gboolean _tmp7_ = FALSE;
				_tmp7_ = TRUE;
				while (TRUE) {
					gint _tmp9_;
					gint _tmp10_;
					GtkBox* _tmp11_;
					gconstpointer _tmp12_;
					if (!_tmp7_) {
						guint _tmp8_;
						_tmp8_ = i;
						i = _tmp8_ + 1;
					}
					_tmp7_ = FALSE;
					_tmp9_ = vala_g_ptr_array_get_length (trailing_images);
					_tmp10_ = _tmp9_;
					if (!(i < ((guint) _tmp10_))) {
						break;
					}
					_tmp11_ = strip;
					_tmp12_ = g_ptr_array_index (trailing_images, i);
					dc_message_row_append_irc_image (_tmp11_, (DcMessage*) _tmp12_);
				}
			}
		}
	}
	_tmp13_ = strip;
	gtk_box_append (body, (GtkWidget*) _tmp13_);
	_g_object_unref0 (strip);
}

static void
dc_message_row_append_irc_image (GtkBox* strip,
                                 DcMessage* m)
{
	GtkWidget* _tmp0_ = NULL;
	GtkWidget* picture = NULL;
	GtkWidget* _tmp7_;
	GtkWidget* _tmp8_;
	g_return_if_fail (strip != NULL);
	g_return_if_fail (m != NULL);
	if (dc_message_is_sticker_file (m)) {
		const gchar* _tmp1_;
		const gchar* _tmp2_;
		GtkWidget* _tmp3_;
		_tmp1_ = dc_message_get_file_path (m);
		_tmp2_ = _tmp1_;
		_tmp3_ = dc_message_row_load_sticker (_tmp2_, dc_message_is_video_sticker_file (m));
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		GtkWidget* _tmp6_;
		_tmp4_ = dc_message_get_file_path (m);
		_tmp5_ = _tmp4_;
		_tmp6_ = dc_message_row_load_picture (_tmp5_, 260, 200, 0, 180, "message-image");
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp6_;
	}
	_tmp7_ = _tmp0_;
	_tmp0_ = NULL;
	picture = _tmp7_;
	_tmp8_ = picture;
	if (_tmp8_ != NULL) {
		GtkWidget* _tmp9_;
		GtkWidget* _tmp10_;
		GtkWidget* _tmp11_;
		GtkWidget* _tmp12_;
		_tmp9_ = picture;
		gtk_widget_add_css_class (_tmp9_, "message-image-irc");
		_tmp10_ = picture;
		gtk_widget_set_halign (_tmp10_, GTK_ALIGN_START);
		_tmp11_ = picture;
		gtk_widget_set_valign (_tmp11_, GTK_ALIGN_START);
		_tmp12_ = picture;
		gtk_box_append (strip, _tmp12_);
	} else {
		GtkLabel* fi = NULL;
		gchar* _tmp13_;
		gchar* _tmp14_;
		GtkLabel* _tmp15_;
		GtkLabel* _tmp16_;
		GtkLabel* _tmp17_;
		GtkLabel* _tmp18_;
		_tmp13_ = dc_message_display_file_name (m, "image");
		_tmp14_ = _tmp13_;
		_tmp15_ = (GtkLabel*) gtk_label_new (_tmp14_);
		g_object_ref_sink (_tmp15_);
		_tmp16_ = _tmp15_;
		_g_free0 (_tmp14_);
		fi = _tmp16_;
		_tmp17_ = fi;
		gtk_widget_add_css_class ((GtkWidget*) _tmp17_, "dim-label");
		_tmp18_ = fi;
		gtk_box_append (strip, (GtkWidget*) _tmp18_);
		_g_object_unref0 (fi);
	}
	_g_object_unref0 (picture);
	_g_object_unref0 (_tmp0_);
}

/**
         * Load a GIF/WebP/WebM attachment as a sticker: natural size capped at
         * STICKER_MAX in both dimensions, never upscaled. Animated stickers
         * start playing (or paused on their first frame) according to the
         * "animate stickers" setting, and a click toggles playback. WebM uses
         * a muted looping media paintable; raster files with a single frame
         * (or that cannot be decoded as an animation) fall back to a static
         * sticker.
         */
static Block24Data*
block24_data_ref (Block24Data* _data24_)
{
	g_atomic_int_inc (&_data24_->_ref_count_);
	return _data24_;
}

static void
block24_data_unref (void * _userdata_)
{
	Block24Data* _data24_;
	_data24_ = (Block24Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data24_->_ref_count_)) {
		_g_object_unref0 (_data24_->sticker);
		g_slice_free (Block24Data, _data24_);
	}
}

static void
_____lambda16_ (Block24Data* _data24_)
{
	DcStickerAnimation* _tmp0_;
	_tmp0_ = _data24_->sticker;
	dc_sticker_animation_toggle_playing (_tmp0_);
}

static void
______lambda16__gtk_gesture_click_released (GtkGestureClick* _sender,
                                            gint n_press,
                                            gdouble x,
                                            gdouble y,
                                            gpointer self)
{
	_____lambda16_ (self);
}

static GtkWidget*
dc_message_row_load_sticker (const gchar* path,
                             gboolean video)
{
	GtkWidget* _tmp28_;
	GError* _inner_error0_ = NULL;
	GtkWidget* result;
	g_return_val_if_fail (path != NULL, NULL);
	if (video) {
		GtkWidget* _tmp0_;
		_tmp0_ = dc_message_row_load_video_sticker (path);
		result = _tmp0_;
		return result;
	}
	{
		GdkPixbufAnimation* anim = NULL;
		GdkPixbufAnimation* _tmp1_;
		GdkPixbufAnimation* _tmp2_;
		_tmp1_ = parla_pixbuf_animation_load (path, &_inner_error0_);
		anim = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = anim;
		if (!parla_pixbuf_animation_is_static_image (_tmp2_)) {
			gint dw = 0;
			GdkPixbufAnimation* _tmp3_;
			gint dh = 0;
			GdkPixbufAnimation* _tmp4_;
			gboolean _tmp5_ = FALSE;
			_tmp3_ = anim;
			dw = parla_pixbuf_animation_get_width (_tmp3_);
			_tmp4_ = anim;
			dh = parla_pixbuf_animation_get_height (_tmp4_);
			if (dw > 0) {
				_tmp5_ = dh > 0;
			} else {
				_tmp5_ = FALSE;
			}
			if (_tmp5_) {
				Block24Data* _data24_;
				gdouble scale = 0.0;
				GtkPicture* picture = NULL;
				GtkPicture* _tmp6_;
				GtkPicture* _tmp7_;
				GdkPixbufAnimation* _tmp8_;
				DcStickerAnimation* _tmp9_;
				GtkPicture* _tmp10_;
				DcStickerAnimation* _tmp11_;
				DcStickerAnimation* _tmp12_;
				GtkPicture* _tmp13_;
				GtkPicture* _tmp14_;
				GtkPicture* _tmp15_;
				GtkPicture* _tmp16_;
				DcScaledPreviewFrame* frame = NULL;
				DcScaledPreviewFrame* _tmp17_;
				DcScaledPreviewFrame* _tmp18_;
				GtkPicture* _tmp19_;
				DcScaledPreviewFrame* _tmp20_;
				DcScaledPreviewFrame* _tmp21_;
				GtkGestureClick* click = NULL;
				DcScaledPreviewFrame* _tmp22_;
				GtkGestureClick* _tmp23_;
				GtkGestureClick* _tmp24_;
				_data24_ = g_slice_new0 (Block24Data);
				_data24_->_ref_count_ = 1;
				scale = MIN (1.0, MIN (((gdouble) DC_MESSAGE_ROW_STICKER_MAX) / dw, ((gdouble) DC_MESSAGE_ROW_STICKER_MAX) / dh));
				dw = MAX (1, (gint) ((dw * scale) + 0.5));
				dh = MAX (1, (gint) ((dh * scale) + 0.5));
				_tmp6_ = (GtkPicture*) gtk_picture_new ();
				g_object_ref_sink (_tmp6_);
				picture = _tmp6_;
				_tmp7_ = picture;
				_tmp8_ = anim;
				_tmp9_ = dc_sticker_animation_new (_tmp7_, _tmp8_, dc_message_row_animate_stickers);
				_data24_->sticker = _tmp9_;
				_tmp10_ = picture;
				_tmp11_ = _data24_->sticker;
				_tmp12_ = _g_object_ref0 (_tmp11_);
				g_object_set_data_full ((GObject*) _tmp10_, "parla-sticker-animation", _tmp12_, g_object_unref);
				_tmp13_ = picture;
				gtk_picture_set_content_fit (_tmp13_, GTK_CONTENT_FIT_CONTAIN);
				_tmp14_ = picture;
				gtk_picture_set_can_shrink (_tmp14_, TRUE);
				_tmp15_ = picture;
				gtk_widget_set_halign ((GtkWidget*) _tmp15_, GTK_ALIGN_FILL);
				_tmp16_ = picture;
				gtk_widget_set_valign ((GtkWidget*) _tmp16_, GTK_ALIGN_FILL);
				_tmp17_ = dc_scaled_preview_frame_new (dw, dh, "message-sticker");
				g_object_ref_sink (_tmp17_);
				frame = _tmp17_;
				_tmp18_ = frame;
				_tmp19_ = picture;
				dc_scaled_preview_frame_set_child (_tmp18_, (GtkWidget*) _tmp19_);
				_tmp20_ = frame;
				gtk_widget_set_halign ((GtkWidget*) _tmp20_, GTK_ALIGN_START);
				_tmp21_ = frame;
				gtk_widget_set_valign ((GtkWidget*) _tmp21_, GTK_ALIGN_START);
				_tmp22_ = frame;
				_tmp23_ = dc_message_row_add_play_toggle ((GtkWidget*) _tmp22_);
				click = _tmp23_;
				_tmp24_ = click;
				g_signal_connect_data (_tmp24_, "released", (GCallback) ______lambda16__gtk_gesture_click_released, block24_data_ref (_data24_), (GClosureNotify) block24_data_unref, 0);
				result = (GtkWidget*) frame;
				_g_object_unref0 (click);
				_g_object_unref0 (picture);
				block24_data_unref (_data24_);
				_data24_ = NULL;
				_g_object_unref0 (anim);
				return result;
			}
		}
		_g_object_unref0 (anim);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		FILE* _tmp25_;
		GError* _tmp26_;
		const gchar* _tmp27_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp25_ = stderr;
		_tmp26_ = e;
		_tmp27_ = _tmp26_->message;
		fprintf (_tmp25_, "  -> Sticker load failed: %s\n", _tmp27_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp28_ = dc_message_row_load_picture (path, DC_MESSAGE_ROW_STICKER_MAX, DC_MESSAGE_ROW_STICKER_MAX, 0, 0, "message-sticker");
	result = _tmp28_;
	return result;
}

static Block25Data*
block25_data_ref (Block25Data* _data25_)
{
	g_atomic_int_inc (&_data25_->_ref_count_);
	return _data25_;
}

static void
block25_data_unref (void * _userdata_)
{
	Block25Data* _data25_;
	_data25_ = (Block25Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data25_->_ref_count_)) {
		_g_object_unref0 (_data25_->sticker);
		g_slice_free (Block25Data, _data25_);
	}
}

static void
__lambda14_ (Block25Data* _data25_)
{
	dc_sticker_video_animation_toggle_playing (_data25_->sticker);
}

static void
___lambda14__gtk_gesture_click_released (GtkGestureClick* _sender,
                                         gint n_press,
                                         gdouble x,
                                         gdouble y,
                                         gpointer self)
{
	__lambda14_ (self);
}

static GtkWidget*
dc_message_row_load_video_sticker (const gchar* path)
{
	Block25Data* _data25_;
	GtkPicture* picture = NULL;
	GtkPicture* _tmp0_;
	DcScaledPreviewFrame* frame = NULL;
	DcScaledPreviewFrame* _tmp1_;
	DcStickerVideoAnimation* _tmp2_;
	DcStickerVideoAnimation* _tmp3_;
	GtkGestureClick* click = NULL;
	GtkGestureClick* _tmp4_;
	GtkWidget* result;
	g_return_val_if_fail (path != NULL, NULL);
	_data25_ = g_slice_new0 (Block25Data);
	_data25_->_ref_count_ = 1;
	_tmp0_ = (GtkPicture*) gtk_picture_new ();
	g_object_ref_sink (_tmp0_);
	picture = _tmp0_;
	gtk_picture_set_content_fit (picture, GTK_CONTENT_FIT_CONTAIN);
	gtk_picture_set_can_shrink (picture, TRUE);
	gtk_widget_set_halign ((GtkWidget*) picture, GTK_ALIGN_FILL);
	gtk_widget_set_valign ((GtkWidget*) picture, GTK_ALIGN_FILL);
	_tmp1_ = dc_scaled_preview_frame_new (DC_MESSAGE_ROW_STICKER_MAX, DC_MESSAGE_ROW_STICKER_MAX, "message-sticker");
	g_object_ref_sink (_tmp1_);
	frame = _tmp1_;
	dc_scaled_preview_frame_set_child (frame, (GtkWidget*) picture);
	gtk_widget_set_halign ((GtkWidget*) frame, GTK_ALIGN_START);
	gtk_widget_set_valign ((GtkWidget*) frame, GTK_ALIGN_START);
	_tmp2_ = dc_sticker_video_animation_new (picture, frame, path, dc_message_row_animate_stickers, DC_MESSAGE_ROW_STICKER_MAX);
	_data25_->sticker = _tmp2_;
	_tmp3_ = _g_object_ref0 (_data25_->sticker);
	g_object_set_data_full ((GObject*) picture, "parla-sticker-video-animation", _tmp3_, g_object_unref);
	_tmp4_ = dc_message_row_add_play_toggle ((GtkWidget*) frame);
	click = _tmp4_;
	g_signal_connect_data (click, "released", (GCallback) ___lambda14__gtk_gesture_click_released, block25_data_ref (_data25_), (GClosureNotify) block25_data_unref, 0);
	result = (GtkWidget*) frame;
	_g_object_unref0 (click);
	_g_object_unref0 (picture);
	block25_data_unref (_data25_);
	_data25_ = NULL;
	return result;
}

/** Primary-click on a sticker toggles its animation playback. */
static GtkGestureClick*
dc_message_row_add_play_toggle (GtkWidget* widget)
{
	GtkGestureClick* click = NULL;
	GtkGestureClick* _tmp0_;
	GtkEventController* _tmp1_;
	GtkGestureClick* result;
	g_return_val_if_fail (widget != NULL, NULL);
	_tmp0_ = (GtkGestureClick*) gtk_gesture_click_new ();
	click = _tmp0_;
	gtk_gesture_single_set_button ((GtkGestureSingle*) click, (guint) GDK_BUTTON_PRIMARY);
	_tmp1_ = _g_object_ref0 ((GtkEventController*) click);
	gtk_widget_add_controller (widget, _tmp1_);
	result = click;
	return result;
}

/** Fit within the maximum bounds, preserving aspect ratio and
            upscaling toward the minimum bounds when possible. */
static GtkWidget*
dc_message_row_load_picture (const gchar* path,
                             gint max_w,
                             gint max_h,
                             gint min_w,
                             gint min_h,
                             const gchar* css_class)
{
	GError* _inner_error0_ = NULL;
	GtkWidget* result;
	g_return_val_if_fail (path != NULL, NULL);
	g_return_val_if_fail (css_class != NULL, NULL);
	{
		gint dw = 0;
		gint dh = 0;
		gboolean _tmp0_ = FALSE;
		gboolean _tmp1_ = FALSE;
		gint _tmp2_ = 0;
		gint _tmp3_ = 0;
		GdkPixbufFormat* _tmp4_;
		GdkPixbuf* pixbuf = NULL;
		GdkPixbuf* _tmp5_;
		GdkTexture* texture = NULL;
		GdkPixbuf* _tmp6_;
		GdkTexture* _tmp7_;
		GtkPicture* picture = NULL;
		GdkTexture* _tmp8_;
		GtkPicture* _tmp9_;
		GtkPicture* _tmp10_;
		GtkPicture* _tmp11_;
		GtkPicture* _tmp12_;
		GtkPicture* _tmp13_;
		DcScaledPreviewFrame* frame = NULL;
		DcScaledPreviewFrame* _tmp14_;
		DcScaledPreviewFrame* _tmp15_;
		GtkPicture* _tmp16_;
		DcScaledPreviewFrame* _tmp17_;
		DcScaledPreviewFrame* _tmp18_;
		_tmp4_ = gdk_pixbuf_get_file_info (path, &_tmp2_, &_tmp3_);
		dw = _tmp2_;
		dh = _tmp3_;
		if (_tmp4_ == NULL) {
			_tmp1_ = TRUE;
		} else {
			_tmp1_ = dw <= 0;
		}
		if (_tmp1_) {
			_tmp0_ = TRUE;
		} else {
			_tmp0_ = dh <= 0;
		}
		if (_tmp0_) {
			result = NULL;
			return result;
		}
		dc_message_row_fit_size (&dw, &dh, max_w, max_h, min_w, min_h);
		_tmp5_ = gdk_pixbuf_new_from_file_at_scale (path, dw, dh, TRUE, &_inner_error0_);
		pixbuf = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp6_ = pixbuf;
		_tmp7_ = dc_texture_from_pixbuf (_tmp6_);
		texture = _tmp7_;
		_tmp8_ = texture;
		_tmp9_ = (GtkPicture*) gtk_picture_new_for_paintable ((GdkPaintable*) _tmp8_);
		g_object_ref_sink (_tmp9_);
		picture = _tmp9_;
		_tmp10_ = picture;
		gtk_picture_set_content_fit (_tmp10_, GTK_CONTENT_FIT_CONTAIN);
		_tmp11_ = picture;
		gtk_picture_set_can_shrink (_tmp11_, TRUE);
		_tmp12_ = picture;
		gtk_widget_set_halign ((GtkWidget*) _tmp12_, GTK_ALIGN_FILL);
		_tmp13_ = picture;
		gtk_widget_set_valign ((GtkWidget*) _tmp13_, GTK_ALIGN_FILL);
		_tmp14_ = dc_scaled_preview_frame_new (dw, dh, css_class);
		g_object_ref_sink (_tmp14_);
		frame = _tmp14_;
		_tmp15_ = frame;
		_tmp16_ = picture;
		dc_scaled_preview_frame_set_child (_tmp15_, (GtkWidget*) _tmp16_);
		_tmp17_ = frame;
		gtk_widget_set_halign ((GtkWidget*) _tmp17_, GTK_ALIGN_START);
		_tmp18_ = frame;
		gtk_widget_set_valign ((GtkWidget*) _tmp18_, GTK_ALIGN_START);
		result = (GtkWidget*) frame;
		_g_object_unref0 (picture);
		_g_object_unref0 (texture);
		_g_object_unref0 (pixbuf);
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		FILE* _tmp19_;
		GError* _tmp20_;
		const gchar* _tmp21_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp19_ = stderr;
		_tmp20_ = e;
		_tmp21_ = _tmp20_->message;
		fprintf (_tmp19_, "  -> Image load failed: %s\n", _tmp21_);
		result = NULL;
		_g_error_free0 (e);
		return result;
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

static void
dc_message_row_fit_size (gint* dw,
                         gint* dh,
                         gint max_w,
                         gint max_h,
                         gint min_w,
                         gint min_h)
{
	gdouble min_scale = 0.0;
	gdouble max_scale = 0.0;
	gdouble scale = 0.0;
	min_scale = MAX (1.0, MAX (dc_message_row_scale_ratio (min_w, *dw, 1.0), dc_message_row_scale_ratio (min_h, *dh, 1.0)));
	max_scale = MIN (dc_message_row_scale_ratio (max_w, *dw, DBL_MAX), dc_message_row_scale_ratio (max_h, *dh, DBL_MAX));
	scale = MIN (min_scale, max_scale);
	*dw = MAX (1, (gint) (((*dw) * scale) + 0.5));
	*dh = MAX (1, (gint) (((*dh) * scale) + 0.5));
}

static gdouble
dc_message_row_scale_ratio (gint limit,
                            gint size,
                            gdouble fallback)
{
	gdouble _tmp0_ = 0.0;
	gdouble result;
	if (limit > 0) {
		_tmp0_ = ((gdouble) limit) / size;
	} else {
		_tmp0_ = fallback;
	}
	result = _tmp0_;
	return result;
}

gboolean
dc_message_row_same_sender (DcMessage* a,
                            DcMessage* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	gboolean _tmp7_;
	gboolean _tmp8_;
	gboolean _tmp9_;
	gboolean _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	gint _tmp13_;
	gint _tmp14_;
	gboolean _tmp15_ = FALSE;
	const gchar* _tmp16_ = NULL;
	const gchar* _tmp17_;
	const gchar* _tmp18_;
	const gchar* _tmp19_ = NULL;
	const gchar* _tmp20_;
	const gchar* _tmp21_;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp1_ = dc_message_get_is_info (a);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp3_;
		gboolean _tmp4_;
		_tmp3_ = dc_message_get_is_info (b);
		_tmp4_ = _tmp3_;
		_tmp0_ = _tmp4_;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp5_ = dc_message_get_is_outgoing (a);
	_tmp6_ = _tmp5_;
	_tmp7_ = dc_message_get_is_outgoing (b);
	_tmp8_ = _tmp7_;
	if (_tmp6_ != _tmp8_) {
		result = FALSE;
		return result;
	}
	_tmp9_ = dc_message_get_is_outgoing (a);
	_tmp10_ = _tmp9_;
	if (_tmp10_) {
		result = TRUE;
		return result;
	}
	_tmp11_ = dc_message_get_sender_contact_id (a);
	_tmp12_ = _tmp11_;
	_tmp13_ = dc_message_get_sender_contact_id (b);
	_tmp14_ = _tmp13_;
	if (_tmp12_ != _tmp14_) {
		result = FALSE;
		return result;
	}
	_tmp17_ = dc_message_get_override_sender_name (a);
	_tmp18_ = _tmp17_;
	_tmp16_ = _tmp18_;
	if (_tmp16_ == NULL) {
		_tmp16_ = "";
	}
	_tmp20_ = dc_message_get_override_sender_name (b);
	_tmp21_ = _tmp20_;
	_tmp19_ = _tmp21_;
	if (_tmp19_ == NULL) {
		_tmp19_ = "";
	}
	if (g_strcmp0 (_tmp16_, _tmp19_) == 0) {
		const gchar* _tmp22_ = NULL;
		const gchar* _tmp23_;
		const gchar* _tmp24_;
		const gchar* _tmp25_ = NULL;
		const gchar* _tmp26_;
		const gchar* _tmp27_;
		_tmp23_ = dc_message_get_sender_name (a);
		_tmp24_ = _tmp23_;
		_tmp22_ = _tmp24_;
		if (_tmp22_ == NULL) {
			_tmp22_ = "";
		}
		_tmp26_ = dc_message_get_sender_name (b);
		_tmp27_ = _tmp26_;
		_tmp25_ = _tmp27_;
		if (_tmp25_ == NULL) {
			_tmp25_ = "";
		}
		_tmp15_ = g_strcmp0 (_tmp22_, _tmp25_) == 0;
	} else {
		_tmp15_ = FALSE;
	}
	result = _tmp15_;
	return result;
}

gchar*
dc_message_row_effective_sender_name (DcMessage* msg)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gchar* author = NULL;
	gchar* _tmp10_;
	const gchar* _tmp11_ = NULL;
	const gchar* _tmp12_;
	gchar* _tmp13_;
	gchar* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = dc_message_get_is_outgoing (msg);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		gboolean _tmp2_ = FALSE;
		const gchar* _tmp3_;
		gchar* _tmp9_;
		_tmp3_ = dc_message_row_self_display_name;
		if (_tmp3_ != NULL) {
			const gchar* _tmp4_;
			gint _tmp5_;
			gint _tmp6_;
			_tmp4_ = dc_message_row_self_display_name;
			_tmp5_ = strlen (_tmp4_);
			_tmp6_ = _tmp5_;
			_tmp2_ = _tmp6_ > 0;
		} else {
			_tmp2_ = FALSE;
		}
		if (_tmp2_) {
			const gchar* _tmp7_;
			gchar* _tmp8_;
			_tmp7_ = dc_message_row_self_display_name;
			_tmp8_ = g_strdup (_tmp7_);
			result = _tmp8_;
			return result;
		}
		_tmp9_ = g_strdup ("me");
		result = _tmp9_;
		return result;
	}
	_tmp10_ = dc_message_row_effective_author_name (msg);
	author = _tmp10_;
	_tmp12_ = author;
	_tmp11_ = _tmp12_;
	if (_tmp11_ == NULL) {
		_tmp11_ = "?";
	}
	_tmp13_ = g_strdup (_tmp11_);
	result = _tmp13_;
	_g_free0 (author);
	return result;
}

/**
         * Display name for an incoming message's author. Prefers the overridden
         * sender name (mailing lists, bots, senders not in the group), shown
         * with a leading "~" per Delta Chat convention; otherwise the contact's
         * display name. Returns null when neither is known.
         */
static gchar*
dc_message_row_effective_author_name (DcMessage* msg)
{
	gboolean _tmp0_ = FALSE;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gboolean _tmp10_ = FALSE;
	const gchar* _tmp11_;
	const gchar* _tmp12_;
	gchar* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_override_sender_name (msg);
	_tmp2_ = _tmp1_;
	if (_tmp2_ != NULL) {
		const gchar* _tmp3_;
		const gchar* _tmp4_;
		gint _tmp5_;
		gint _tmp6_;
		_tmp3_ = dc_message_get_override_sender_name (msg);
		_tmp4_ = _tmp3_;
		_tmp5_ = strlen (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp0_ = _tmp6_ > 0;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp7_ = dc_message_get_override_sender_name (msg);
		_tmp8_ = _tmp7_;
		_tmp9_ = g_strconcat ("~", _tmp8_, NULL);
		result = _tmp9_;
		return result;
	}
	_tmp11_ = dc_message_get_sender_name (msg);
	_tmp12_ = _tmp11_;
	if (_tmp12_ != NULL) {
		const gchar* _tmp13_;
		const gchar* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		_tmp13_ = dc_message_get_sender_name (msg);
		_tmp14_ = _tmp13_;
		_tmp15_ = strlen (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp10_ = _tmp16_ > 0;
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		const gchar* _tmp17_;
		const gchar* _tmp18_;
		gchar* _tmp19_;
		_tmp17_ = dc_message_get_sender_name (msg);
		_tmp18_ = _tmp17_;
		_tmp19_ = g_strdup (_tmp18_);
		result = _tmp19_;
		return result;
	}
	result = NULL;
	return result;
}

/**
         * "Forwarded by <author>" for incoming messages where the forwarder is
         * known, otherwise a plain "Forwarded" marker. Delta Chat does not
         * preserve the original author of forwarded content, so the recoverable
         * identity is the forwarder (sender), exposed as the tooltip address.
         */
static GtkLabel*
dc_message_row_build_forwarded_indicator (DcMessage* msg)
{
	gchar* _tmp0_ = NULL;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gchar* author = NULL;
	gchar* _tmp4_;
	gchar* _tmp5_ = NULL;
	const gchar* _tmp6_;
	GtkLabel* lbl = NULL;
	GtkLabel* _tmp10_;
	GtkLabel* _tmp11_;
	GtkLabel* _tmp12_;
	GtkLabel* _tmp13_;
	GtkLabel* _tmp14_;
	gboolean _tmp15_ = FALSE;
	gboolean _tmp16_ = FALSE;
	gboolean _tmp17_;
	gboolean _tmp18_;
	GtkLabel* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_is_outgoing (msg);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		_g_free0 (_tmp0_);
		_tmp0_ = NULL;
	} else {
		gchar* _tmp3_;
		_tmp3_ = dc_message_row_effective_author_name (msg);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	}
	_tmp4_ = _tmp0_;
	_tmp0_ = NULL;
	author = _tmp4_;
	_tmp6_ = author;
	if (_tmp6_ != NULL) {
		const gchar* _tmp7_;
		gchar* _tmp8_;
		_tmp7_ = author;
		_tmp8_ = g_strconcat ("↪ Forwarded by ", _tmp7_, NULL);
		_g_free0 (_tmp5_);
		_tmp5_ = _tmp8_;
	} else {
		gchar* _tmp9_;
		_tmp9_ = g_strdup ("↪ Forwarded");
		_g_free0 (_tmp5_);
		_tmp5_ = _tmp9_;
	}
	_tmp10_ = (GtkLabel*) gtk_label_new (_tmp5_);
	g_object_ref_sink (_tmp10_);
	lbl = _tmp10_;
	_tmp11_ = lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp11_, "message-forwarded");
	_tmp12_ = lbl;
	gtk_widget_set_halign ((GtkWidget*) _tmp12_, GTK_ALIGN_START);
	_tmp13_ = lbl;
	gtk_label_set_xalign (_tmp13_, (gfloat) 0);
	_tmp14_ = lbl;
	gtk_label_set_ellipsize (_tmp14_, PANGO_ELLIPSIZE_END);
	_tmp17_ = dc_message_get_is_outgoing (msg);
	_tmp18_ = _tmp17_;
	if (!_tmp18_) {
		const gchar* _tmp19_;
		const gchar* _tmp20_;
		_tmp19_ = dc_message_get_sender_address (msg);
		_tmp20_ = _tmp19_;
		_tmp16_ = _tmp20_ != NULL;
	} else {
		_tmp16_ = FALSE;
	}
	if (_tmp16_) {
		const gchar* _tmp21_;
		const gchar* _tmp22_;
		gint _tmp23_;
		gint _tmp24_;
		_tmp21_ = dc_message_get_sender_address (msg);
		_tmp22_ = _tmp21_;
		_tmp23_ = strlen (_tmp22_);
		_tmp24_ = _tmp23_;
		_tmp15_ = _tmp24_ > 0;
	} else {
		_tmp15_ = FALSE;
	}
	if (_tmp15_) {
		GtkLabel* _tmp25_;
		const gchar* _tmp26_;
		const gchar* _tmp27_;
		_tmp25_ = lbl;
		_tmp26_ = dc_message_get_sender_address (msg);
		_tmp27_ = _tmp26_;
		gtk_widget_set_tooltip_text ((GtkWidget*) _tmp25_, _tmp27_);
	}
	result = lbl;
	_g_free0 (_tmp5_);
	_g_free0 (author);
	_g_free0 (_tmp0_);
	return result;
}

static GtkLabel*
dc_message_row_build_edited_indicator (const gchar* text)
{
	GtkLabel* lbl = NULL;
	GtkLabel* _tmp0_;
	GtkLabel* result;
	g_return_val_if_fail (text != NULL, NULL);
	_tmp0_ = (GtkLabel*) gtk_label_new (text);
	g_object_ref_sink (_tmp0_);
	lbl = _tmp0_;
	gtk_widget_add_css_class ((GtkWidget*) lbl, "message-edited");
	gtk_widget_set_tooltip_text ((GtkWidget*) lbl, "This message was edited");
	result = lbl;
	return result;
}

static void
dc_message_row_build_info_row (DcMessageRow* self,
                               DcMessage* msg)
{
	const gchar* _tmp0_ = NULL;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	GtkLabel* label = NULL;
	GtkLabel* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_tmp1_ = dc_message_get_text (msg);
	_tmp2_ = _tmp1_;
	_tmp0_ = _tmp2_;
	if (_tmp0_ == NULL) {
		_tmp0_ = "";
	}
	_tmp3_ = (GtkLabel*) gtk_label_new (_tmp0_);
	g_object_ref_sink (_tmp3_);
	label = _tmp3_;
	gtk_widget_add_css_class ((GtkWidget*) label, "dim-label");
	gtk_widget_add_css_class ((GtkWidget*) label, "caption");
	gtk_widget_set_hexpand ((GtkWidget*) label, TRUE);
	gtk_widget_set_halign ((GtkWidget*) label, GTK_ALIGN_CENTER);
	gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
	gtk_widget_set_margin_top ((GtkWidget*) label, 4);
	gtk_widget_set_margin_bottom ((GtkWidget*) label, 4);
	gtk_label_set_wrap (label, TRUE);
	gtk_box_append ((GtkBox*) self, (GtkWidget*) label);
	_g_object_unref0 (label);
}

static GtkWidget*
dc_message_row_build_video_preview (DcMessage* msg)
{
	GtkOverlay* overlay = NULL;
	GtkOverlay* _tmp0_;
	GtkOverlay* _tmp1_;
	GtkOverlay* _tmp2_;
	GtkWidget* _tmp3_;
	GtkWidget* _tmp4_;
	GtkBox* play_box = NULL;
	GtkBox* _tmp5_;
	GtkBox* _tmp6_;
	GtkBox* _tmp7_;
	GtkBox* _tmp8_;
	GtkBox* _tmp9_;
	GtkImage* play = NULL;
	GtkImage* _tmp10_;
	GtkImage* _tmp11_;
	GtkBox* _tmp12_;
	GtkImage* _tmp13_;
	GtkOverlay* _tmp14_;
	GtkBox* _tmp15_;
	gboolean _tmp16_ = FALSE;
	const gchar* _tmp17_;
	const gchar* _tmp18_;
	DcScaledPreviewFrame* frame = NULL;
	DcScaledPreviewFrame* _tmp37_;
	GtkOverlay* _tmp38_;
	GtkWidget* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = (GtkOverlay*) gtk_overlay_new ();
	g_object_ref_sink (_tmp0_);
	overlay = _tmp0_;
	_tmp1_ = overlay;
	gtk_widget_set_halign ((GtkWidget*) _tmp1_, GTK_ALIGN_START);
	_tmp2_ = overlay;
	_tmp3_ = dc_message_row_build_video_paintable (msg);
	_tmp4_ = _tmp3_;
	gtk_overlay_set_child (_tmp2_, _tmp4_);
	_g_object_unref0 (_tmp4_);
	_tmp5_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	g_object_ref_sink (_tmp5_);
	play_box = _tmp5_;
	_tmp6_ = play_box;
	gtk_widget_add_css_class ((GtkWidget*) _tmp6_, "message-video-play");
	_tmp7_ = play_box;
	gtk_widget_set_halign ((GtkWidget*) _tmp7_, GTK_ALIGN_CENTER);
	_tmp8_ = play_box;
	gtk_widget_set_valign ((GtkWidget*) _tmp8_, GTK_ALIGN_CENTER);
	_tmp9_ = play_box;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp9_, "Play video");
	_tmp10_ = (GtkImage*) gtk_image_new_from_icon_name ("media-playback-start-symbolic");
	g_object_ref_sink (_tmp10_);
	play = _tmp10_;
	_tmp11_ = play;
	gtk_image_set_pixel_size (_tmp11_, 20);
	_tmp12_ = play_box;
	_tmp13_ = play;
	gtk_box_append (_tmp12_, (GtkWidget*) _tmp13_);
	_tmp14_ = overlay;
	_tmp15_ = play_box;
	gtk_overlay_add_overlay (_tmp14_, (GtkWidget*) _tmp15_);
	_tmp17_ = dc_message_get_file_name (msg);
	_tmp18_ = _tmp17_;
	if (_tmp18_ != NULL) {
		const gchar* _tmp19_;
		const gchar* _tmp20_;
		gint _tmp21_;
		gint _tmp22_;
		_tmp19_ = dc_message_get_file_name (msg);
		_tmp20_ = _tmp19_;
		_tmp21_ = strlen (_tmp20_);
		_tmp22_ = _tmp21_;
		_tmp16_ = _tmp22_ > 0;
	} else {
		_tmp16_ = FALSE;
	}
	if (_tmp16_) {
		GtkLabel* name = NULL;
		const gchar* _tmp23_;
		const gchar* _tmp24_;
		GtkLabel* _tmp25_;
		GtkLabel* _tmp26_;
		GtkLabel* _tmp27_;
		GtkLabel* _tmp28_;
		GtkLabel* _tmp29_;
		GtkLabel* _tmp30_;
		GtkLabel* _tmp31_;
		GtkLabel* _tmp32_;
		GtkLabel* _tmp33_;
		GtkLabel* _tmp34_;
		GtkOverlay* _tmp35_;
		GtkLabel* _tmp36_;
		_tmp23_ = dc_message_get_file_name (msg);
		_tmp24_ = _tmp23_;
		_tmp25_ = (GtkLabel*) gtk_label_new (_tmp24_);
		g_object_ref_sink (_tmp25_);
		name = _tmp25_;
		_tmp26_ = name;
		gtk_widget_add_css_class ((GtkWidget*) _tmp26_, "message-video-name");
		_tmp27_ = name;
		gtk_label_set_ellipsize (_tmp27_, PANGO_ELLIPSIZE_MIDDLE);
		_tmp28_ = name;
		gtk_label_set_max_width_chars (_tmp28_, 30);
		_tmp29_ = name;
		gtk_widget_set_halign ((GtkWidget*) _tmp29_, GTK_ALIGN_START);
		_tmp30_ = name;
		gtk_widget_set_valign ((GtkWidget*) _tmp30_, GTK_ALIGN_END);
		_tmp31_ = name;
		gtk_label_set_xalign (_tmp31_, (gfloat) 0);
		_tmp32_ = name;
		gtk_widget_set_margin_start ((GtkWidget*) _tmp32_, 8);
		_tmp33_ = name;
		gtk_widget_set_margin_end ((GtkWidget*) _tmp33_, 8);
		_tmp34_ = name;
		gtk_widget_set_margin_bottom ((GtkWidget*) _tmp34_, 6);
		_tmp35_ = overlay;
		_tmp36_ = name;
		gtk_overlay_add_overlay (_tmp35_, (GtkWidget*) _tmp36_);
		_g_object_unref0 (name);
	}
	_tmp37_ = dc_scaled_preview_frame_new (260, 150, "message-video-frame");
	g_object_ref_sink (_tmp37_);
	frame = _tmp37_;
	_tmp38_ = overlay;
	dc_scaled_preview_frame_set_child (frame, (GtkWidget*) _tmp38_);
	result = (GtkWidget*) frame;
	_g_object_unref0 (play);
	_g_object_unref0 (play_box);
	_g_object_unref0 (overlay);
	return result;
}

static GtkWidget*
dc_message_row_build_video_paintable (DcMessage* msg)
{
	GtkPicture* preview = NULL;
	gboolean _tmp0_;
	gboolean _tmp1_;
	GtkPicture* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	GtkPicture* _tmp14_;
	GtkPicture* _tmp15_;
	GtkPicture* _tmp16_;
	GtkWidget* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = dc_message_get_has_local_file (msg);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		GtkMediaFile* media = NULL;
		const gchar* _tmp2_;
		const gchar* _tmp3_;
		GtkMediaFile* _tmp4_;
		GtkMediaFile* _tmp5_;
		GtkMediaFile* _tmp6_;
		GtkPicture* _tmp7_;
		_tmp2_ = dc_message_get_file_path (msg);
		_tmp3_ = _tmp2_;
		_tmp4_ = (GtkMediaFile*) gtk_media_file_new_for_filename (_tmp3_);
		media = _tmp4_;
		_tmp5_ = media;
		gtk_media_stream_pause ((GtkMediaStream*) _tmp5_);
		_tmp6_ = media;
		_tmp7_ = (GtkPicture*) gtk_picture_new_for_paintable ((GdkPaintable*) _tmp6_);
		g_object_ref_sink (_tmp7_);
		_g_object_unref0 (preview);
		preview = _tmp7_;
		_g_object_unref0 (media);
	} else {
		GdkPaintable* _tmp8_;
		GdkPaintable* _tmp9_;
		GtkPicture* _tmp10_;
		_tmp8_ = gdk_paintable_new_empty (260, 150);
		_tmp9_ = _tmp8_;
		_tmp10_ = (GtkPicture*) gtk_picture_new_for_paintable (_tmp9_);
		g_object_ref_sink (_tmp10_);
		_g_object_unref0 (preview);
		preview = _tmp10_;
		_g_object_unref0 (_tmp9_);
	}
	_tmp11_ = preview;
	_tmp12_ = dc_message_display_file_name (msg, "video");
	_tmp13_ = _tmp12_;
	gtk_picture_set_alternative_text (_tmp11_, _tmp13_);
	_g_free0 (_tmp13_);
	_tmp14_ = preview;
	gtk_picture_set_can_shrink (_tmp14_, TRUE);
	_tmp15_ = preview;
	gtk_picture_set_content_fit (_tmp15_, GTK_CONTENT_FIT_COVER);
	_tmp16_ = preview;
	gtk_widget_add_css_class ((GtkWidget*) _tmp16_, "message-video-bg");
	result = (GtkWidget*) preview;
	return result;
}

static GtkWidget*
dc_message_row_build_audio_player (DcMessageRow* self,
                                   DcMessage* msg)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	DcAudioPlayer* _tmp3_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = dc_message_get_has_local_file (msg);
	_tmp1_ = _tmp0_;
	if (!_tmp1_) {
		GtkBox* _tmp2_;
		_tmp2_ = dc_message_row_build_file_indicator (msg);
		result = (GtkWidget*) _tmp2_;
		return result;
	}
	_tmp3_ = dc_audio_player_new (msg, self->priv->account_id);
	g_object_ref_sink (_tmp3_);
	result = (GtkWidget*) _tmp3_;
	return result;
}

static GtkBox*
dc_message_row_build_file_indicator (DcMessage* msg)
{
	GtkBox* file_box = NULL;
	GtkBox* _tmp0_;
	GtkImage* icon = NULL;
	GtkImage* _tmp1_;
	GtkLabel* fname = NULL;
	gchar* _tmp2_;
	gchar* _tmp3_;
	GtkLabel* _tmp4_;
	GtkLabel* _tmp5_;
	GtkBox* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
	g_object_ref_sink (_tmp0_);
	file_box = _tmp0_;
	gtk_widget_add_css_class ((GtkWidget*) file_box, "message-attachment");
	_tmp1_ = (GtkImage*) gtk_image_new_from_icon_name ("mail-attachment-symbolic");
	g_object_ref_sink (_tmp1_);
	icon = _tmp1_;
	gtk_image_set_pixel_size (icon, 16);
	gtk_box_append (file_box, (GtkWidget*) icon);
	_tmp2_ = dc_message_display_file_name (msg, "file");
	_tmp3_ = _tmp2_;
	_tmp4_ = (GtkLabel*) gtk_label_new (_tmp3_);
	g_object_ref_sink (_tmp4_);
	_tmp5_ = _tmp4_;
	_g_free0 (_tmp3_);
	fname = _tmp5_;
	gtk_widget_add_css_class ((GtkWidget*) fname, "dim-label");
	gtk_label_set_ellipsize (fname, PANGO_ELLIPSIZE_MIDDLE);
	gtk_label_set_max_width_chars (fname, 28);
	gtk_box_append (file_box, (GtkWidget*) fname);
	result = file_box;
	_g_object_unref0 (fname);
	_g_object_unref0 (icon);
	return result;
}

static GtkLabel*
dc_message_row_build_tick_indicator (DcMessage* msg)
{
	gchar* glyph = NULL;
	gchar* extra_class = NULL;
	gchar* tooltip = NULL;
	gboolean _tmp0_;
	gboolean _tmp1_;
	GtkLabel* lbl = NULL;
	const gchar* _tmp20_;
	GtkLabel* _tmp21_;
	GtkLabel* _tmp22_;
	GtkLabel* _tmp23_;
	const gchar* _tmp24_;
	const gchar* _tmp25_;
	GtkLabel* result;
	g_return_val_if_fail (msg != NULL, NULL);
	tooltip = NULL;
	_tmp0_ = dc_message_get_is_failed (msg);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		_tmp2_ = g_strdup ("⚠");
		_g_free0 (glyph);
		glyph = _tmp2_;
		_tmp3_ = g_strdup ("message-tick-failed");
		_g_free0 (extra_class);
		extra_class = _tmp3_;
		_tmp4_ = g_strdup ("Sending failed");
		_g_free0 (tooltip);
		tooltip = _tmp4_;
	} else {
		gboolean _tmp5_;
		gboolean _tmp6_;
		_tmp5_ = dc_message_get_is_read (msg);
		_tmp6_ = _tmp5_;
		if (_tmp6_) {
			gchar* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			_tmp7_ = g_strdup ("✓✓");
			_g_free0 (glyph);
			glyph = _tmp7_;
			_tmp8_ = g_strdup ("message-tick-read");
			_g_free0 (extra_class);
			extra_class = _tmp8_;
			_tmp9_ = g_strdup ("Read");
			_g_free0 (tooltip);
			tooltip = _tmp9_;
		} else {
			gboolean _tmp10_;
			gboolean _tmp11_;
			_tmp10_ = dc_message_get_is_delivered (msg);
			_tmp11_ = _tmp10_;
			if (_tmp11_) {
				gchar* _tmp12_;
				gchar* _tmp13_;
				gchar* _tmp14_;
				_tmp12_ = g_strdup ("✓");
				_g_free0 (glyph);
				glyph = _tmp12_;
				_tmp13_ = g_strdup ("message-tick");
				_g_free0 (extra_class);
				extra_class = _tmp13_;
				_tmp14_ = g_strdup ("Delivered");
				_g_free0 (tooltip);
				tooltip = _tmp14_;
			} else {
				gboolean _tmp15_;
				gboolean _tmp16_;
				_tmp15_ = dc_message_get_is_pending (msg);
				_tmp16_ = _tmp15_;
				if (_tmp16_) {
					gchar* _tmp17_;
					gchar* _tmp18_;
					gchar* _tmp19_;
					_tmp17_ = g_strdup ("⧖");
					_g_free0 (glyph);
					glyph = _tmp17_;
					_tmp18_ = g_strdup ("message-tick");
					_g_free0 (extra_class);
					extra_class = _tmp18_;
					_tmp19_ = g_strdup ("Sending…");
					_g_free0 (tooltip);
					tooltip = _tmp19_;
				} else {
					result = NULL;
					_g_free0 (tooltip);
					_g_free0 (extra_class);
					_g_free0 (glyph);
					return result;
				}
			}
		}
	}
	_tmp20_ = glyph;
	_tmp21_ = (GtkLabel*) gtk_label_new (_tmp20_);
	g_object_ref_sink (_tmp21_);
	lbl = _tmp21_;
	_tmp22_ = lbl;
	gtk_widget_add_css_class ((GtkWidget*) _tmp22_, "message-time");
	_tmp23_ = lbl;
	_tmp24_ = extra_class;
	gtk_widget_add_css_class ((GtkWidget*) _tmp23_, _tmp24_);
	_tmp25_ = tooltip;
	if (_tmp25_ != NULL) {
		GtkLabel* _tmp26_;
		const gchar* _tmp27_;
		_tmp26_ = lbl;
		_tmp27_ = tooltip;
		gtk_widget_set_tooltip_text ((GtkWidget*) _tmp26_, _tmp27_);
	}
	result = lbl;
	_g_free0 (tooltip);
	_g_free0 (extra_class);
	_g_free0 (glyph);
	return result;
}

static GtkLabel*
dc_message_row_build_pin_indicator (DcMessage* msg)
{
	GtkLabel* pin = NULL;
	GtkLabel* _tmp0_;
	GtkLabel* result;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = (GtkLabel*) gtk_label_new ("📌");
	g_object_ref_sink (_tmp0_);
	pin = _tmp0_;
	gtk_widget_add_css_class ((GtkWidget*) pin, "message-pin");
	gtk_widget_set_tooltip_text ((GtkWidget*) pin, "Pinned");
	g_object_bind_property_with_closures ((GObject*) msg, "is-pinned", (GObject*) pin, "visible", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
	result = pin;
	return result;
}

static GtkButton*
dc_message_row_build_quote_block (DcMessageRow* self,
                                  DcMessage* msg,
                                  gint max_width_chars,
                                  gint lines)
{
	GtkButton* btn = NULL;
	GtkButton* _tmp0_;
	GtkButton* _tmp1_;
	GtkButton* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	gboolean stacked = FALSE;
	GtkButton* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = (GtkButton*) gtk_button_new ();
	g_object_ref_sink (_tmp0_);
	btn = _tmp0_;
	_tmp1_ = btn;
	gtk_widget_add_css_class ((GtkWidget*) _tmp1_, "flat");
	_tmp2_ = btn;
	gtk_widget_add_css_class ((GtkWidget*) _tmp2_, "quote-block");
	_tmp3_ = dc_message_get_quote_msg_id (msg);
	_tmp4_ = _tmp3_;
	if (_tmp4_ > 0) {
		GtkButton* _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		GtkButton* _tmp8_;
		_tmp5_ = btn;
		_tmp6_ = dc_message_get_quote_msg_id (msg);
		_tmp7_ = _tmp6_;
		g_object_set_data_full ((GObject*) _tmp5_, "parla-message-row-quote-id", (gpointer) ((gintptr) _tmp7_), NULL);
		_tmp8_ = btn;
		g_signal_connect_object (_tmp8_, "clicked", (GCallback) dc_message_row_on_quote_clicked, (GObject*) self, (GConnectFlags) 0);
	}
	if (lines > 1) {
		const gchar* _tmp11_;
		const gchar* _tmp12_;
		_tmp11_ = dc_message_get_quote_sender_name (msg);
		_tmp12_ = _tmp11_;
		_tmp10_ = _tmp12_ != NULL;
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		const gchar* _tmp13_;
		const gchar* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		_tmp13_ = dc_message_get_quote_sender_name (msg);
		_tmp14_ = _tmp13_;
		_tmp15_ = strlen (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp9_ = _tmp16_ > 0;
	} else {
		_tmp9_ = FALSE;
	}
	stacked = _tmp9_;
	if (stacked) {
		GtkBox* box = NULL;
		GtkBox* _tmp17_;
		GtkLabel* s = NULL;
		const gchar* _tmp18_;
		const gchar* _tmp19_;
		GtkLabel* _tmp20_;
		GtkLabel* _tmp21_;
		GtkLabel* _tmp22_;
		GtkLabel* _tmp23_;
		GtkBox* _tmp24_;
		GtkLabel* _tmp25_;
		GtkLabel* t = NULL;
		const gchar* _tmp26_;
		const gchar* _tmp27_;
		GtkLabel* _tmp28_;
		GtkLabel* _tmp29_;
		GtkLabel* _tmp30_;
		GtkLabel* _tmp31_;
		GtkLabel* _tmp32_;
		GtkLabel* _tmp33_;
		GtkLabel* _tmp34_;
		GtkBox* _tmp35_;
		GtkLabel* _tmp36_;
		GtkButton* _tmp37_;
		GtkBox* _tmp38_;
		_tmp17_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
		g_object_ref_sink (_tmp17_);
		box = _tmp17_;
		_tmp18_ = dc_message_get_quote_sender_name (msg);
		_tmp19_ = _tmp18_;
		_tmp20_ = (GtkLabel*) gtk_label_new (_tmp19_);
		g_object_ref_sink (_tmp20_);
		s = _tmp20_;
		_tmp21_ = s;
		gtk_widget_add_css_class ((GtkWidget*) _tmp21_, "quote-sender");
		_tmp22_ = s;
		gtk_widget_set_halign ((GtkWidget*) _tmp22_, GTK_ALIGN_START);
		_tmp23_ = s;
		gtk_label_set_xalign (_tmp23_, (gfloat) 0);
		_tmp24_ = box;
		_tmp25_ = s;
		gtk_box_append (_tmp24_, (GtkWidget*) _tmp25_);
		_tmp26_ = dc_message_get_quote_text (msg);
		_tmp27_ = _tmp26_;
		_tmp28_ = (GtkLabel*) gtk_label_new (_tmp27_);
		g_object_ref_sink (_tmp28_);
		t = _tmp28_;
		_tmp29_ = t;
		gtk_widget_add_css_class ((GtkWidget*) _tmp29_, "quote-text");
		_tmp30_ = t;
		gtk_widget_set_halign ((GtkWidget*) _tmp30_, GTK_ALIGN_START);
		_tmp31_ = t;
		gtk_label_set_xalign (_tmp31_, (gfloat) 0);
		_tmp32_ = t;
		gtk_label_set_ellipsize (_tmp32_, PANGO_ELLIPSIZE_END);
		_tmp33_ = t;
		gtk_label_set_max_width_chars (_tmp33_, max_width_chars);
		_tmp34_ = t;
		gtk_label_set_lines (_tmp34_, lines);
		_tmp35_ = box;
		_tmp36_ = t;
		gtk_box_append (_tmp35_, (GtkWidget*) _tmp36_);
		_tmp37_ = btn;
		_tmp38_ = box;
		gtk_button_set_child (_tmp37_, (GtkWidget*) _tmp38_);
		_g_object_unref0 (t);
		_g_object_unref0 (s);
		_g_object_unref0 (box);
	} else {
		gchar* _tmp39_ = NULL;
		gboolean _tmp40_ = FALSE;
		const gchar* _tmp41_;
		const gchar* _tmp42_;
		gchar* prefix = NULL;
		gchar* _tmp51_;
		GtkLabel* t = NULL;
		const gchar* _tmp52_;
		const gchar* _tmp53_;
		const gchar* _tmp54_;
		gchar* _tmp55_;
		gchar* _tmp56_;
		GtkLabel* _tmp57_;
		GtkLabel* _tmp58_;
		GtkLabel* _tmp59_;
		GtkLabel* _tmp60_;
		GtkLabel* _tmp61_;
		GtkLabel* _tmp62_;
		GtkLabel* _tmp63_;
		GtkLabel* _tmp64_;
		GtkButton* _tmp65_;
		GtkLabel* _tmp66_;
		_tmp41_ = dc_message_get_quote_sender_name (msg);
		_tmp42_ = _tmp41_;
		if (_tmp42_ != NULL) {
			const gchar* _tmp43_;
			const gchar* _tmp44_;
			gint _tmp45_;
			gint _tmp46_;
			_tmp43_ = dc_message_get_quote_sender_name (msg);
			_tmp44_ = _tmp43_;
			_tmp45_ = strlen (_tmp44_);
			_tmp46_ = _tmp45_;
			_tmp40_ = _tmp46_ > 0;
		} else {
			_tmp40_ = FALSE;
		}
		if (_tmp40_) {
			const gchar* _tmp47_;
			const gchar* _tmp48_;
			gchar* _tmp49_;
			_tmp47_ = dc_message_get_quote_sender_name (msg);
			_tmp48_ = _tmp47_;
			_tmp49_ = g_strconcat (_tmp48_, ": ", NULL);
			_g_free0 (_tmp39_);
			_tmp39_ = _tmp49_;
		} else {
			gchar* _tmp50_;
			_tmp50_ = g_strdup ("");
			_g_free0 (_tmp39_);
			_tmp39_ = _tmp50_;
		}
		_tmp51_ = _tmp39_;
		_tmp39_ = NULL;
		prefix = _tmp51_;
		_tmp52_ = prefix;
		_tmp53_ = dc_message_get_quote_text (msg);
		_tmp54_ = _tmp53_;
		_tmp55_ = g_strconcat (_tmp52_, _tmp54_, NULL);
		_tmp56_ = _tmp55_;
		_tmp57_ = (GtkLabel*) gtk_label_new (_tmp56_);
		g_object_ref_sink (_tmp57_);
		_tmp58_ = _tmp57_;
		_g_free0 (_tmp56_);
		t = _tmp58_;
		_tmp59_ = t;
		gtk_widget_add_css_class ((GtkWidget*) _tmp59_, "quote-text");
		_tmp60_ = t;
		gtk_widget_set_halign ((GtkWidget*) _tmp60_, GTK_ALIGN_START);
		_tmp61_ = t;
		gtk_label_set_xalign (_tmp61_, (gfloat) 0);
		_tmp62_ = t;
		gtk_label_set_ellipsize (_tmp62_, PANGO_ELLIPSIZE_END);
		_tmp63_ = t;
		gtk_label_set_max_width_chars (_tmp63_, max_width_chars);
		_tmp64_ = t;
		gtk_label_set_lines (_tmp64_, lines);
		_tmp65_ = btn;
		_tmp66_ = t;
		gtk_button_set_child (_tmp65_, (GtkWidget*) _tmp66_);
		_g_object_unref0 (t);
		_g_free0 (prefix);
		_g_free0 (_tmp39_);
	}
	result = btn;
	return result;
}

static void
dc_message_row_on_quote_clicked (GtkButton* button,
                                 DcMessageRow* row)
{
	gint quoted_id = 0;
	gconstpointer _tmp0_;
	g_return_if_fail (button != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = g_object_get_data ((GObject*) button, "parla-message-row-quote-id");
	quoted_id = (gint) ((gintptr) _tmp0_);
	if (quoted_id > 0) {
		g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_QUOTE_CLICKED_SIGNAL], 0, quoted_id);
	}
}

/** Trim a long body for the collapsed preview, cutting at the last line
         * break before the cap when there is one so markup stays balanced. */
static gint
string_index_of_nth_char (const gchar* self,
                          glong c)
{
	gchar* _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = g_utf8_offset_to_pointer (self, c);
	result = (gint) (_tmp0_ - ((gchar*) self));
	return result;
}

static gint
string_last_index_of_char (const gchar* self,
                           gunichar c,
                           gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = g_utf8_strrchr (((gchar*) self) + start_index, (gssize) -1, c);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

static gchar*
dc_message_row_collapsed_preview (const gchar* text)
{
	gchar* head = NULL;
	gchar* _tmp1_;
	gint nl = 0;
	const gchar* _tmp2_;
	const gchar* _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* result;
	g_return_val_if_fail (text != NULL, NULL);
	if (((glong) g_utf8_strlen (text, (gssize) -1)) <= DC_MESSAGE_ROW_PREVIEW_MAX_CHARS) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (text);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = string_substring (text, (glong) 0, (glong) string_index_of_nth_char (text, DC_MESSAGE_ROW_PREVIEW_MAX_CHARS));
	head = _tmp1_;
	_tmp2_ = head;
	nl = string_last_index_of_char (_tmp2_, (gunichar) '\n', 0);
	_tmp3_ = head;
	_tmp4_ = strlen (_tmp3_);
	_tmp5_ = _tmp4_;
	if (nl > (_tmp5_ / 2)) {
		const gchar* _tmp6_;
		gchar* _tmp7_;
		_tmp6_ = head;
		_tmp7_ = string_substring (_tmp6_, (glong) 0, (glong) nl);
		_g_free0 (head);
		head = _tmp7_;
	}
	_tmp8_ = head;
	_tmp9_ = g_strconcat (_tmp8_, "…", NULL);
	result = _tmp9_;
	_g_free0 (head);
	return result;
}

static GtkWidget*
dc_message_row_build_text_widget (DcMessageRow* self,
                                  DcMessage* msg,
                                  gint max_width_chars)
{
	GtkWidget* body = NULL;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp42_ = FALSE;
	gboolean _tmp43_;
	gboolean _tmp44_;
	GtkBox* box = NULL;
	GtkBox* _tmp47_;
	GtkBox* _tmp48_;
	GtkBox* _tmp49_;
	GtkWidget* _tmp50_;
	gboolean _tmp51_ = FALSE;
	gboolean _tmp52_;
	gboolean _tmp53_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_full_message_expanded (msg);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		const gchar* _tmp3_;
		const gchar* _tmp4_;
		_tmp3_ = dc_message_get_full_message_text (msg);
		_tmp4_ = _tmp3_;
		_tmp0_ = _tmp4_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		const gchar* _tmp5_;
		const gchar* _tmp6_;
		DcMentionRoster* _tmp7_;
		GtkLabel* _tmp8_;
		_tmp5_ = dc_message_get_full_message_text (msg);
		_tmp6_ = _tmp5_;
		_tmp7_ = self->priv->mention_roster;
		_tmp8_ = dc_message_row_build_markup_label (_tmp6_, max_width_chars, 0, _tmp7_);
		_g_object_unref0 (body);
		body = (GtkWidget*) _tmp8_;
	} else {
		gboolean _tmp9_ = FALSE;
		gboolean _tmp10_ = FALSE;
		gboolean _tmp11_;
		gboolean _tmp12_;
		_tmp11_ = dc_message_get_full_message_expanded (msg);
		_tmp12_ = _tmp11_;
		if (!_tmp12_) {
			gboolean _tmp13_;
			gboolean _tmp14_;
			_tmp13_ = dc_message_get_has_full_message_action (msg);
			_tmp14_ = _tmp13_;
			_tmp10_ = _tmp14_;
		} else {
			_tmp10_ = FALSE;
		}
		if (_tmp10_) {
			const gchar* _tmp15_ = NULL;
			const gchar* _tmp16_;
			const gchar* _tmp17_;
			_tmp16_ = dc_message_get_text (msg);
			_tmp17_ = _tmp16_;
			_tmp15_ = _tmp17_;
			if (_tmp15_ == NULL) {
				_tmp15_ = "";
			}
			_tmp9_ = ((glong) g_utf8_strlen (_tmp15_, (gssize) -1)) > DC_MESSAGE_ROW_PREVIEW_MAX_CHARS;
		} else {
			_tmp9_ = FALSE;
		}
		if (_tmp9_) {
			const gchar* _tmp18_ = NULL;
			const gchar* _tmp19_;
			const gchar* _tmp20_;
			gchar* _tmp21_;
			gchar* _tmp22_;
			DcMentionRoster* _tmp23_;
			GtkLabel* _tmp24_;
			_tmp19_ = dc_message_get_text (msg);
			_tmp20_ = _tmp19_;
			_tmp18_ = _tmp20_;
			if (_tmp18_ == NULL) {
				_tmp18_ = "";
			}
			_tmp21_ = dc_message_row_collapsed_preview (_tmp18_);
			_tmp22_ = _tmp21_;
			_tmp23_ = self->priv->mention_roster;
			_tmp24_ = dc_message_row_build_markup_label (_tmp22_, max_width_chars, 0, _tmp23_);
			_g_object_unref0 (body);
			body = (GtkWidget*) _tmp24_;
			_g_free0 (_tmp22_);
		} else {
			if (dc_markdown_mode == DC_MARKDOWN_MODE_ENABLED) {
				GtkWidget* md_body = NULL;
				GtkWidget* _tmp25_;
				GtkWidget* _tmp26_ = NULL;
				GtkWidget* _tmp27_;
				GtkWidget* _tmp28_;
				GtkWidget* _tmp35_;
				_tmp25_ = dc_message_row_build_text_with_markdown_blocks (self, msg, max_width_chars);
				md_body = _tmp25_;
				_tmp27_ = md_body;
				_tmp28_ = _g_object_ref0 (_tmp27_);
				_tmp26_ = _tmp28_;
				if (_tmp26_ == NULL) {
					const gchar* _tmp29_;
					const gchar* _tmp30_;
					const gchar* _tmp31_;
					const gchar* _tmp32_;
					DcMentionRoster* _tmp33_;
					GtkLabel* _tmp34_;
					_tmp29_ = dc_message_get_text (msg);
					_tmp30_ = _tmp29_;
					_tmp31_ = dc_message_get_text (msg);
					_tmp32_ = _tmp31_;
					_tmp33_ = self->priv->mention_roster;
					_tmp34_ = dc_message_row_build_markup_label (_tmp30_, max_width_chars, dc_message_row_emoji_only_count (_tmp32_), _tmp33_);
					_g_object_unref0 (_tmp26_);
					_tmp26_ = (GtkWidget*) _tmp34_;
				}
				_tmp35_ = _tmp26_;
				_tmp26_ = NULL;
				_g_object_unref0 (body);
				body = _tmp35_;
				_g_object_unref0 (_tmp26_);
				_g_object_unref0 (md_body);
			} else {
				const gchar* _tmp36_;
				const gchar* _tmp37_;
				const gchar* _tmp38_;
				const gchar* _tmp39_;
				DcMentionRoster* _tmp40_;
				GtkLabel* _tmp41_;
				_tmp36_ = dc_message_get_text (msg);
				_tmp37_ = _tmp36_;
				_tmp38_ = dc_message_get_text (msg);
				_tmp39_ = _tmp38_;
				_tmp40_ = self->priv->mention_roster;
				_tmp41_ = dc_message_row_build_markup_label (_tmp37_, max_width_chars, dc_message_row_emoji_only_count (_tmp39_), _tmp40_);
				_g_object_unref0 (body);
				body = (GtkWidget*) _tmp41_;
			}
		}
	}
	_tmp43_ = dc_message_get_has_full_message_action (msg);
	_tmp44_ = _tmp43_;
	if (!_tmp44_) {
		gboolean _tmp45_;
		gboolean _tmp46_;
		_tmp45_ = dc_message_get_is_downloading_full_message (msg);
		_tmp46_ = _tmp45_;
		_tmp42_ = !_tmp46_;
	} else {
		_tmp42_ = FALSE;
	}
	if (_tmp42_) {
		result = body;
		return result;
	}
	_tmp47_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
	g_object_ref_sink (_tmp47_);
	box = _tmp47_;
	_tmp48_ = box;
	gtk_widget_set_halign ((GtkWidget*) _tmp48_, GTK_ALIGN_FILL);
	_tmp49_ = box;
	_tmp50_ = body;
	gtk_box_append (_tmp49_, _tmp50_);
	_tmp52_ = dc_message_get_is_downloading_full_message (msg);
	_tmp53_ = _tmp52_;
	if (_tmp53_) {
		_tmp51_ = TRUE;
	} else {
		gboolean _tmp54_;
		gboolean _tmp55_;
		_tmp54_ = dc_message_get_full_message_loading (msg);
		_tmp55_ = _tmp54_;
		_tmp51_ = _tmp55_;
	}
	if (_tmp51_) {
		const gchar* _tmp56_ = NULL;
		gboolean _tmp57_;
		gboolean _tmp58_;
		gchar* status_text = NULL;
		gchar* _tmp62_;
		GtkLabel* status = NULL;
		const gchar* _tmp63_;
		GtkLabel* _tmp64_;
		GtkLabel* _tmp65_;
		GtkLabel* _tmp66_;
		GtkLabel* _tmp67_;
		GtkBox* _tmp68_;
		GtkLabel* _tmp69_;
		_tmp57_ = dc_message_get_full_message_loading (msg);
		_tmp58_ = _tmp57_;
		if (_tmp58_) {
			_tmp56_ = "Loading full message…";
		} else {
			const gchar* _tmp59_ = NULL;
			gboolean _tmp60_;
			gboolean _tmp61_;
			_tmp60_ = dc_message_get_has_file (msg);
			_tmp61_ = _tmp60_;
			if (_tmp61_) {
				_tmp59_ = "Downloading attachment...";
			} else {
				_tmp59_ = "Downloading full message...";
			}
			_tmp56_ = _tmp59_;
		}
		_tmp62_ = g_strdup (_tmp56_);
		status_text = _tmp62_;
		_tmp63_ = status_text;
		_tmp64_ = (GtkLabel*) gtk_label_new (_tmp63_);
		g_object_ref_sink (_tmp64_);
		status = _tmp64_;
		_tmp65_ = status;
		gtk_widget_add_css_class ((GtkWidget*) _tmp65_, "message-full-text-status");
		_tmp66_ = status;
		gtk_widget_set_halign ((GtkWidget*) _tmp66_, GTK_ALIGN_START);
		_tmp67_ = status;
		gtk_label_set_xalign (_tmp67_, (gfloat) 0);
		_tmp68_ = box;
		_tmp69_ = status;
		gtk_box_append (_tmp68_, (GtkWidget*) _tmp69_);
		_g_object_unref0 (status);
		_g_free0 (status_text);
	} else {
		GtkBox* actions = NULL;
		GtkBox* _tmp70_;
		GtkBox* _tmp71_;
		GtkBox* _tmp72_;
		const gchar* _tmp73_ = NULL;
		gboolean _tmp74_;
		gboolean _tmp75_;
		GtkButton* toggle_btn = NULL;
		GtkButton* _tmp82_;
		GtkButton* _tmp83_;
		GtkButton* _tmp84_;
		GtkButton* _tmp85_;
		GtkButton* _tmp86_;
		GtkButton* _tmp87_;
		GtkBox* _tmp88_;
		GtkButton* _tmp89_;
		gboolean _tmp90_;
		gboolean _tmp91_;
		GtkBox* _tmp101_;
		GtkBox* _tmp102_;
		_tmp70_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
		g_object_ref_sink (_tmp70_);
		actions = _tmp70_;
		_tmp71_ = actions;
		gtk_widget_set_halign ((GtkWidget*) _tmp71_, GTK_ALIGN_FILL);
		_tmp72_ = actions;
		gtk_widget_set_hexpand ((GtkWidget*) _tmp72_, TRUE);
		_tmp74_ = dc_message_get_can_download_full_message (msg);
		_tmp75_ = _tmp74_;
		if (_tmp75_) {
			const gchar* _tmp76_ = NULL;
			gboolean _tmp77_;
			gboolean _tmp78_;
			_tmp77_ = dc_message_get_has_file (msg);
			_tmp78_ = _tmp77_;
			if (_tmp78_) {
				_tmp76_ = "Download attachment";
			} else {
				_tmp76_ = "Download full message";
			}
			_tmp73_ = _tmp76_;
		} else {
			const gchar* _tmp79_ = NULL;
			gboolean _tmp80_;
			gboolean _tmp81_;
			_tmp80_ = dc_message_get_full_message_expanded (msg);
			_tmp81_ = _tmp80_;
			if (_tmp81_) {
				_tmp79_ = "Collapse";
			} else {
				_tmp79_ = "Expand";
			}
			_tmp73_ = _tmp79_;
		}
		_tmp82_ = (GtkButton*) gtk_button_new_with_label (_tmp73_);
		g_object_ref_sink (_tmp82_);
		toggle_btn = _tmp82_;
		_tmp83_ = toggle_btn;
		gtk_widget_add_css_class ((GtkWidget*) _tmp83_, "flat");
		_tmp84_ = toggle_btn;
		gtk_widget_add_css_class ((GtkWidget*) _tmp84_, "message-full-text-button");
		_tmp85_ = toggle_btn;
		gtk_widget_set_halign ((GtkWidget*) _tmp85_, GTK_ALIGN_START);
		_tmp86_ = toggle_btn;
		gtk_widget_set_focus_on_click ((GtkWidget*) _tmp86_, FALSE);
		_tmp87_ = toggle_btn;
		g_signal_connect_object (_tmp87_, "clicked", (GCallback) dc_message_row_on_full_message_clicked, (GObject*) self, (GConnectFlags) 0);
		_tmp88_ = actions;
		_tmp89_ = toggle_btn;
		gtk_box_append (_tmp88_, (GtkWidget*) _tmp89_);
		_tmp90_ = dc_message_get_can_download_full_message (msg);
		_tmp91_ = _tmp90_;
		if (!_tmp91_) {
			GtkButton* view_btn = NULL;
			GtkButton* _tmp92_;
			GtkButton* _tmp93_;
			GtkButton* _tmp94_;
			GtkButton* _tmp95_;
			GtkButton* _tmp96_;
			GtkButton* _tmp97_;
			GtkButton* _tmp98_;
			GtkBox* _tmp99_;
			GtkButton* _tmp100_;
			_tmp92_ = (GtkButton*) gtk_button_new_with_label ("View full message");
			g_object_ref_sink (_tmp92_);
			view_btn = _tmp92_;
			_tmp93_ = view_btn;
			gtk_widget_add_css_class ((GtkWidget*) _tmp93_, "flat");
			_tmp94_ = view_btn;
			gtk_widget_add_css_class ((GtkWidget*) _tmp94_, "message-full-text-button");
			_tmp95_ = view_btn;
			gtk_widget_set_hexpand ((GtkWidget*) _tmp95_, TRUE);
			_tmp96_ = view_btn;
			gtk_widget_set_halign ((GtkWidget*) _tmp96_, GTK_ALIGN_END);
			_tmp97_ = view_btn;
			gtk_widget_set_focus_on_click ((GtkWidget*) _tmp97_, FALSE);
			_tmp98_ = view_btn;
			g_signal_connect_object (_tmp98_, "clicked", (GCallback) dc_message_row_on_full_message_view_clicked, (GObject*) self, (GConnectFlags) 0);
			_tmp99_ = actions;
			_tmp100_ = view_btn;
			gtk_box_append (_tmp99_, (GtkWidget*) _tmp100_);
			_g_object_unref0 (view_btn);
		}
		_tmp101_ = box;
		_tmp102_ = actions;
		gtk_box_append (_tmp101_, (GtkWidget*) _tmp102_);
		_g_object_unref0 (toggle_btn);
		_g_object_unref0 (actions);
	}
	result = (GtkWidget*) box;
	_g_object_unref0 (body);
	return result;
}

static void
dc_message_row_on_full_message_clicked (GtkButton* button,
                                        DcMessageRow* row)
{
	gint _tmp0_;
	g_return_if_fail (button != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = row->priv->_message_id;
	g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_FULL_MESSAGE_REQUESTED_SIGNAL], 0, _tmp0_);
}

static void
dc_message_row_on_full_message_view_clicked (GtkButton* button,
                                             DcMessageRow* row)
{
	gint _tmp0_;
	g_return_if_fail (button != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = row->priv->_message_id;
	g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_FULL_MESSAGE_VIEW_REQUESTED_SIGNAL], 0, _tmp0_);
}

static inline GRegex*
_thread_safe_regex_init (GRegex** re,
                         const gchar * pattern,
                         GRegexCompileFlags compile_flags)
{
	if (g_once_init_enter ((volatile gsize*) re)) {
		GRegex* val = g_regex_new (pattern, compile_flags, 0, NULL);
		g_once_init_leave ((volatile gsize*) re, (gsize) val);
	}
	return *re;
}

static GtkLabel*
dc_message_row_build_markup_label (const gchar* raw,
                                   gint max_width_chars,
                                   gint emoji_count,
                                   DcMentionRoster* roster)
{
	gchar* spread = NULL;
	gchar* _tmp0_;
	GtkLabel* text = NULL;
	const gchar* _tmp1_;
	GtkLabel* _tmp2_;
	GtkLabel* _tmp17_;
	GtkLabel* _tmp18_;
	GtkLabel* _tmp19_;
	GtkLabel* _tmp20_;
	GtkLabel* _tmp21_;
	GtkLabel* _tmp25_;
	GError* _inner_error0_ = NULL;
	GtkLabel* result;
	g_return_val_if_fail (raw != NULL, NULL);
	_tmp0_ = dc_message_row_spread_adjacent_emoji (raw);
	spread = _tmp0_;
	_tmp1_ = spread;
	_tmp2_ = (GtkLabel*) gtk_label_new (_tmp1_);
	g_object_ref_sink (_tmp2_);
	text = _tmp2_;
	{
		gchar* _tmp3_ = NULL;
		gchar* markup = NULL;
		gchar* _tmp8_;
		gchar* probe = NULL;
		const gchar* _tmp9_;
		gchar* _tmp10_;
		PangoAttrList* attrs = NULL;
		gchar* parsed = NULL;
		gunichar accel = 0U;
		const gchar* _tmp11_;
		PangoAttrList* _tmp12_ = NULL;
		gchar* _tmp13_ = NULL;
		gunichar _tmp14_ = 0U;
		GtkLabel* _tmp15_;
		const gchar* _tmp16_;
		if (roster != NULL) {
			const gchar* _tmp4_;
			gchar* _tmp5_;
			_tmp4_ = spread;
			_tmp5_ = dc_mentions_render_markup (_tmp4_, roster);
			_g_free0 (_tmp3_);
			_tmp3_ = _tmp5_;
		} else {
			const gchar* _tmp6_;
			gchar* _tmp7_;
			_tmp6_ = spread;
			_tmp7_ = dc_markdown_format (_tmp6_);
			_g_free0 (_tmp3_);
			_tmp3_ = _tmp7_;
		}
		_tmp8_ = _tmp3_;
		_tmp3_ = NULL;
		markup = _tmp8_;
		_tmp9_ = markup;
		_tmp10_ = g_regex_replace (_thread_safe_regex_init (&_tmp_regex_0, "<\\/?a(\\s[^>]*)?>", 0), _tmp9_, (gssize) -1, 0, "", 0, &_inner_error0_);
		probe = _tmp10_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (markup);
			_g_free0 (_tmp3_);
			goto __catch0_g_error;
		}
		_tmp11_ = probe;
		pango_parse_markup (_tmp11_, -1, (gunichar) 0, &_tmp12_, &_tmp13_, &_tmp14_, &_inner_error0_);
		_pango_attr_list_unref0 (attrs);
		attrs = _tmp12_;
		_g_free0 (parsed);
		parsed = _tmp13_;
		accel = _tmp14_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (parsed);
			_pango_attr_list_unref0 (attrs);
			_g_free0 (probe);
			_g_free0 (markup);
			_g_free0 (_tmp3_);
			goto __catch0_g_error;
		}
		_tmp15_ = text;
		_tmp16_ = markup;
		gtk_label_set_markup (_tmp15_, _tmp16_);
		_g_free0 (parsed);
		_pango_attr_list_unref0 (attrs);
		_g_free0 (probe);
		_g_free0 (markup);
		_g_free0 (_tmp3_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (text);
		_g_free0 (spread);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp17_ = text;
	gtk_label_set_wrap (_tmp17_, emoji_count == 0);
	_tmp18_ = text;
	gtk_label_set_wrap_mode (_tmp18_, PANGO_WRAP_WORD_CHAR);
	_tmp19_ = text;
	gtk_widget_set_halign ((GtkWidget*) _tmp19_, GTK_ALIGN_START);
	_tmp20_ = text;
	gtk_label_set_xalign (_tmp20_, (gfloat) 0);
	_tmp21_ = text;
	gtk_label_set_selectable (_tmp21_, TRUE);
	if (emoji_count == 1) {
		GtkLabel* _tmp22_;
		_tmp22_ = text;
		gtk_widget_add_css_class ((GtkWidget*) _tmp22_, "message-big-emoji");
	} else {
		if (emoji_count == 2) {
			GtkLabel* _tmp23_;
			_tmp23_ = text;
			gtk_widget_add_css_class ((GtkWidget*) _tmp23_, "message-medium-emoji");
		}
	}
	if (max_width_chars > 0) {
		GtkLabel* _tmp24_;
		_tmp24_ = text;
		gtk_label_set_max_width_chars (_tmp24_, max_width_chars);
	}
	_tmp25_ = text;
	dc_message_row_connect_label_links (_tmp25_);
	result = text;
	_g_free0 (spread);
	return result;
}

static void
dc_message_row_connect_label_links (GtkLabel* text)
{
	g_return_if_fail (text != NULL);
	g_signal_connect_object (text, "activate-link", (GCallback) dc_message_row_on_label_activate_link, (GObject*) text, (GConnectFlags) 0);
}

static gboolean
dc_message_row_on_label_activate_link (GtkLabel* sender,
                                       const gchar* uri,
                                       GtkLabel* text)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean result;
	g_return_val_if_fail (sender != NULL, FALSE);
	g_return_val_if_fail (uri != NULL, FALSE);
	g_return_val_if_fail (text != NULL, FALSE);
	if (g_str_has_prefix (uri, "parla-mention:")) {
		GtkRoot* _tmp1_;
		_tmp1_ = gtk_widget_get_root ((GtkWidget*) text);
		_tmp0_ = DC_IS_WINDOW (_tmp1_);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		GtkRoot* _tmp2_;
		_tmp2_ = gtk_widget_get_root ((GtkWidget*) text);
		dc_window_open_mention (G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, DC_TYPE_WINDOW, DcWindow), uri);
		result = TRUE;
		return result;
	}
	if (dc_is_delta_invite_uri (uri)) {
		GtkRoot* _tmp4_;
		_tmp4_ = gtk_widget_get_root ((GtkWidget*) text);
		_tmp3_ = DC_IS_WINDOW (_tmp4_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		GtkRoot* _tmp5_;
		_tmp5_ = gtk_widget_get_root ((GtkWidget*) text);
		dc_window_handle_invite_uri (G_TYPE_CHECK_INSTANCE_CAST (_tmp5_, DC_TYPE_WINDOW, DcWindow), uri);
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}

static GtkWidget*
dc_message_row_build_text_with_markdown_blocks (DcMessageRow* self,
                                                DcMessage* msg,
                                                gint max_width_chars)
{
	const gchar* _tmp0_ = NULL;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* raw = NULL;
	gchar* _tmp3_;
	gchar** lines = NULL;
	const gchar* _tmp4_;
	gchar** _tmp5_;
	gchar** _tmp6_;
	gint lines_length1;
	gint _lines_size_;
	GtkBox* body = NULL;
	GtkBox* _tmp7_;
	GtkBox* _tmp8_;
	GtkBox* _tmp9_;
	gboolean found_block = FALSE;
	gchar* open_fence = NULL;
	gint text_start = 0;
	GtkBox* _tmp46_;
	gchar** _tmp47_;
	gint _tmp47__length1;
	gchar** _tmp48_;
	gint _tmp48__length1;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_text (msg);
	_tmp2_ = _tmp1_;
	_tmp0_ = _tmp2_;
	if (_tmp0_ == NULL) {
		_tmp0_ = "";
	}
	_tmp3_ = g_strdup (_tmp0_);
	raw = _tmp3_;
	_tmp4_ = raw;
	_tmp6_ = _tmp5_ = g_strsplit (_tmp4_, "\n", 0);
	lines = _tmp6_;
	lines_length1 = _vala_array_length (_tmp5_);
	_lines_size_ = lines_length1;
	_tmp7_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
	g_object_ref_sink (_tmp7_);
	body = _tmp7_;
	_tmp8_ = body;
	gtk_widget_set_halign ((GtkWidget*) _tmp8_, GTK_ALIGN_FILL);
	_tmp9_ = body;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp9_, TRUE);
	found_block = FALSE;
	open_fence = NULL;
	text_start = 0;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp10_ = FALSE;
			_tmp10_ = TRUE;
			while (TRUE) {
				gchar** _tmp11_;
				gint _tmp11__length1;
				gchar* fence = NULL;
				gchar** _tmp12_;
				gint _tmp12__length1;
				const gchar* _tmp13_;
				gchar* _tmp14_;
				const gchar* _tmp15_;
				const gchar* _tmp19_;
				gint end = 0;
				DcMessageRowMarkdownTableBlock* table = NULL;
				gchar** _tmp23_;
				gint _tmp23__length1;
				gint _tmp24_ = 0;
				DcMessageRowMarkdownTableBlock* _tmp25_;
				DcMessageRowMarkdownTableBlock* _tmp26_;
				gboolean checked = FALSE;
				gint marker_start = 0;
				gint content_start = 0;
				gchar** _tmp33_;
				gint _tmp33__length1;
				const gchar* _tmp34_;
				gboolean _tmp35_ = FALSE;
				gint _tmp36_ = 0;
				gint _tmp37_ = 0;
				gboolean _tmp38_;
				gint _tmp45_;
				if (!_tmp10_) {
				}
				_tmp10_ = FALSE;
				_tmp11_ = lines;
				_tmp11__length1 = lines_length1;
				if (!(i < _tmp11__length1)) {
					break;
				}
				_tmp12_ = lines;
				_tmp12__length1 = lines_length1;
				_tmp13_ = _tmp12_[i];
				_tmp14_ = dc_message_row_code_fence_marker (_tmp13_);
				fence = _tmp14_;
				_tmp15_ = open_fence;
				if (_tmp15_ != NULL) {
					const gchar* _tmp16_;
					const gchar* _tmp17_;
					gint _tmp18_;
					_tmp16_ = fence;
					_tmp17_ = open_fence;
					if (g_strcmp0 (_tmp16_, _tmp17_) == 0) {
						_g_free0 (open_fence);
						open_fence = NULL;
					}
					_tmp18_ = i;
					i = _tmp18_ + 1;
					_g_free0 (fence);
					continue;
				}
				_tmp19_ = fence;
				if (_tmp19_ != NULL) {
					const gchar* _tmp20_;
					gchar* _tmp21_;
					gint _tmp22_;
					_tmp20_ = fence;
					_tmp21_ = g_strdup (_tmp20_);
					_g_free0 (open_fence);
					open_fence = _tmp21_;
					_tmp22_ = i;
					i = _tmp22_ + 1;
					_g_free0 (fence);
					continue;
				}
				_tmp23_ = lines;
				_tmp23__length1 = lines_length1;
				_tmp25_ = dc_message_row_parse_table_at (_tmp23_, (gint) _tmp23__length1, i, &_tmp24_);
				end = _tmp24_;
				table = _tmp25_;
				_tmp26_ = table;
				if (_tmp26_ != NULL) {
					GtkBox* _tmp27_;
					gchar** _tmp28_;
					gint _tmp28__length1;
					GtkBox* _tmp29_;
					DcMessageRowMarkdownTableBlock* _tmp30_;
					GtkWidget* _tmp31_;
					GtkWidget* _tmp32_;
					_tmp27_ = body;
					_tmp28_ = lines;
					_tmp28__length1 = lines_length1;
					dc_message_row_append_text_block (self, _tmp27_, _tmp28_, (gint) _tmp28__length1, text_start, i, max_width_chars);
					_tmp29_ = body;
					_tmp30_ = table;
					_tmp31_ = dc_message_row_build_table_grid (_tmp30_, max_width_chars);
					_tmp32_ = _tmp31_;
					gtk_box_append (_tmp29_, _tmp32_);
					_g_object_unref0 (_tmp32_);
					found_block = TRUE;
					i = end;
					text_start = i;
					_dc_message_row_markdown_table_block_unref0 (table);
					_g_free0 (fence);
					continue;
				}
				_tmp33_ = lines;
				_tmp33__length1 = lines_length1;
				_tmp34_ = _tmp33_[i];
				_tmp38_ = dc_markdown_parse_task_checkbox (_tmp34_, &_tmp35_, &_tmp36_, &_tmp37_);
				checked = _tmp35_;
				marker_start = _tmp36_;
				content_start = _tmp37_;
				if (_tmp38_) {
					GtkBox* _tmp39_;
					gchar** _tmp40_;
					gint _tmp40__length1;
					GtkBox* _tmp41_;
					GtkWidget* _tmp42_;
					GtkWidget* _tmp43_;
					gint _tmp44_;
					_tmp39_ = body;
					_tmp40_ = lines;
					_tmp40__length1 = lines_length1;
					dc_message_row_append_text_block (self, _tmp39_, _tmp40_, (gint) _tmp40__length1, text_start, i, max_width_chars);
					_tmp41_ = body;
					_tmp42_ = dc_message_row_build_task_line (self, msg, i, checked, content_start, max_width_chars);
					_tmp43_ = _tmp42_;
					gtk_box_append (_tmp41_, _tmp43_);
					_g_object_unref0 (_tmp43_);
					found_block = TRUE;
					_tmp44_ = i;
					i = _tmp44_ + 1;
					text_start = i;
					_dc_message_row_markdown_table_block_unref0 (table);
					_g_free0 (fence);
					continue;
				}
				_tmp45_ = i;
				i = _tmp45_ + 1;
				_dc_message_row_markdown_table_block_unref0 (table);
				_g_free0 (fence);
			}
		}
	}
	if (!found_block) {
		result = NULL;
		_g_free0 (open_fence);
		_g_object_unref0 (body);
		lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (raw);
		return result;
	}
	_tmp46_ = body;
	_tmp47_ = lines;
	_tmp47__length1 = lines_length1;
	_tmp48_ = lines;
	_tmp48__length1 = lines_length1;
	dc_message_row_append_text_block (self, _tmp46_, _tmp47_, (gint) _tmp47__length1, text_start, _tmp48__length1, max_width_chars);
	result = (GtkWidget*) body;
	_g_free0 (open_fence);
	lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (raw);
	return result;
}

static gchar*
string_strip (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strstrip (_result_);
	result = _result_;
	return result;
}

static gchar*
dc_message_row_code_fence_marker (const gchar* line)
{
	gchar* s = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (line != NULL, NULL);
	_tmp0_ = string_strip (line);
	s = _tmp0_;
	_tmp1_ = s;
	if (g_str_has_prefix (_tmp1_, "```")) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup ("```");
		result = _tmp2_;
		_g_free0 (s);
		return result;
	}
	_tmp3_ = s;
	if (g_str_has_prefix (_tmp3_, "~~~")) {
		gchar* _tmp4_;
		_tmp4_ = g_strdup ("~~~");
		result = _tmp4_;
		_g_free0 (s);
		return result;
	}
	result = NULL;
	_g_free0 (s);
	return result;
}

static void
dc_message_row_append_text_block (DcMessageRow* self,
                                  GtkBox* body,
                                  gchar** lines,
                                  gint lines_length1,
                                  gint start,
                                  gint end,
                                  gint max_width_chars)
{
	gchar* text = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	const gchar* _tmp7_;
	DcMentionRoster* _tmp8_;
	GtkLabel* _tmp9_;
	GtkLabel* _tmp10_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (body != NULL);
	_tmp0_ = dc_message_row_join_lines (lines, (gint) lines_length1, start, end);
	_tmp1_ = _tmp0_;
	_tmp2_ = string_strip (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	text = _tmp3_;
	_tmp4_ = text;
	_tmp5_ = strlen (_tmp4_);
	_tmp6_ = _tmp5_;
	if (_tmp6_ == 0) {
		_g_free0 (text);
		return;
	}
	_tmp7_ = text;
	_tmp8_ = self->priv->mention_roster;
	_tmp9_ = dc_message_row_build_markup_label (_tmp7_, max_width_chars, 0, _tmp8_);
	_tmp10_ = _tmp9_;
	gtk_box_append (body, (GtkWidget*) _tmp10_);
	_g_object_unref0 (_tmp10_);
	_g_free0 (text);
}

static gchar*
dc_message_row_join_lines (gchar** lines,
                           gint lines_length1,
                           gint start,
                           gint end)
{
	GString* sb = NULL;
	GString* _tmp0_;
	GString* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	_tmp0_ = g_string_new ("");
	sb = _tmp0_;
	{
		gint i = 0;
		i = start;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				GString* _tmp4_;
				const gchar* _tmp5_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(i < end)) {
					break;
				}
				if (i > start) {
					GString* _tmp3_;
					_tmp3_ = sb;
					g_string_append_c (_tmp3_, '\n');
				}
				_tmp4_ = sb;
				_tmp5_ = lines[i];
				g_string_append (_tmp4_, _tmp5_);
			}
		}
	}
	_tmp6_ = sb;
	_tmp7_ = _tmp6_->str;
	_tmp8_ = g_strdup (_tmp7_);
	result = _tmp8_;
	_g_string_free0 (sb);
	return result;
}

static GtkWidget*
dc_message_row_build_task_line (DcMessageRow* self,
                                DcMessage* msg,
                                gint line_index,
                                gboolean checked,
                                gint content_start,
                                gint max_width_chars)
{
	GtkBox* row = NULL;
	GtkBox* _tmp0_;
	GtkBox* _tmp1_;
	GtkBox* _tmp2_;
	GtkBox* _tmp3_;
	const gchar* _tmp4_ = NULL;
	gchar* glyph = NULL;
	gchar* _tmp5_;
	gboolean _tmp6_;
	gboolean _tmp7_;
	const gchar* _tmp32_ = NULL;
	const gchar* _tmp33_;
	const gchar* _tmp34_;
	gchar* line = NULL;
	gchar** _tmp35_;
	gchar** _tmp36_;
	gchar** _tmp37_;
	gint _tmp37__length1;
	const gchar* _tmp38_;
	gchar* _tmp39_;
	gchar* _tmp40_;
	gchar* _tmp41_ = NULL;
	const gchar* _tmp42_;
	gint _tmp43_;
	gint _tmp44_;
	gchar* content = NULL;
	gchar* _tmp48_;
	gint _tmp49_ = 0;
	gint label_width = 0;
	GtkLabel* label = NULL;
	const gchar* _tmp50_;
	DcMentionRoster* _tmp51_;
	GtkLabel* _tmp52_;
	GtkBox* _tmp53_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp0_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
	g_object_ref_sink (_tmp0_);
	row = _tmp0_;
	_tmp1_ = row;
	gtk_widget_add_css_class ((GtkWidget*) _tmp1_, "markdown-task-line");
	_tmp2_ = row;
	gtk_widget_set_halign ((GtkWidget*) _tmp2_, GTK_ALIGN_FILL);
	_tmp3_ = row;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp3_, TRUE);
	if (checked) {
		_tmp4_ = "✅";
	} else {
		_tmp4_ = "⬜";
	}
	_tmp5_ = g_strdup (_tmp4_);
	glyph = _tmp5_;
	_tmp6_ = dc_message_get_can_edit_text (msg);
	_tmp7_ = _tmp6_;
	if (_tmp7_) {
		GtkButton* toggle = NULL;
		const gchar* _tmp8_;
		GtkButton* _tmp9_;
		GtkButton* _tmp10_;
		GtkButton* _tmp11_;
		GtkButton* _tmp12_;
		const gchar* _tmp13_ = NULL;
		GtkButton* _tmp14_;
		const gchar* _tmp15_ = NULL;
		const gchar* _tmp16_;
		const gchar* _tmp17_;
		gchar* raw = NULL;
		gchar* _tmp18_;
		gint idx = 0;
		GtkButton* _tmp19_;
		const gchar* _tmp20_;
		gchar* _tmp21_;
		GtkButton* _tmp22_;
		GtkButton* _tmp23_;
		GtkBox* _tmp24_;
		GtkButton* _tmp25_;
		_tmp8_ = glyph;
		_tmp9_ = (GtkButton*) gtk_button_new_with_label (_tmp8_);
		g_object_ref_sink (_tmp9_);
		toggle = _tmp9_;
		_tmp10_ = toggle;
		gtk_widget_add_css_class ((GtkWidget*) _tmp10_, "flat");
		_tmp11_ = toggle;
		gtk_widget_add_css_class ((GtkWidget*) _tmp11_, "markdown-task-toggle");
		_tmp12_ = toggle;
		gtk_widget_set_valign ((GtkWidget*) _tmp12_, GTK_ALIGN_START);
		if (checked) {
			_tmp13_ = "Mark unchecked";
		} else {
			_tmp13_ = "Mark checked";
		}
		_tmp14_ = toggle;
		gtk_widget_set_tooltip_text ((GtkWidget*) _tmp14_, _tmp13_);
		_tmp16_ = dc_message_get_text (msg);
		_tmp17_ = _tmp16_;
		_tmp15_ = _tmp17_;
		if (_tmp15_ == NULL) {
			_tmp15_ = "";
		}
		_tmp18_ = g_strdup (_tmp15_);
		raw = _tmp18_;
		idx = line_index;
		_tmp19_ = toggle;
		_tmp20_ = raw;
		_tmp21_ = g_strdup (_tmp20_);
		g_object_set_data_full ((GObject*) _tmp19_, DC_MESSAGE_ROW_TASK_RAW_DATA, _tmp21_, g_free);
		_tmp22_ = toggle;
		g_object_set_data_full ((GObject*) _tmp22_, DC_MESSAGE_ROW_TASK_INDEX_DATA, (gpointer) ((gintptr) idx), NULL);
		_tmp23_ = toggle;
		g_signal_connect_object (_tmp23_, "clicked", (GCallback) dc_message_row_on_task_toggle_clicked, (GObject*) self, (GConnectFlags) 0);
		_tmp24_ = row;
		_tmp25_ = toggle;
		gtk_box_append (_tmp24_, (GtkWidget*) _tmp25_);
		_g_free0 (raw);
		_g_object_unref0 (toggle);
	} else {
		GtkLabel* mark = NULL;
		const gchar* _tmp26_;
		GtkLabel* _tmp27_;
		GtkLabel* _tmp28_;
		GtkLabel* _tmp29_;
		GtkBox* _tmp30_;
		GtkLabel* _tmp31_;
		_tmp26_ = glyph;
		_tmp27_ = (GtkLabel*) gtk_label_new (_tmp26_);
		g_object_ref_sink (_tmp27_);
		mark = _tmp27_;
		_tmp28_ = mark;
		gtk_widget_add_css_class ((GtkWidget*) _tmp28_, "markdown-task-glyph");
		_tmp29_ = mark;
		gtk_widget_set_valign ((GtkWidget*) _tmp29_, GTK_ALIGN_START);
		_tmp30_ = row;
		_tmp31_ = mark;
		gtk_box_append (_tmp30_, (GtkWidget*) _tmp31_);
		_g_object_unref0 (mark);
	}
	_tmp33_ = dc_message_get_text (msg);
	_tmp34_ = _tmp33_;
	_tmp32_ = _tmp34_;
	if (_tmp32_ == NULL) {
		_tmp32_ = "";
	}
	_tmp36_ = _tmp35_ = g_strsplit (_tmp32_, "\n", 0);
	_tmp37_ = _tmp36_;
	_tmp37__length1 = _vala_array_length (_tmp35_);
	_tmp38_ = _tmp37_[line_index];
	_tmp39_ = g_strdup (_tmp38_);
	_tmp40_ = _tmp39_;
	_tmp37_ = (_vala_array_free (_tmp37_, _tmp37__length1, (GDestroyNotify) g_free), NULL);
	line = _tmp40_;
	_tmp42_ = line;
	_tmp43_ = strlen (_tmp42_);
	_tmp44_ = _tmp43_;
	if (content_start < _tmp44_) {
		const gchar* _tmp45_;
		gchar* _tmp46_;
		_tmp45_ = line;
		_tmp46_ = string_substring (_tmp45_, (glong) content_start, (glong) -1);
		_g_free0 (_tmp41_);
		_tmp41_ = _tmp46_;
	} else {
		gchar* _tmp47_;
		_tmp47_ = g_strdup ("");
		_g_free0 (_tmp41_);
		_tmp41_ = _tmp47_;
	}
	_tmp48_ = _tmp41_;
	_tmp41_ = NULL;
	content = _tmp48_;
	if (max_width_chars > 0) {
		_tmp49_ = MAX (1, max_width_chars - 4);
	} else {
		_tmp49_ = max_width_chars;
	}
	label_width = _tmp49_;
	_tmp50_ = content;
	_tmp51_ = self->priv->mention_roster;
	_tmp52_ = dc_message_row_build_markup_label (_tmp50_, label_width, 0, _tmp51_);
	label = _tmp52_;
	gtk_widget_set_valign ((GtkWidget*) label, GTK_ALIGN_START);
	gtk_widget_set_hexpand ((GtkWidget*) label, TRUE);
	_tmp53_ = row;
	gtk_box_append (_tmp53_, (GtkWidget*) label);
	result = (GtkWidget*) row;
	_g_object_unref0 (label);
	_g_free0 (content);
	_g_free0 (_tmp41_);
	_g_free0 (line);
	_g_free0 (glyph);
	return result;
}

static void
dc_message_row_on_task_toggle_clicked (GtkButton* button,
                                       DcMessageRow* row)
{
	gchar* raw = NULL;
	gconstpointer _tmp0_;
	gchar* _tmp1_;
	gint index = 0;
	gconstpointer _tmp2_;
	const gchar* _tmp3_;
	gchar* new_text = NULL;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	const gchar* _tmp6_;
	gint _tmp7_;
	const gchar* _tmp8_;
	g_return_if_fail (button != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = g_object_get_data ((GObject*) button, DC_MESSAGE_ROW_TASK_RAW_DATA);
	_tmp1_ = g_strdup ((const gchar*) _tmp0_);
	raw = _tmp1_;
	_tmp2_ = g_object_get_data ((GObject*) button, DC_MESSAGE_ROW_TASK_INDEX_DATA);
	index = (gint) ((gintptr) _tmp2_);
	_tmp3_ = raw;
	if (_tmp3_ == NULL) {
		_g_free0 (raw);
		return;
	}
	_tmp4_ = raw;
	_tmp5_ = dc_message_row_toggled_task_text (_tmp4_, index);
	new_text = _tmp5_;
	_tmp6_ = new_text;
	if (_tmp6_ == NULL) {
		_g_free0 (new_text);
		_g_free0 (raw);
		return;
	}
	gtk_widget_set_sensitive ((GtkWidget*) button, FALSE);
	_tmp7_ = row->priv->_message_id;
	_tmp8_ = new_text;
	g_signal_emit (row, dc_message_row_signals[DC_MESSAGE_ROW_CHECKBOX_TOGGLE_REQUESTED_SIGNAL], 0, _tmp7_, _tmp8_);
	_g_free0 (new_text);
	_g_free0 (raw);
}

static gchar*
dc_message_row_toggled_task_text (const gchar* raw,
                                  gint line_index)
{
	gchar** lines = NULL;
	gchar** _tmp0_;
	gchar** _tmp1_;
	gint lines_length1;
	gint _lines_size_;
	gboolean _tmp2_ = FALSE;
	gboolean checked = FALSE;
	gint marker_start = 0;
	gint content_start = 0;
	gchar** _tmp4_;
	gint _tmp4__length1;
	const gchar* _tmp5_;
	gboolean _tmp6_ = FALSE;
	gint _tmp7_ = 0;
	gint _tmp8_ = 0;
	gboolean _tmp9_;
	gchar* line = NULL;
	gchar** _tmp10_;
	gint _tmp10__length1;
	const gchar* _tmp11_;
	gchar* _tmp12_;
	const gchar* _tmp13_ = NULL;
	gchar* replacement = NULL;
	gchar* _tmp14_;
	gchar** _tmp15_;
	gint _tmp15__length1;
	const gchar* _tmp16_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	const gchar* _tmp19_;
	gchar* _tmp20_;
	gchar* _tmp21_;
	const gchar* _tmp22_;
	gchar* _tmp23_;
	gchar* _tmp24_;
	gchar* _tmp25_;
	gchar** _tmp26_;
	gint _tmp26__length1;
	gchar** _tmp27_;
	gint _tmp27__length1;
	gchar* _tmp28_;
	gchar* result;
	g_return_val_if_fail (raw != NULL, NULL);
	_tmp1_ = _tmp0_ = g_strsplit (raw, "\n", 0);
	lines = _tmp1_;
	lines_length1 = _vala_array_length (_tmp0_);
	_lines_size_ = lines_length1;
	if (line_index < 0) {
		_tmp2_ = TRUE;
	} else {
		gchar** _tmp3_;
		gint _tmp3__length1;
		_tmp3_ = lines;
		_tmp3__length1 = lines_length1;
		_tmp2_ = line_index >= _tmp3__length1;
	}
	if (_tmp2_) {
		result = NULL;
		lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
		return result;
	}
	_tmp4_ = lines;
	_tmp4__length1 = lines_length1;
	_tmp5_ = _tmp4_[line_index];
	_tmp9_ = dc_markdown_parse_task_checkbox (_tmp5_, &_tmp6_, &_tmp7_, &_tmp8_);
	checked = _tmp6_;
	marker_start = _tmp7_;
	content_start = _tmp8_;
	if (!_tmp9_) {
		result = NULL;
		lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
		return result;
	}
	_tmp10_ = lines;
	_tmp10__length1 = lines_length1;
	_tmp11_ = _tmp10_[line_index];
	_tmp12_ = g_strdup (_tmp11_);
	line = _tmp12_;
	if (checked) {
		_tmp13_ = "[ ]";
	} else {
		_tmp13_ = "[x]";
	}
	_tmp14_ = g_strdup (_tmp13_);
	replacement = _tmp14_;
	_tmp15_ = lines;
	_tmp15__length1 = lines_length1;
	_tmp16_ = line;
	_tmp17_ = string_substring (_tmp16_, (glong) 0, (glong) marker_start);
	_tmp18_ = _tmp17_;
	_tmp19_ = replacement;
	_tmp20_ = g_strconcat (_tmp18_, _tmp19_, NULL);
	_tmp21_ = _tmp20_;
	_tmp22_ = line;
	_tmp23_ = string_substring (_tmp22_, (glong) (marker_start + 3), (glong) -1);
	_tmp24_ = _tmp23_;
	_tmp25_ = g_strconcat (_tmp21_, _tmp24_, NULL);
	_g_free0 (_tmp15_[line_index]);
	_tmp15_[line_index] = _tmp25_;
	_g_free0 (_tmp24_);
	_g_free0 (_tmp21_);
	_g_free0 (_tmp18_);
	_tmp26_ = lines;
	_tmp26__length1 = lines_length1;
	_tmp27_ = lines;
	_tmp27__length1 = lines_length1;
	_tmp28_ = dc_message_row_join_lines (_tmp26_, (gint) _tmp26__length1, 0, _tmp27__length1);
	result = _tmp28_;
	_g_free0 (replacement);
	_g_free0 (line);
	lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
	return result;
}

static DcMessageRowMarkdownTableBlock*
dc_message_row_parse_table_at (gchar** lines,
                               gint lines_length1,
                               gint start,
                               gint* end)
{
	gint _vala_end = 0;
	gchar** header = NULL;
	const gchar* _tmp0_;
	gint _tmp1_ = 0;
	gchar** _tmp2_;
	gint header_length1;
	gint _header_size_;
	gchar** separator = NULL;
	const gchar* _tmp3_;
	gint _tmp4_ = 0;
	gchar** _tmp5_;
	gint separator_length1;
	gint _separator_size_;
	gboolean _tmp6_ = FALSE;
	gchar** _tmp7_;
	gint _tmp7__length1;
	gboolean _tmp9_ = FALSE;
	gchar** _tmp10_;
	gint _tmp10__length1;
	gchar** _tmp13_;
	gint _tmp13__length1;
	DcMessageRowMarkdownTableBlock* table = NULL;
	gchar** _tmp14_;
	gint _tmp14__length1;
	DcMessageRowMarkdownTableBlock* _tmp15_;
	DcMessageRowMarkdownTableBlock* _tmp23_;
	GPtrArray* _tmp24_;
	gchar** _tmp25_;
	gint _tmp25__length1;
	DcMessageRowMarkdownTableRow* _tmp26_;
	DcMessageRowMarkdownTableBlock* result;
	_vala_end = start;
	if ((start + 1) >= lines_length1) {
		result = NULL;
		if (end) {
			*end = _vala_end;
		}
		return result;
	}
	_tmp0_ = lines[start];
	_tmp2_ = dc_message_row_parse_table_row (_tmp0_, &_tmp1_);
	header = _tmp2_;
	header_length1 = _tmp1_;
	_header_size_ = header_length1;
	_tmp3_ = lines[start + 1];
	_tmp5_ = dc_message_row_parse_table_row (_tmp3_, &_tmp4_);
	separator = _tmp5_;
	separator_length1 = _tmp4_;
	_separator_size_ = separator_length1;
	_tmp7_ = header;
	_tmp7__length1 = header_length1;
	if (_tmp7_ == NULL) {
		_tmp6_ = TRUE;
	} else {
		gchar** _tmp8_;
		gint _tmp8__length1;
		_tmp8_ = separator;
		_tmp8__length1 = separator_length1;
		_tmp6_ = _tmp8_ == NULL;
	}
	if (_tmp6_) {
		result = NULL;
		separator = (_vala_array_free (separator, separator_length1, (GDestroyNotify) g_free), NULL);
		header = (_vala_array_free (header, header_length1, (GDestroyNotify) g_free), NULL);
		if (end) {
			*end = _vala_end;
		}
		return result;
	}
	_tmp10_ = header;
	_tmp10__length1 = header_length1;
	if (_tmp10__length1 < 2) {
		_tmp9_ = TRUE;
	} else {
		gchar** _tmp11_;
		gint _tmp11__length1;
		gchar** _tmp12_;
		gint _tmp12__length1;
		_tmp11_ = header;
		_tmp11__length1 = header_length1;
		_tmp12_ = separator;
		_tmp12__length1 = separator_length1;
		_tmp9_ = _tmp11__length1 != _tmp12__length1;
	}
	if (_tmp9_) {
		result = NULL;
		separator = (_vala_array_free (separator, separator_length1, (GDestroyNotify) g_free), NULL);
		header = (_vala_array_free (header, header_length1, (GDestroyNotify) g_free), NULL);
		if (end) {
			*end = _vala_end;
		}
		return result;
	}
	_tmp13_ = separator;
	_tmp13__length1 = separator_length1;
	if (!dc_message_row_is_table_separator (_tmp13_, (gint) _tmp13__length1)) {
		result = NULL;
		separator = (_vala_array_free (separator, separator_length1, (GDestroyNotify) g_free), NULL);
		header = (_vala_array_free (header, header_length1, (GDestroyNotify) g_free), NULL);
		if (end) {
			*end = _vala_end;
		}
		return result;
	}
	_tmp14_ = header;
	_tmp14__length1 = header_length1;
	_tmp15_ = dc_message_row_markdown_table_block_new (_tmp14__length1);
	table = _tmp15_;
	{
		gint c = 0;
		c = 0;
		{
			gboolean _tmp16_ = FALSE;
			_tmp16_ = TRUE;
			while (TRUE) {
				gchar** _tmp18_;
				gint _tmp18__length1;
				DcMessageRowMarkdownTableBlock* _tmp19_;
				gint* _tmp20_;
				gint _tmp20__length1;
				gchar** _tmp21_;
				gint _tmp21__length1;
				const gchar* _tmp22_;
				if (!_tmp16_) {
					gint _tmp17_;
					_tmp17_ = c;
					c = _tmp17_ + 1;
				}
				_tmp16_ = FALSE;
				_tmp18_ = header;
				_tmp18__length1 = header_length1;
				if (!(c < _tmp18__length1)) {
					break;
				}
				_tmp19_ = table;
				_tmp20_ = _tmp19_->aligns;
				_tmp20__length1 = _tmp19_->aligns_length1;
				_tmp21_ = separator;
				_tmp21__length1 = separator_length1;
				_tmp22_ = _tmp21_[c];
				_tmp20_[c] = dc_message_row_table_separator_align (_tmp22_);
			}
		}
	}
	_tmp23_ = table;
	_tmp24_ = _tmp23_->rows;
	_tmp25_ = header;
	_tmp25__length1 = header_length1;
	_tmp26_ = dc_message_row_markdown_table_row_new (_tmp25_, _tmp25__length1, TRUE);
	g_ptr_array_add (_tmp24_, _tmp26_);
	_vala_end = start + 2;
	while (TRUE) {
		gchar* line = NULL;
		const gchar* _tmp27_;
		gchar* _tmp28_;
		const gchar* _tmp29_;
		gchar* _tmp30_;
		gchar* _tmp31_;
		gint _tmp32_;
		gint _tmp33_;
		gboolean _tmp34_;
		gchar** cells = NULL;
		const gchar* _tmp35_;
		gint _tmp36_ = 0;
		gchar** _tmp37_;
		gint cells_length1;
		gint _cells_size_;
		gboolean _tmp38_ = FALSE;
		gchar** _tmp39_;
		gint _tmp39__length1;
		DcMessageRowMarkdownTableBlock* _tmp42_;
		GPtrArray* _tmp43_;
		gchar** _tmp44_;
		gint _tmp44__length1;
		DcMessageRowMarkdownTableRow* _tmp45_;
		gint _tmp46_;
		if (!(_vala_end < lines_length1)) {
			break;
		}
		_tmp27_ = lines[_vala_end];
		_tmp28_ = g_strdup (_tmp27_);
		line = _tmp28_;
		_tmp29_ = line;
		_tmp30_ = string_strip (_tmp29_);
		_tmp31_ = _tmp30_;
		_tmp32_ = strlen (_tmp31_);
		_tmp33_ = _tmp32_;
		_tmp34_ = _tmp33_ == 0;
		_g_free0 (_tmp31_);
		if (_tmp34_) {
			_g_free0 (line);
			break;
		}
		_tmp35_ = line;
		_tmp37_ = dc_message_row_parse_table_row (_tmp35_, &_tmp36_);
		cells = _tmp37_;
		cells_length1 = _tmp36_;
		_cells_size_ = cells_length1;
		_tmp39_ = cells;
		_tmp39__length1 = cells_length1;
		if (_tmp39_ == NULL) {
			_tmp38_ = TRUE;
		} else {
			gchar** _tmp40_;
			gint _tmp40__length1;
			gchar** _tmp41_;
			gint _tmp41__length1;
			_tmp40_ = cells;
			_tmp40__length1 = cells_length1;
			_tmp41_ = header;
			_tmp41__length1 = header_length1;
			_tmp38_ = _tmp40__length1 != _tmp41__length1;
		}
		if (_tmp38_) {
			cells = (_vala_array_free (cells, cells_length1, (GDestroyNotify) g_free), NULL);
			_g_free0 (line);
			break;
		}
		_tmp42_ = table;
		_tmp43_ = _tmp42_->rows;
		_tmp44_ = cells;
		_tmp44__length1 = cells_length1;
		_tmp45_ = dc_message_row_markdown_table_row_new (_tmp44_, _tmp44__length1, FALSE);
		g_ptr_array_add (_tmp43_, _tmp45_);
		_tmp46_ = _vala_end;
		_vala_end = _tmp46_ + 1;
		cells = (_vala_array_free (cells, cells_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (line);
	}
	result = table;
	separator = (_vala_array_free (separator, separator_length1, (GDestroyNotify) g_free), NULL);
	header = (_vala_array_free (header, header_length1, (GDestroyNotify) g_free), NULL);
	if (end) {
		*end = _vala_end;
	}
	return result;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static gchar**
dc_message_row_parse_table_row (const gchar* line,
                                gint* result_length1)
{
	gchar* trimmed = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* inner = NULL;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	const gchar* _tmp5_;
	gboolean _tmp8_ = FALSE;
	const gchar* _tmp9_;
	gchar** raw = NULL;
	const gchar* _tmp18_;
	gchar** _tmp19_;
	gchar** _tmp20_;
	gint raw_length1;
	gint _raw_size_;
	gchar** _tmp21_;
	gint _tmp21__length1;
	gchar** cells = NULL;
	gchar** _tmp23_;
	gint _tmp23__length1;
	gchar** _tmp24_;
	gint cells_length1;
	gint _cells_size_;
	gchar** _tmp32_;
	gint _tmp32__length1;
	gchar** result;
	g_return_val_if_fail (line != NULL, NULL);
	_tmp0_ = string_strip (line);
	trimmed = _tmp0_;
	_tmp1_ = trimmed;
	if (!string_contains (_tmp1_, "|")) {
		gchar** _tmp2_;
		gint _tmp2__length1;
		_tmp2_ = NULL;
		_tmp2__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp2__length1;
		}
		result = _tmp2_;
		_g_free0 (trimmed);
		return result;
	}
	_tmp3_ = trimmed;
	_tmp4_ = g_strdup (_tmp3_);
	inner = _tmp4_;
	_tmp5_ = inner;
	if (g_str_has_prefix (_tmp5_, "|")) {
		const gchar* _tmp6_;
		gchar* _tmp7_;
		_tmp6_ = inner;
		_tmp7_ = string_substring (_tmp6_, (glong) 1, (glong) -1);
		_g_free0 (inner);
		inner = _tmp7_;
	}
	_tmp9_ = inner;
	if (g_str_has_suffix (_tmp9_, "|")) {
		const gchar* _tmp10_;
		gint _tmp11_;
		gint _tmp12_;
		_tmp10_ = inner;
		_tmp11_ = strlen (_tmp10_);
		_tmp12_ = _tmp11_;
		_tmp8_ = _tmp12_ > 0;
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		const gchar* _tmp13_;
		const gchar* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		gchar* _tmp17_;
		_tmp13_ = inner;
		_tmp14_ = inner;
		_tmp15_ = strlen (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp17_ = string_substring (_tmp13_, (glong) 0, (glong) (_tmp16_ - 1));
		_g_free0 (inner);
		inner = _tmp17_;
	}
	_tmp18_ = inner;
	_tmp20_ = _tmp19_ = g_strsplit (_tmp18_, "|", 0);
	raw = _tmp20_;
	raw_length1 = _vala_array_length (_tmp19_);
	_raw_size_ = raw_length1;
	_tmp21_ = raw;
	_tmp21__length1 = raw_length1;
	if (_tmp21__length1 < 2) {
		gchar** _tmp22_;
		gint _tmp22__length1;
		_tmp22_ = NULL;
		_tmp22__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp22__length1;
		}
		result = _tmp22_;
		raw = (_vala_array_free (raw, raw_length1, (GDestroyNotify) g_free), NULL);
		_g_free0 (inner);
		_g_free0 (trimmed);
		return result;
	}
	_tmp23_ = raw;
	_tmp23__length1 = raw_length1;
	_tmp24_ = g_new0 (gchar*, _tmp23__length1 + 1);
	cells = _tmp24_;
	cells_length1 = _tmp23__length1;
	_cells_size_ = cells_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp25_ = FALSE;
			_tmp25_ = TRUE;
			while (TRUE) {
				gchar** _tmp27_;
				gint _tmp27__length1;
				gchar** _tmp28_;
				gint _tmp28__length1;
				gchar** _tmp29_;
				gint _tmp29__length1;
				const gchar* _tmp30_;
				gchar* _tmp31_;
				if (!_tmp25_) {
					gint _tmp26_;
					_tmp26_ = i;
					i = _tmp26_ + 1;
				}
				_tmp25_ = FALSE;
				_tmp27_ = raw;
				_tmp27__length1 = raw_length1;
				if (!(i < _tmp27__length1)) {
					break;
				}
				_tmp28_ = cells;
				_tmp28__length1 = cells_length1;
				_tmp29_ = raw;
				_tmp29__length1 = raw_length1;
				_tmp30_ = _tmp29_[i];
				_tmp31_ = string_strip (_tmp30_);
				_g_free0 (_tmp28_[i]);
				_tmp28_[i] = _tmp31_;
			}
		}
	}
	_tmp32_ = cells;
	_tmp32__length1 = cells_length1;
	if (result_length1) {
		*result_length1 = _tmp32__length1;
	}
	result = _tmp32_;
	raw = (_vala_array_free (raw, raw_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (inner);
	_g_free0 (trimmed);
	return result;
}

static gchar
string_get (const gchar* self,
            glong index)
{
	gchar _tmp0_;
	gchar result;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = ((gchar*) self)[index];
	result = _tmp0_;
	return result;
}

static gboolean
dc_message_row_is_table_separator (gchar** cells,
                                   gint cells_length1)
{
	gboolean result;
	{
		gchar** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint _cell_collection_size_ = 0;
		gint cell_it = 0;
		cell_collection = cells;
		cell_collection_length1 = cells_length1;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			gchar* _tmp0_;
			gchar* cell = NULL;
			_tmp0_ = g_strdup (cell_collection[cell_it]);
			cell = _tmp0_;
			{
				gchar* s = NULL;
				const gchar* _tmp1_;
				gchar* _tmp2_;
				gint _tmp3_ = 0;
				const gchar* _tmp4_;
				gint start = 0;
				gint _tmp5_ = 0;
				const gchar* _tmp6_;
				gint end = 0;
				_tmp1_ = cell;
				_tmp2_ = string_strip (_tmp1_);
				s = _tmp2_;
				_tmp4_ = s;
				if (g_str_has_prefix (_tmp4_, ":")) {
					_tmp3_ = 1;
				} else {
					_tmp3_ = 0;
				}
				start = _tmp3_;
				_tmp6_ = s;
				if (g_str_has_suffix (_tmp6_, ":")) {
					const gchar* _tmp7_;
					gint _tmp8_;
					gint _tmp9_;
					_tmp7_ = s;
					_tmp8_ = strlen (_tmp7_);
					_tmp9_ = _tmp8_;
					_tmp5_ = _tmp9_ - 1;
				} else {
					const gchar* _tmp10_;
					gint _tmp11_;
					gint _tmp12_;
					_tmp10_ = s;
					_tmp11_ = strlen (_tmp10_);
					_tmp12_ = _tmp11_;
					_tmp5_ = _tmp12_;
				}
				end = _tmp5_;
				if ((end - start) < 3) {
					result = FALSE;
					_g_free0 (s);
					_g_free0 (cell);
					return result;
				}
				{
					gint i = 0;
					i = start;
					{
						gboolean _tmp13_ = FALSE;
						_tmp13_ = TRUE;
						while (TRUE) {
							const gchar* _tmp15_;
							if (!_tmp13_) {
								gint _tmp14_;
								_tmp14_ = i;
								i = _tmp14_ + 1;
							}
							_tmp13_ = FALSE;
							if (!(i < end)) {
								break;
							}
							_tmp15_ = s;
							if (string_get (_tmp15_, (glong) i) != '-') {
								result = FALSE;
								_g_free0 (s);
								_g_free0 (cell);
								return result;
							}
						}
					}
				}
				_g_free0 (s);
				_g_free0 (cell);
			}
		}
	}
	result = TRUE;
	return result;
}

static gint
dc_message_row_table_separator_align (const gchar* cell)
{
	gchar* s = NULL;
	gchar* _tmp0_;
	gboolean left = FALSE;
	const gchar* _tmp1_;
	gboolean right = FALSE;
	const gchar* _tmp2_;
	gboolean _tmp3_ = FALSE;
	gint result;
	g_return_val_if_fail (cell != NULL, -1);
	_tmp0_ = string_strip (cell);
	s = _tmp0_;
	_tmp1_ = s;
	left = g_str_has_prefix (_tmp1_, ":");
	_tmp2_ = s;
	right = g_str_has_suffix (_tmp2_, ":");
	if (left) {
		_tmp3_ = right;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		result = DC_MESSAGE_ROW_ALIGN_CENTER;
		_g_free0 (s);
		return result;
	}
	if (right) {
		result = DC_MESSAGE_ROW_ALIGN_RIGHT;
		_g_free0 (s);
		return result;
	}
	result = DC_MESSAGE_ROW_ALIGN_LEFT;
	_g_free0 (s);
	return result;
}

static gpointer
_dc_message_row_markdown_table_row_ref0 (gpointer self)
{
	return self ? dc_message_row_markdown_table_row_ref (self) : NULL;
}

static GtkWidget*
dc_message_row_build_table_grid (DcMessageRowMarkdownTableBlock* table,
                                 gint max_width_chars)
{
	GtkGrid* grid = NULL;
	GtkGrid* _tmp0_;
	GtkGrid* _tmp1_;
	GtkGrid* _tmp2_;
	GtkGrid* _tmp3_;
	GtkGrid* _tmp4_;
	GtkGrid* _tmp5_;
	gint columns = 0;
	gint* _tmp6_;
	gint _tmp6__length1;
	gint cell_width = 0;
	GtkWidget* result;
	g_return_val_if_fail (table != NULL, NULL);
	_tmp0_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp0_);
	grid = _tmp0_;
	_tmp1_ = grid;
	gtk_widget_add_css_class ((GtkWidget*) _tmp1_, "markdown-table");
	_tmp2_ = grid;
	gtk_widget_set_halign ((GtkWidget*) _tmp2_, GTK_ALIGN_FILL);
	_tmp3_ = grid;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp3_, TRUE);
	_tmp4_ = grid;
	gtk_grid_set_column_spacing (_tmp4_, 0);
	_tmp5_ = grid;
	gtk_grid_set_row_spacing (_tmp5_, 0);
	_tmp6_ = table->aligns;
	_tmp6__length1 = table->aligns_length1;
	columns = _tmp6__length1;
	cell_width = dc_message_row_table_cell_width_chars (columns, max_width_chars);
	{
		gint r = 0;
		r = 0;
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				GPtrArray* _tmp9_;
				gint _tmp10_;
				gint _tmp11_;
				DcMessageRowMarkdownTableRow* row = NULL;
				GPtrArray* _tmp12_;
				gconstpointer _tmp13_;
				DcMessageRowMarkdownTableRow* _tmp14_;
				if (!_tmp7_) {
					gint _tmp8_;
					_tmp8_ = r;
					r = _tmp8_ + 1;
				}
				_tmp7_ = FALSE;
				_tmp9_ = table->rows;
				_tmp10_ = vala_g_ptr_array_get_length (_tmp9_);
				_tmp11_ = _tmp10_;
				if (!(r < _tmp11_)) {
					break;
				}
				_tmp12_ = table->rows;
				_tmp13_ = g_ptr_array_index (_tmp12_, (guint) r);
				_tmp14_ = _dc_message_row_markdown_table_row_ref0 ((DcMessageRowMarkdownTableRow*) _tmp13_);
				row = _tmp14_;
				{
					gint c = 0;
					c = 0;
					{
						gboolean _tmp15_ = FALSE;
						_tmp15_ = TRUE;
						while (TRUE) {
							GtkWidget* cell = NULL;
							DcMessageRowMarkdownTableRow* _tmp17_;
							gchar** _tmp18_;
							gint _tmp18__length1;
							const gchar* _tmp19_;
							gint* _tmp20_;
							gint _tmp20__length1;
							gint _tmp21_;
							DcMessageRowMarkdownTableRow* _tmp22_;
							GtkWidget* _tmp23_;
							GtkGrid* _tmp24_;
							GtkWidget* _tmp25_;
							if (!_tmp15_) {
								gint _tmp16_;
								_tmp16_ = c;
								c = _tmp16_ + 1;
							}
							_tmp15_ = FALSE;
							if (!(c < columns)) {
								break;
							}
							_tmp17_ = row;
							_tmp18_ = _tmp17_->cells;
							_tmp18__length1 = _tmp17_->cells_length1;
							_tmp19_ = _tmp18_[c];
							_tmp20_ = table->aligns;
							_tmp20__length1 = table->aligns_length1;
							_tmp21_ = _tmp20_[c];
							_tmp22_ = row;
							_tmp23_ = dc_message_row_build_table_cell (_tmp19_, cell_width, _tmp21_, _tmp22_->header);
							cell = _tmp23_;
							_tmp24_ = grid;
							_tmp25_ = cell;
							gtk_grid_attach (_tmp24_, _tmp25_, c, r, 1, 1);
							_g_object_unref0 (cell);
						}
					}
				}
				_dc_message_row_markdown_table_row_unref0 (row);
			}
		}
	}
	result = (GtkWidget*) grid;
	return result;
}

static gint
dc_message_row_table_cell_width_chars (gint columns,
                                       gint max_width_chars)
{
	gint _tmp0_ = 0;
	gint total = 0;
	gint width = 0;
	gint result;
	if (max_width_chars > 0) {
		_tmp0_ = max_width_chars;
	} else {
		_tmp0_ = 84;
	}
	total = _tmp0_;
	width = (total - ((columns - 1) * 3)) / columns;
	result = MAX (6, MIN (28, width));
	return result;
}

static GtkWidget*
dc_message_row_build_table_cell (const gchar* raw,
                                 gint width_chars,
                                 gint align,
                                 gboolean header)
{
	GtkLabel* label = NULL;
	GtkLabel* _tmp0_;
	GtkLabel* _tmp1_;
	GtkLabel* _tmp3_;
	GtkLabel* _tmp4_;
	GtkLabel* _tmp5_;
	GtkLabel* _tmp6_;
	gfloat _tmp7_ = 0.0F;
	GtkLabel* _tmp9_;
	GtkJustification _tmp10_ = 0;
	GtkLabel* _tmp12_;
	GtkWidget* result;
	g_return_val_if_fail (raw != NULL, NULL);
	_tmp0_ = dc_message_row_build_markup_label (raw, width_chars, 0, NULL);
	label = _tmp0_;
	_tmp1_ = label;
	gtk_widget_add_css_class ((GtkWidget*) _tmp1_, "markdown-table-cell");
	if (header) {
		GtkLabel* _tmp2_;
		_tmp2_ = label;
		gtk_widget_add_css_class ((GtkWidget*) _tmp2_, "markdown-table-header");
	}
	_tmp3_ = label;
	gtk_widget_set_valign ((GtkWidget*) _tmp3_, GTK_ALIGN_START);
	_tmp4_ = label;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp4_, TRUE);
	_tmp5_ = label;
	gtk_label_set_width_chars (_tmp5_, MIN (width_chars, 18));
	_tmp6_ = label;
	gtk_label_set_max_width_chars (_tmp6_, width_chars);
	if (align == DC_MESSAGE_ROW_ALIGN_RIGHT) {
		_tmp7_ = 1.0f;
	} else {
		gfloat _tmp8_ = 0.0F;
		if (align == DC_MESSAGE_ROW_ALIGN_CENTER) {
			_tmp8_ = 0.5f;
		} else {
			_tmp8_ = 0.0f;
		}
		_tmp7_ = _tmp8_;
	}
	_tmp9_ = label;
	gtk_label_set_xalign (_tmp9_, _tmp7_);
	if (align == DC_MESSAGE_ROW_ALIGN_RIGHT) {
		_tmp10_ = GTK_JUSTIFY_RIGHT;
	} else {
		GtkJustification _tmp11_ = 0;
		if (align == DC_MESSAGE_ROW_ALIGN_CENTER) {
			_tmp11_ = GTK_JUSTIFY_CENTER;
		} else {
			_tmp11_ = GTK_JUSTIFY_LEFT;
		}
		_tmp10_ = _tmp11_;
	}
	_tmp12_ = label;
	gtk_label_set_justify (_tmp12_, _tmp10_);
	result = (GtkWidget*) label;
	return result;
}

/** Number of emoji when the message is emoji-only (whitespace allowed
            between them), 0 otherwise. */
static gint
dc_message_row_emoji_only_count (const gchar* raw)
{
	gchar* text = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gint index = 0;
	gint count = 0;
	gint result;
	if (raw == NULL) {
		result = 0;
		return result;
	}
	_tmp0_ = string_strip (raw);
	text = _tmp0_;
	_tmp1_ = text;
	_tmp2_ = strlen (_tmp1_);
	_tmp3_ = _tmp2_;
	if (_tmp3_ == 0) {
		result = 0;
		_g_free0 (text);
		return result;
	}
	index = 0;
	count = 0;
	while (TRUE) {
		const gchar* _tmp4_;
		gint _tmp5_;
		gint _tmp6_;
		const gchar* _tmp7_;
		gboolean _tmp8_;
		gint _tmp9_;
		const gchar* _tmp10_;
		_tmp4_ = text;
		_tmp5_ = strlen (_tmp4_);
		_tmp6_ = _tmp5_;
		if (!(index < _tmp6_)) {
			break;
		}
		_tmp7_ = text;
		_tmp8_ = dc_message_row_consume_emoji_sequence (_tmp7_, &index);
		if (!_tmp8_) {
			result = 0;
			_g_free0 (text);
			return result;
		}
		_tmp9_ = count;
		count = _tmp9_ + 1;
		_tmp10_ = text;
		dc_message_row_consume_whitespace (_tmp10_, &index);
	}
	result = count;
	_g_free0 (text);
	return result;
}

/** On macOS the emoji glyphs draw wider than the advance width
            Pango measures, so adjacent emoji visually overlap at any font
            size.  Inserting a thin space between consecutive emoji
            clusters restores the separation; other platforms render
            emoji at their advance width and are returned unchanged. */
static gboolean
string_get_next_char (const gchar* self,
                      gint* index,
                      gunichar* c)
{
	gunichar _vala_c = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	if (_vala_c != ((gunichar) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp0_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
}

gchar*
dc_message_row_spread_adjacent_emoji (const gchar* raw)
{
	GString* sb = NULL;
	GString* _tmp2_;
	gint index = 0;
	gboolean prev_emoji = FALSE;
	GString* _tmp13_;
	const gchar* _tmp14_;
	gchar* _tmp15_;
	gchar* result;
	if (raw == NULL) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup ("");
		result = _tmp0_;
		return result;
	}
	if (!dc_platform_is_macos ()) {
		gchar* _tmp1_;
		_tmp1_ = g_strdup (raw);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = g_string_new ("");
	sb = _tmp2_;
	index = 0;
	prev_emoji = FALSE;
	while (TRUE) {
		gint _tmp3_;
		gint _tmp4_;
		gint start = 0;
		gboolean _tmp5_;
		_tmp3_ = strlen (raw);
		_tmp4_ = _tmp3_;
		if (!(index < _tmp4_)) {
			break;
		}
		start = index;
		_tmp5_ = dc_message_row_consume_emoji_sequence (raw, &index);
		if (_tmp5_) {
			GString* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			if (prev_emoji) {
				GString* _tmp6_;
				_tmp6_ = sb;
				g_string_append_unichar (_tmp6_, (gunichar) 0x2009);
			}
			_tmp7_ = sb;
			_tmp8_ = string_substring (raw, (glong) start, (glong) (index - start));
			_tmp9_ = _tmp8_;
			g_string_append (_tmp7_, _tmp9_);
			_g_free0 (_tmp9_);
			prev_emoji = TRUE;
		} else {
			gunichar c = 0U;
			gunichar _tmp10_ = 0U;
			gboolean _tmp11_;
			GString* _tmp12_;
			index = start;
			_tmp11_ = string_get_next_char (raw, &index, &_tmp10_);
			c = _tmp10_;
			if (!_tmp11_) {
				break;
			}
			_tmp12_ = sb;
			g_string_append_unichar (_tmp12_, c);
			prev_emoji = FALSE;
		}
	}
	_tmp13_ = sb;
	_tmp14_ = _tmp13_->str;
	_tmp15_ = g_strdup (_tmp14_);
	result = _tmp15_;
	_g_string_free0 (sb);
	return result;
}

static void
dc_message_row_consume_whitespace (const gchar* text,
                                   gint* index)
{
	g_return_if_fail (text != NULL);
	while (TRUE) {
		gint next = 0;
		gunichar c = 0U;
		gunichar _tmp0_ = 0U;
		gboolean _tmp1_;
		next = *index;
		_tmp1_ = string_get_next_char (text, &next, &_tmp0_);
		c = _tmp0_;
		if (!_tmp1_) {
			return;
		}
		if (!g_unichar_isspace (c)) {
			return;
		}
		*index = next;
	}
}

static gboolean
dc_message_row_consume_emoji_sequence (const gchar* text,
                                       gint* index)
{
	gunichar c = 0U;
	gunichar _tmp0_ = 0U;
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	_tmp1_ = string_get_next_char (text, index, &_tmp0_);
	c = _tmp0_;
	if (!_tmp1_) {
		result = FALSE;
		return result;
	}
	if (dc_message_row_is_keycap_base (c)) {
		gboolean _tmp2_;
		dc_message_row_consume_variation_selectors (text, index);
		_tmp2_ = dc_message_row_consume_char (text, index, (gunichar) 0x20e3);
		result = _tmp2_;
		return result;
	}
	if (dc_message_row_is_regional_indicator (c)) {
		gunichar _tmp3_ = 0U;
		gboolean _tmp4_;
		_tmp4_ = string_get_next_char (text, index, &_tmp3_);
		c = _tmp3_;
		if (!_tmp4_) {
			result = FALSE;
			return result;
		}
		result = dc_message_row_is_regional_indicator (c);
		return result;
	}
	if (!dc_message_row_is_emoji_base (c)) {
		result = FALSE;
		return result;
	}
	dc_message_row_consume_emoji_modifiers (text, index);
	while (TRUE) {
		gboolean _tmp5_;
		gunichar _tmp6_ = 0U;
		gboolean _tmp7_;
		_tmp5_ = dc_message_row_consume_char (text, index, (gunichar) 0x200d);
		if (!_tmp5_) {
			break;
		}
		_tmp7_ = string_get_next_char (text, index, &_tmp6_);
		c = _tmp6_;
		if (!_tmp7_) {
			result = FALSE;
			return result;
		}
		if (!dc_message_row_is_emoji_base (c)) {
			result = FALSE;
			return result;
		}
		dc_message_row_consume_emoji_modifiers (text, index);
	}
	result = TRUE;
	return result;
}

static gboolean
dc_message_row_consume_char (const gchar* text,
                             gint* index,
                             gunichar expected)
{
	gint next = 0;
	gunichar c = 0U;
	gunichar _tmp0_ = 0U;
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	next = *index;
	_tmp1_ = string_get_next_char (text, &next, &_tmp0_);
	c = _tmp0_;
	if (!_tmp1_) {
		result = FALSE;
		return result;
	}
	if (c != expected) {
		result = FALSE;
		return result;
	}
	*index = next;
	result = TRUE;
	return result;
}

static void
dc_message_row_consume_emoji_modifiers (const gchar* text,
                                        gint* index)
{
	g_return_if_fail (text != NULL);
	while (TRUE) {
		gboolean _tmp0_ = FALSE;
		gboolean _tmp1_;
		_tmp1_ = dc_message_row_consume_variation_selectors (text, index);
		if (_tmp1_) {
			_tmp0_ = TRUE;
		} else {
			gboolean _tmp2_;
			_tmp2_ = dc_message_row_consume_emoji_modifier (text, index);
			_tmp0_ = _tmp2_;
		}
		if (!_tmp0_) {
			break;
		}
	}
	dc_message_row_consume_tag_sequence (text, index);
}

static gboolean
dc_message_row_consume_variation_selectors (const gchar* text,
                                            gint* index)
{
	gboolean consumed = FALSE;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	consumed = FALSE;
	while (TRUE) {
		gint next = 0;
		gunichar c = 0U;
		gunichar _tmp0_ = 0U;
		gboolean _tmp1_;
		gboolean _tmp2_ = FALSE;
		next = *index;
		_tmp1_ = string_get_next_char (text, &next, &_tmp0_);
		c = _tmp0_;
		if (!_tmp1_) {
			result = consumed;
			return result;
		}
		if (c != ((gunichar) 0xfe0e)) {
			_tmp2_ = c != ((gunichar) 0xfe0f);
		} else {
			_tmp2_ = FALSE;
		}
		if (_tmp2_) {
			result = consumed;
			return result;
		}
		*index = next;
		consumed = TRUE;
	}
}

static gboolean
dc_message_row_consume_emoji_modifier (const gchar* text,
                                       gint* index)
{
	gint next = 0;
	gunichar c = 0U;
	gunichar _tmp0_ = 0U;
	gboolean _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	next = *index;
	_tmp1_ = string_get_next_char (text, &next, &_tmp0_);
	c = _tmp0_;
	if (!_tmp1_) {
		result = FALSE;
		return result;
	}
	if (c < ((gunichar) 0x1f3fb)) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = c > ((gunichar) 0x1f3ff);
	}
	if (_tmp2_) {
		result = FALSE;
		return result;
	}
	*index = next;
	result = TRUE;
	return result;
}

static void
dc_message_row_consume_tag_sequence (const gchar* text,
                                     gint* index)
{
	gint before = 0;
	gint next = 0;
	gunichar c = 0U;
	gboolean has_tag = FALSE;
	gboolean _tmp3_ = FALSE;
	g_return_if_fail (text != NULL);
	before = *index;
	next = *index;
	has_tag = FALSE;
	while (TRUE) {
		gunichar _tmp0_ = 0U;
		gboolean _tmp1_;
		gboolean _tmp2_ = FALSE;
		_tmp1_ = string_get_next_char (text, &next, &_tmp0_);
		c = _tmp0_;
		if (!_tmp1_) {
			break;
		}
		if (c < ((gunichar) 0xe0020)) {
			_tmp2_ = TRUE;
		} else {
			_tmp2_ = c > ((gunichar) 0xe007e);
		}
		if (_tmp2_) {
			break;
		}
		*index = next;
		has_tag = TRUE;
	}
	if (has_tag) {
		gboolean _tmp4_;
		_tmp4_ = dc_message_row_consume_char (text, index, (gunichar) 0xe007f);
		_tmp3_ = _tmp4_;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		return;
	}
	*index = before;
}

static gboolean
dc_message_row_is_keycap_base (gunichar c)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	if (c == ((gunichar) 0x23)) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = c == ((gunichar) 0x2a);
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp2_ = FALSE;
		if (c >= ((gunichar) 0x30)) {
			_tmp2_ = c <= ((gunichar) 0x39);
		} else {
			_tmp2_ = FALSE;
		}
		_tmp0_ = _tmp2_;
	}
	result = _tmp0_;
	return result;
}

static gboolean
dc_message_row_is_regional_indicator (gunichar c)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	if (c >= ((gunichar) 0x1f1e6)) {
		_tmp0_ = c <= ((gunichar) 0x1f1ff);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gboolean
dc_message_row_is_emoji_base (gunichar c)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp7_ = FALSE;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	gboolean _tmp12_ = FALSE;
	gboolean _tmp13_ = FALSE;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_ = FALSE;
	gboolean _tmp16_ = FALSE;
	gboolean _tmp17_ = FALSE;
	gboolean _tmp18_ = FALSE;
	gboolean _tmp19_ = FALSE;
	gboolean _tmp20_ = FALSE;
	gboolean _tmp21_ = FALSE;
	gboolean _tmp22_ = FALSE;
	gboolean _tmp23_ = FALSE;
	gboolean _tmp24_ = FALSE;
	gboolean _tmp25_ = FALSE;
	gboolean _tmp26_ = FALSE;
	gboolean result;
	if (c == ((gunichar) 0x00a9)) {
		_tmp26_ = TRUE;
	} else {
		_tmp26_ = c == ((gunichar) 0x00ae);
	}
	if (_tmp26_) {
		_tmp25_ = TRUE;
	} else {
		_tmp25_ = c == ((gunichar) 0x203c);
	}
	if (_tmp25_) {
		_tmp24_ = TRUE;
	} else {
		_tmp24_ = c == ((gunichar) 0x2049);
	}
	if (_tmp24_) {
		_tmp23_ = TRUE;
	} else {
		_tmp23_ = c == ((gunichar) 0x2122);
	}
	if (_tmp23_) {
		_tmp22_ = TRUE;
	} else {
		_tmp22_ = c == ((gunichar) 0x2139);
	}
	if (_tmp22_) {
		_tmp21_ = TRUE;
	} else {
		gboolean _tmp27_ = FALSE;
		if (c >= ((gunichar) 0x2194)) {
			_tmp27_ = c <= ((gunichar) 0x21aa);
		} else {
			_tmp27_ = FALSE;
		}
		_tmp21_ = _tmp27_;
	}
	if (_tmp21_) {
		_tmp20_ = TRUE;
	} else {
		_tmp20_ = c == ((gunichar) 0x231a);
	}
	if (_tmp20_) {
		_tmp19_ = TRUE;
	} else {
		_tmp19_ = c == ((gunichar) 0x231b);
	}
	if (_tmp19_) {
		_tmp18_ = TRUE;
	} else {
		_tmp18_ = c == ((gunichar) 0x2328);
	}
	if (_tmp18_) {
		_tmp17_ = TRUE;
	} else {
		_tmp17_ = c == ((gunichar) 0x23cf);
	}
	if (_tmp17_) {
		_tmp16_ = TRUE;
	} else {
		gboolean _tmp28_ = FALSE;
		if (c >= ((gunichar) 0x23e9)) {
			_tmp28_ = c <= ((gunichar) 0x23f3);
		} else {
			_tmp28_ = FALSE;
		}
		_tmp16_ = _tmp28_;
	}
	if (_tmp16_) {
		_tmp15_ = TRUE;
	} else {
		gboolean _tmp29_ = FALSE;
		if (c >= ((gunichar) 0x23f8)) {
			_tmp29_ = c <= ((gunichar) 0x23fa);
		} else {
			_tmp29_ = FALSE;
		}
		_tmp15_ = _tmp29_;
	}
	if (_tmp15_) {
		_tmp14_ = TRUE;
	} else {
		_tmp14_ = c == ((gunichar) 0x24c2);
	}
	if (_tmp14_) {
		_tmp13_ = TRUE;
	} else {
		_tmp13_ = c == ((gunichar) 0x25aa);
	}
	if (_tmp13_) {
		_tmp12_ = TRUE;
	} else {
		_tmp12_ = c == ((gunichar) 0x25ab);
	}
	if (_tmp12_) {
		_tmp11_ = TRUE;
	} else {
		_tmp11_ = c == ((gunichar) 0x25b6);
	}
	if (_tmp11_) {
		_tmp10_ = TRUE;
	} else {
		_tmp10_ = c == ((gunichar) 0x25c0);
	}
	if (_tmp10_) {
		_tmp9_ = TRUE;
	} else {
		gboolean _tmp30_ = FALSE;
		if (c >= ((gunichar) 0x25fb)) {
			_tmp30_ = c <= ((gunichar) 0x25fe);
		} else {
			_tmp30_ = FALSE;
		}
		_tmp9_ = _tmp30_;
	}
	if (_tmp9_) {
		_tmp8_ = TRUE;
	} else {
		gboolean _tmp31_ = FALSE;
		if (c >= ((gunichar) 0x2600)) {
			_tmp31_ = c <= ((gunichar) 0x27bf);
		} else {
			_tmp31_ = FALSE;
		}
		_tmp8_ = _tmp31_;
	}
	if (_tmp8_) {
		_tmp7_ = TRUE;
	} else {
		_tmp7_ = c == ((gunichar) 0x2934);
	}
	if (_tmp7_) {
		_tmp6_ = TRUE;
	} else {
		_tmp6_ = c == ((gunichar) 0x2935);
	}
	if (_tmp6_) {
		_tmp5_ = TRUE;
	} else {
		gboolean _tmp32_ = FALSE;
		if (c >= ((gunichar) 0x2b05)) {
			_tmp32_ = c <= ((gunichar) 0x2b55);
		} else {
			_tmp32_ = FALSE;
		}
		_tmp5_ = _tmp32_;
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = c == ((gunichar) 0x3030);
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = c == ((gunichar) 0x303d);
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = c == ((gunichar) 0x3297);
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = c == ((gunichar) 0x3299);
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp33_ = FALSE;
		if (c >= ((gunichar) 0x1f000)) {
			_tmp33_ = c <= ((gunichar) 0x1faff);
		} else {
			_tmp33_ = FALSE;
		}
		_tmp0_ = _tmp33_;
	}
	result = _tmp0_;
	return result;
}

/** Reaction badge bar, or null when the message has no reactions. */
static GtkBox*
dc_message_row_build_reactions_box (DcMessageRow* self,
                                    DcMessage* msg)
{
	gboolean _tmp0_ = FALSE;
	GPtrArray* _tmp1_;
	gboolean has_details = FALSE;
	gboolean _tmp5_ = FALSE;
	GtkBox* box = NULL;
	GtkBox* _tmp13_;
	GtkBox* _tmp14_;
	GtkBox* _tmp15_;
	const gchar* _tmp26_;
	const gchar* _tmp27_;
	gchar** _tmp28_;
	gchar** _tmp29_;
	GtkBox* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = msg->reaction_details;
	if (_tmp1_ != NULL) {
		GPtrArray* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		_tmp2_ = msg->reaction_details;
		_tmp3_ = vala_g_ptr_array_get_length (_tmp2_);
		_tmp4_ = _tmp3_;
		_tmp0_ = _tmp4_ > 0;
	} else {
		_tmp0_ = FALSE;
	}
	has_details = _tmp0_;
	if (!has_details) {
		gboolean _tmp6_ = FALSE;
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		_tmp7_ = dc_message_get_reactions (msg);
		_tmp8_ = _tmp7_;
		if (_tmp8_ == NULL) {
			_tmp6_ = TRUE;
		} else {
			const gchar* _tmp9_;
			const gchar* _tmp10_;
			gint _tmp11_;
			gint _tmp12_;
			_tmp9_ = dc_message_get_reactions (msg);
			_tmp10_ = _tmp9_;
			_tmp11_ = strlen (_tmp10_);
			_tmp12_ = _tmp11_;
			_tmp6_ = _tmp12_ == 0;
		}
		_tmp5_ = _tmp6_;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		result = NULL;
		return result;
	}
	_tmp13_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
	g_object_ref_sink (_tmp13_);
	box = _tmp13_;
	_tmp14_ = box;
	gtk_widget_add_css_class ((GtkWidget*) _tmp14_, "reaction-bar");
	_tmp15_ = box;
	gtk_widget_set_halign ((GtkWidget*) _tmp15_, GTK_ALIGN_START);
	if (has_details) {
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp16_ = FALSE;
				_tmp16_ = TRUE;
				while (TRUE) {
					GPtrArray* _tmp18_;
					gint _tmp19_;
					gint _tmp20_;
					GtkBox* _tmp21_;
					GPtrArray* _tmp22_;
					gconstpointer _tmp23_;
					GtkWidget* _tmp24_;
					GtkWidget* _tmp25_;
					if (!_tmp16_) {
						gint _tmp17_;
						_tmp17_ = i;
						i = _tmp17_ + 1;
					}
					_tmp16_ = FALSE;
					_tmp18_ = msg->reaction_details;
					_tmp19_ = vala_g_ptr_array_get_length (_tmp18_);
					_tmp20_ = _tmp19_;
					if (!(i < _tmp20_)) {
						break;
					}
					_tmp21_ = box;
					_tmp22_ = msg->reaction_details;
					_tmp23_ = g_ptr_array_index (_tmp22_, (guint) i);
					_tmp24_ = dc_message_row_build_reaction_badge (self, msg, (DcMessageReaction*) _tmp23_);
					_tmp25_ = _tmp24_;
					gtk_box_append (_tmp21_, _tmp25_);
					_g_object_unref0 (_tmp25_);
				}
			}
		}
		result = box;
		return result;
	}
	_tmp26_ = dc_message_get_reactions (msg);
	_tmp27_ = _tmp26_;
	_tmp29_ = _tmp28_ = g_strsplit (_tmp27_, ",", 0);
	{
		gchar** part_collection = NULL;
		gint part_collection_length1 = 0;
		gint _part_collection_size_ = 0;
		gint part_it = 0;
		part_collection = _tmp29_;
		part_collection_length1 = _vala_array_length (_tmp28_);
		for (part_it = 0; part_it < part_collection_length1; part_it = part_it + 1) {
			gchar* _tmp30_;
			gchar* part = NULL;
			_tmp30_ = g_strdup (part_collection[part_it]);
			part = _tmp30_;
			{
				gchar** kv = NULL;
				const gchar* _tmp31_;
				gchar** _tmp32_;
				gchar** _tmp33_;
				gint kv_length1;
				gint _kv_size_;
				gchar** _tmp34_;
				gint _tmp34__length1;
				DcMessageReaction* reaction = NULL;
				gchar** _tmp35_;
				gint _tmp35__length1;
				const gchar* _tmp36_;
				DcMessageReaction* _tmp37_;
				DcMessageReaction* _tmp38_;
				gchar** _tmp39_;
				gint _tmp39__length1;
				const gchar* _tmp40_;
				GtkBox* _tmp41_;
				DcMessageReaction* _tmp42_;
				GtkWidget* _tmp43_;
				GtkWidget* _tmp44_;
				_tmp31_ = part;
				_tmp33_ = _tmp32_ = g_strsplit (_tmp31_, ":", 2);
				kv = _tmp33_;
				kv_length1 = _vala_array_length (_tmp32_);
				_kv_size_ = kv_length1;
				_tmp34_ = kv;
				_tmp34__length1 = kv_length1;
				if (_tmp34__length1 < 2) {
					kv = (_vala_array_free (kv, kv_length1, (GDestroyNotify) g_free), NULL);
					_g_free0 (part);
					continue;
				}
				_tmp35_ = kv;
				_tmp35__length1 = kv_length1;
				_tmp36_ = _tmp35_[0];
				_tmp37_ = dc_message_reaction_new (_tmp36_);
				reaction = _tmp37_;
				_tmp38_ = reaction;
				_tmp39_ = kv;
				_tmp39__length1 = kv_length1;
				_tmp40_ = _tmp39_[1];
				dc_message_reaction_set_count (_tmp38_, atoi (_tmp40_));
				_tmp41_ = box;
				_tmp42_ = reaction;
				_tmp43_ = dc_message_row_build_reaction_badge (self, msg, _tmp42_);
				_tmp44_ = _tmp43_;
				gtk_box_append (_tmp41_, _tmp44_);
				_g_object_unref0 (_tmp44_);
				_g_object_unref0 (reaction);
				kv = (_vala_array_free (kv, kv_length1, (GDestroyNotify) g_free), NULL);
				_g_free0 (part);
			}
		}
		part_collection = (_vala_array_free (part_collection, part_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	result = box;
	return result;
}

static GtkWidget*
dc_message_row_build_reaction_badge (DcMessageRow* self,
                                     DcMessage* msg,
                                     DcMessageReaction* reaction)
{
	gchar* count = NULL;
	gint _tmp0_;
	gint _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_ = NULL;
	gint _tmp4_;
	gint _tmp5_;
	GtkButton* badge = NULL;
	GtkButton* _tmp13_;
	GtkPopover* popover = NULL;
	GtkPopover* _tmp14_;
	GtkPopover* _tmp15_;
	GtkEventControllerMotion* motion = NULL;
	GtkEventControllerMotion* _tmp16_;
	GtkEventController* _tmp17_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	g_return_val_if_fail (reaction != NULL, NULL);
	_tmp0_ = dc_message_reaction_get_count (reaction);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_strdup_printf ("%i", _tmp1_);
	count = _tmp2_;
	_tmp4_ = dc_message_reaction_get_count (reaction);
	_tmp5_ = _tmp4_;
	if (_tmp5_ == 1) {
		const gchar* _tmp6_;
		const gchar* _tmp7_;
		gchar* _tmp8_;
		_tmp6_ = dc_message_reaction_get_emoji (reaction);
		_tmp7_ = _tmp6_;
		_tmp8_ = g_strdup (_tmp7_);
		_g_free0 (_tmp3_);
		_tmp3_ = _tmp8_;
	} else {
		const gchar* _tmp9_;
		const gchar* _tmp10_;
		const gchar* _tmp11_;
		gchar* _tmp12_;
		_tmp9_ = dc_message_reaction_get_emoji (reaction);
		_tmp10_ = _tmp9_;
		_tmp11_ = count;
		_tmp12_ = g_strdup_printf ("%s %s", _tmp10_, _tmp11_);
		_g_free0 (_tmp3_);
		_tmp3_ = _tmp12_;
	}
	_tmp13_ = (GtkButton*) gtk_button_new_with_label (_tmp3_);
	g_object_ref_sink (_tmp13_);
	badge = _tmp13_;
	gtk_widget_add_css_class ((GtkWidget*) badge, "flat");
	gtk_widget_add_css_class ((GtkWidget*) badge, "reaction-badge");
	gtk_widget_set_tooltip_text ((GtkWidget*) badge, "Show reactions");
	_tmp14_ = dc_message_row_build_reaction_popover (self, msg, reaction);
	popover = _tmp14_;
	_tmp15_ = _g_object_ref0 (popover);
	g_object_set_data_full ((GObject*) badge, DC_MESSAGE_ROW_REACTION_POPOVER_DATA, _tmp15_, g_object_unref);
	_tmp16_ = (GtkEventControllerMotion*) gtk_event_controller_motion_new ();
	motion = _tmp16_;
	dc_message_row_connect_reaction_popover (badge, motion, popover);
	_tmp17_ = _g_object_ref0 ((GtkEventController*) motion);
	gtk_widget_add_controller ((GtkWidget*) badge, _tmp17_);
	result = (GtkWidget*) badge;
	_g_object_unref0 (motion);
	_g_object_unref0 (popover);
	_g_free0 (_tmp3_);
	_g_free0 (count);
	return result;
}

static void
dc_message_row_connect_reaction_popover (GtkButton* badge,
                                         GtkEventControllerMotion* motion,
                                         GtkPopover* popover)
{
	g_return_if_fail (badge != NULL);
	g_return_if_fail (motion != NULL);
	g_return_if_fail (popover != NULL);
	g_signal_connect_object (badge, "clicked", (GCallback) dc_message_row_on_reaction_clicked, (GObject*) popover, (GConnectFlags) 0);
	g_signal_connect_object (motion, "enter", (GCallback) dc_message_row_on_reaction_enter, (GObject*) popover, (GConnectFlags) 0);
	g_signal_connect_object (motion, "leave", (GCallback) dc_message_row_on_reaction_leave, (GObject*) popover, (GConnectFlags) 0);
	g_signal_connect_object (badge, "destroy", (GCallback) dc_message_row_on_reaction_badge_destroy, (GObject*) popover, (GConnectFlags) 0);
	g_signal_connect_object (popover, "closed", (GCallback) dc_message_row_on_reaction_popover_closed, (GObject*) badge, (GConnectFlags) 0);
}

static void
dc_message_row_on_reaction_clicked (GtkButton* badge,
                                    GtkPopover* popover)
{
	g_return_if_fail (badge != NULL);
	g_return_if_fail (popover != NULL);
	dc_message_row_cancel_reaction_popdown (popover);
	dc_message_row_show_reaction_popover (badge, popover);
}

static void
dc_message_row_on_reaction_enter (GtkEventControllerMotion* motion,
                                  gdouble x,
                                  gdouble y,
                                  GtkPopover* popover)
{
	GtkButton* badge = NULL;
	GtkWidget* _tmp0_;
	GtkWidget* _tmp1_;
	GtkButton* _tmp2_;
	GtkButton* _tmp3_;
	g_return_if_fail (motion != NULL);
	g_return_if_fail (popover != NULL);
	dc_message_row_cancel_reaction_popdown (popover);
	_tmp0_ = gtk_event_controller_get_widget ((GtkEventController*) motion);
	_tmp1_ = _tmp0_;
	_tmp2_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp1_, gtk_button_get_type ()) ? ((GtkButton*) _tmp1_) : NULL);
	badge = _tmp2_;
	_tmp3_ = badge;
	if (_tmp3_ != NULL) {
		GtkButton* _tmp4_;
		_tmp4_ = badge;
		dc_message_row_show_reaction_popover (_tmp4_, popover);
	}
	_g_object_unref0 (badge);
}

static void
dc_message_row_on_reaction_leave (GtkEventControllerMotion* motion,
                                  GtkPopover* popover)
{
	g_return_if_fail (motion != NULL);
	g_return_if_fail (popover != NULL);
	dc_message_row_cancel_reaction_popdown (popover);
	dc_message_row_schedule_reaction_popdown (popover);
}

static void
dc_message_row_show_reaction_popover (GtkButton* badge,
                                      GtkPopover* popover)
{
	GtkWidget* _tmp0_;
	g_return_if_fail (badge != NULL);
	g_return_if_fail (popover != NULL);
	_tmp0_ = gtk_widget_get_parent ((GtkWidget*) popover);
	if (_tmp0_ == NULL) {
		gtk_widget_set_parent ((GtkWidget*) popover, (GtkWidget*) badge);
	}
	gtk_popover_popup (popover);
}

static void
dc_message_row_on_reaction_badge_destroy (GtkButton* badge,
                                          GtkPopover* popover)
{
	GtkWidget* _tmp0_;
	g_return_if_fail (badge != NULL);
	g_return_if_fail (popover != NULL);
	dc_message_row_cancel_reaction_popdown (popover);
	gtk_popover_popdown (popover);
	_tmp0_ = gtk_widget_get_parent ((GtkWidget*) popover);
	if (_tmp0_ == G_TYPE_CHECK_INSTANCE_CAST (badge, gtk_widget_get_type (), GtkWidget)) {
		gtk_widget_unparent ((GtkWidget*) popover);
	}
}

static void
dc_message_row_on_reaction_popover_closed (GtkPopover* popover,
                                           GtkButton* badge)
{
	GtkWidget* _tmp0_;
	g_return_if_fail (popover != NULL);
	g_return_if_fail (badge != NULL);
	_tmp0_ = gtk_widget_get_parent ((GtkWidget*) popover);
	if (_tmp0_ == G_TYPE_CHECK_INSTANCE_CAST (badge, gtk_widget_get_type (), GtkWidget)) {
		gtk_widget_unparent ((GtkWidget*) popover);
	}
}

static void
dc_message_row_cancel_reaction_popdown (GtkPopover* popover)
{
	guint source_id = 0U;
	gconstpointer _tmp0_;
	g_return_if_fail (popover != NULL);
	_tmp0_ = g_object_get_data ((GObject*) popover, DC_MESSAGE_ROW_REACTION_HIDE_DATA);
	source_id = (guint) ((guintptr) _tmp0_);
	if (source_id == ((guint) 0)) {
		return;
	}
	g_source_remove (source_id);
	g_object_set_data_full ((GObject*) popover, DC_MESSAGE_ROW_REACTION_HIDE_DATA, (gpointer) ((guintptr) 0), NULL);
}

static Block26Data*
block26_data_ref (Block26Data* _data26_)
{
	g_atomic_int_inc (&_data26_->_ref_count_);
	return _data26_;
}

static void
block26_data_unref (void * _userdata_)
{
	Block26Data* _data26_;
	_data26_ = (Block26Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data26_->_ref_count_)) {
		g_weak_ref_clear (&_data26_->popover_ref);
		g_slice_free (Block26Data, _data26_);
	}
}

static gboolean
__lambda436_ (Block26Data* _data26_)
{
	GtkPopover* live_popover = NULL;
	GObject* _tmp0_;
	GtkPopover* _tmp1_;
	GtkPopover* _tmp2_;
	gboolean result;
	_tmp0_ = g_weak_ref_get (&_data26_->popover_ref);
	_tmp1_ = G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, gtk_popover_get_type ()) ? ((GtkPopover*) _tmp0_) : NULL;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (_tmp0_);
	}
	live_popover = _tmp1_;
	_tmp2_ = live_popover;
	if (_tmp2_ != NULL) {
		GtkPopover* _tmp3_;
		GtkPopover* _tmp4_;
		_tmp3_ = live_popover;
		g_object_set_data_full ((GObject*) _tmp3_, DC_MESSAGE_ROW_REACTION_HIDE_DATA, (gpointer) ((guintptr) 0), NULL);
		_tmp4_ = live_popover;
		gtk_popover_popdown (_tmp4_);
	}
	result = G_SOURCE_REMOVE;
	_g_object_unref0 (live_popover);
	return result;
}

static gboolean
___lambda436__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda436_ (self);
	return result;
}

static void
dc_message_row_schedule_reaction_popdown (GtkPopover* popover)
{
	Block26Data* _data26_;
	guint source_id = 0U;
	g_return_if_fail (popover != NULL);
	_data26_ = g_slice_new0 (Block26Data);
	_data26_->_ref_count_ = 1;
	g_weak_ref_init (&_data26_->popover_ref, (GObject*) popover);
	source_id = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 180, ___lambda436__gsource_func, block26_data_ref (_data26_), block26_data_unref);
	g_object_set_data_full ((GObject*) popover, DC_MESSAGE_ROW_REACTION_HIDE_DATA, (gpointer) ((guintptr) source_id), NULL);
	block26_data_unref (_data26_);
	_data26_ = NULL;
}

static GtkPopover*
dc_message_row_build_reaction_popover (DcMessageRow* self,
                                       DcMessage* msg,
                                       DcMessageReaction* reaction)
{
	GtkPopover* popover = NULL;
	GtkPopover* _tmp0_;
	GtkPopover* _tmp1_;
	GtkPopover* _tmp2_;
	GtkPopover* _tmp3_;
	GtkBox* pill = NULL;
	GtkBox* _tmp4_;
	GtkBox* _tmp5_;
	GPtrArray* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	GtkPopover* _tmp32_;
	GtkBox* _tmp33_;
	GtkPopover* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	g_return_val_if_fail (reaction != NULL, NULL);
	_tmp0_ = (GtkPopover*) gtk_popover_new ();
	g_object_ref_sink (_tmp0_);
	popover = _tmp0_;
	_tmp1_ = popover;
	gtk_popover_set_has_arrow (_tmp1_, FALSE);
	_tmp2_ = popover;
	gtk_popover_set_autohide (_tmp2_, TRUE);
	_tmp3_ = popover;
	gtk_popover_set_position (_tmp3_, GTK_POS_TOP);
	_tmp4_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
	g_object_ref_sink (_tmp4_);
	pill = _tmp4_;
	_tmp5_ = pill;
	gtk_widget_add_css_class ((GtkWidget*) _tmp5_, "reaction-users-pill");
	_tmp6_ = reaction->users;
	_tmp7_ = vala_g_ptr_array_get_length (_tmp6_);
	_tmp8_ = _tmp7_;
	if (_tmp8_ == 0) {
		gchar* _tmp9_ = NULL;
		gint _tmp10_;
		gint _tmp11_;
		GtkLabel* label = NULL;
		GtkLabel* _tmp16_;
		GtkLabel* _tmp17_;
		GtkBox* _tmp18_;
		GtkLabel* _tmp19_;
		_tmp10_ = dc_message_reaction_get_count (reaction);
		_tmp11_ = _tmp10_;
		if (_tmp11_ == 1) {
			gchar* _tmp12_;
			_tmp12_ = g_strdup ("Unknown user");
			_g_free0 (_tmp9_);
			_tmp9_ = _tmp12_;
		} else {
			gint _tmp13_;
			gint _tmp14_;
			gchar* _tmp15_;
			_tmp13_ = dc_message_reaction_get_count (reaction);
			_tmp14_ = _tmp13_;
			_tmp15_ = g_strdup_printf ("%d reactions", _tmp14_);
			_g_free0 (_tmp9_);
			_tmp9_ = _tmp15_;
		}
		_tmp16_ = (GtkLabel*) gtk_label_new (_tmp9_);
		g_object_ref_sink (_tmp16_);
		label = _tmp16_;
		_tmp17_ = label;
		gtk_widget_add_css_class ((GtkWidget*) _tmp17_, "reaction-user-name");
		_tmp18_ = pill;
		_tmp19_ = label;
		gtk_box_append (_tmp18_, (GtkWidget*) _tmp19_);
		_g_object_unref0 (label);
		_g_free0 (_tmp9_);
	} else {
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp20_ = FALSE;
				_tmp20_ = TRUE;
				while (TRUE) {
					GPtrArray* _tmp22_;
					gint _tmp23_;
					gint _tmp24_;
					GtkBox* _tmp25_;
					GPtrArray* _tmp26_;
					gconstpointer _tmp27_;
					gint _tmp28_;
					gint _tmp29_;
					GtkWidget* _tmp30_;
					GtkWidget* _tmp31_;
					if (!_tmp20_) {
						gint _tmp21_;
						_tmp21_ = i;
						i = _tmp21_ + 1;
					}
					_tmp20_ = FALSE;
					_tmp22_ = reaction->users;
					_tmp23_ = vala_g_ptr_array_get_length (_tmp22_);
					_tmp24_ = _tmp23_;
					if (!(i < _tmp24_)) {
						break;
					}
					_tmp25_ = pill;
					_tmp26_ = reaction->users;
					_tmp27_ = g_ptr_array_index (_tmp26_, (guint) i);
					_tmp28_ = dc_message_reaction_user_get_contact_id ((DcMessageReactionUser*) _tmp27_);
					_tmp29_ = _tmp28_;
					_tmp30_ = dc_message_row_build_reaction_user_row (self, msg, _tmp29_);
					_tmp31_ = _tmp30_;
					gtk_box_append (_tmp25_, _tmp31_);
					_g_object_unref0 (_tmp31_);
				}
			}
		}
	}
	_tmp32_ = popover;
	_tmp33_ = pill;
	gtk_popover_set_child (_tmp32_, (GtkWidget*) _tmp33_);
	result = popover;
	_g_object_unref0 (pill);
	return result;
}

static GtkWidget*
dc_message_row_build_reaction_user_row (DcMessageRow* self,
                                        DcMessage* msg,
                                        gint contact_id)
{
	gchar* name = NULL;
	gchar* avatar_path = NULL;
	gchar* _tmp0_ = NULL;
	gchar* _tmp1_ = NULL;
	GtkBox* row = NULL;
	GtkBox* _tmp2_;
	GtkWidget* _tmp3_;
	GtkWidget* _tmp4_;
	GtkLabel* label = NULL;
	GtkLabel* _tmp5_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (msg != NULL, NULL);
	dc_message_row_reaction_user_identity (self, msg, contact_id, &_tmp0_, &_tmp1_);
	_g_free0 (name);
	name = _tmp0_;
	_g_free0 (avatar_path);
	avatar_path = _tmp1_;
	_tmp2_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
	g_object_ref_sink (_tmp2_);
	row = _tmp2_;
	gtk_widget_add_css_class ((GtkWidget*) row, "reaction-user-row");
	_tmp3_ = dc_presence_avatar (22, name, avatar_path, FALSE, NULL, NULL);
	_tmp4_ = _tmp3_;
	gtk_box_append (row, _tmp4_);
	_g_object_unref0 (_tmp4_);
	_tmp5_ = (GtkLabel*) gtk_label_new (name);
	g_object_ref_sink (_tmp5_);
	label = _tmp5_;
	gtk_widget_add_css_class ((GtkWidget*) label, "reaction-user-name");
	gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END);
	gtk_label_set_max_width_chars (label, 26);
	gtk_label_set_xalign (label, (gfloat) 0);
	gtk_box_append (row, (GtkWidget*) label);
	result = (GtkWidget*) row;
	_g_object_unref0 (label);
	_g_free0 (avatar_path);
	_g_free0 (name);
	return result;
}

static void
dc_message_row_reaction_user_identity (DcMessageRow* self,
                                       DcMessage* msg,
                                       gint contact_id,
                                       gchar** name,
                                       gchar** avatar_path)
{
	gchar* _vala_name = NULL;
	gchar* _vala_avatar_path = NULL;
	DcMentionMember* _tmp10_ = NULL;
	DcMentionRoster* _tmp11_;
	DcMentionMember* member = NULL;
	DcMentionMember* _tmp14_;
	DcMentionMember* _tmp15_;
	gboolean _tmp43_ = FALSE;
	gboolean _tmp44_ = FALSE;
	gboolean _tmp45_;
	gboolean _tmp46_;
	gchar* _tmp59_ = NULL;
	gchar* _tmp62_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_g_free0 (_vala_avatar_path);
	_vala_avatar_path = NULL;
	if (contact_id == 1) {
		const gchar* _tmp0_ = NULL;
		gboolean _tmp1_ = FALSE;
		const gchar* _tmp2_;
		gchar* _tmp7_;
		const gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp2_ = dc_message_row_self_display_name;
		if (_tmp2_ != NULL) {
			const gchar* _tmp3_;
			gint _tmp4_;
			gint _tmp5_;
			_tmp3_ = dc_message_row_self_display_name;
			_tmp4_ = strlen (_tmp3_);
			_tmp5_ = _tmp4_;
			_tmp1_ = _tmp5_ > 0;
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			const gchar* _tmp6_;
			_tmp6_ = dc_message_row_self_display_name;
			_tmp0_ = _tmp6_;
		} else {
			_tmp0_ = "You";
		}
		_tmp7_ = g_strdup (_tmp0_);
		_g_free0 (_vala_name);
		_vala_name = _tmp7_;
		_tmp8_ = dc_message_row_self_avatar_path;
		_tmp9_ = g_strdup (_tmp8_);
		_g_free0 (_vala_avatar_path);
		_vala_avatar_path = _tmp9_;
		if (name) {
			*name = _vala_name;
		} else {
			_g_free0 (_vala_name);
		}
		if (avatar_path) {
			*avatar_path = _vala_avatar_path;
		} else {
			_g_free0 (_vala_avatar_path);
		}
		return;
	}
	_tmp11_ = self->priv->reaction_roster;
	if (_tmp11_ != NULL) {
		DcMentionRoster* _tmp12_;
		DcMentionMember* _tmp13_;
		_tmp12_ = self->priv->reaction_roster;
		_tmp13_ = dc_mention_roster_lookup_contact (_tmp12_, contact_id);
		_g_object_unref0 (_tmp10_);
		_tmp10_ = _tmp13_;
	} else {
		_g_object_unref0 (_tmp10_);
		_tmp10_ = NULL;
	}
	_tmp14_ = _tmp10_;
	_tmp10_ = NULL;
	member = _tmp14_;
	_tmp15_ = member;
	if (_tmp15_ != NULL) {
		gchar* _tmp16_ = NULL;
		DcMentionMember* _tmp17_;
		const gchar* _tmp18_;
		const gchar* _tmp19_;
		gint _tmp20_;
		gint _tmp21_;
		gchar* _tmp38_;
		DcMentionMember* _tmp39_;
		const gchar* _tmp40_;
		const gchar* _tmp41_;
		gchar* _tmp42_;
		_tmp17_ = member;
		_tmp18_ = dc_mention_member_get_display_name (_tmp17_);
		_tmp19_ = _tmp18_;
		_tmp20_ = strlen (_tmp19_);
		_tmp21_ = _tmp20_;
		if (_tmp21_ > 0) {
			DcMentionMember* _tmp22_;
			const gchar* _tmp23_;
			const gchar* _tmp24_;
			gchar* _tmp25_;
			_tmp22_ = member;
			_tmp23_ = dc_mention_member_get_display_name (_tmp22_);
			_tmp24_ = _tmp23_;
			_tmp25_ = g_strdup (_tmp24_);
			_g_free0 (_tmp16_);
			_tmp16_ = _tmp25_;
		} else {
			gchar* _tmp26_ = NULL;
			DcMentionMember* _tmp27_;
			const gchar* _tmp28_;
			const gchar* _tmp29_;
			gint _tmp30_;
			gint _tmp31_;
			gchar* _tmp37_;
			_tmp27_ = member;
			_tmp28_ = dc_mention_member_get_address (_tmp27_);
			_tmp29_ = _tmp28_;
			_tmp30_ = strlen (_tmp29_);
			_tmp31_ = _tmp30_;
			if (_tmp31_ > 0) {
				DcMentionMember* _tmp32_;
				const gchar* _tmp33_;
				const gchar* _tmp34_;
				gchar* _tmp35_;
				_tmp32_ = member;
				_tmp33_ = dc_mention_member_get_address (_tmp32_);
				_tmp34_ = _tmp33_;
				_tmp35_ = g_strdup (_tmp34_);
				_g_free0 (_tmp26_);
				_tmp26_ = _tmp35_;
			} else {
				gchar* _tmp36_;
				_tmp36_ = g_strdup_printf ("Contact %d", contact_id);
				_g_free0 (_tmp26_);
				_tmp26_ = _tmp36_;
			}
			_tmp37_ = _tmp26_;
			_tmp26_ = NULL;
			_g_free0 (_tmp16_);
			_tmp16_ = _tmp37_;
			_g_free0 (_tmp26_);
		}
		_tmp38_ = _tmp16_;
		_tmp16_ = NULL;
		_g_free0 (_vala_name);
		_vala_name = _tmp38_;
		_tmp39_ = member;
		_tmp40_ = dc_mention_member_get_avatar_path (_tmp39_);
		_tmp41_ = _tmp40_;
		_tmp42_ = g_strdup (_tmp41_);
		_g_free0 (_vala_avatar_path);
		_vala_avatar_path = _tmp42_;
		_g_free0 (_tmp16_);
		_g_object_unref0 (member);
		_g_object_unref0 (_tmp10_);
		if (name) {
			*name = _vala_name;
		} else {
			_g_free0 (_vala_name);
		}
		if (avatar_path) {
			*avatar_path = _vala_avatar_path;
		} else {
			_g_free0 (_vala_avatar_path);
		}
		return;
	}
	_tmp45_ = dc_message_get_is_outgoing (msg);
	_tmp46_ = _tmp45_;
	if (!_tmp46_) {
		_tmp44_ = contact_id > 0;
	} else {
		_tmp44_ = FALSE;
	}
	if (_tmp44_) {
		gint _tmp47_;
		gint _tmp48_;
		_tmp47_ = dc_message_get_sender_contact_id (msg);
		_tmp48_ = _tmp47_;
		_tmp43_ = contact_id == _tmp48_;
	} else {
		_tmp43_ = FALSE;
	}
	if (_tmp43_) {
		gchar* author = NULL;
		gchar* _tmp49_;
		const gchar* _tmp50_ = NULL;
		const gchar* _tmp51_;
		gchar* _tmp55_;
		const gchar* _tmp56_;
		const gchar* _tmp57_;
		gchar* _tmp58_;
		_tmp49_ = dc_message_row_effective_author_name (msg);
		author = _tmp49_;
		_tmp51_ = author;
		_tmp50_ = _tmp51_;
		if (_tmp50_ == NULL) {
			const gchar* _tmp52_ = NULL;
			const gchar* _tmp53_;
			const gchar* _tmp54_;
			_tmp53_ = dc_message_get_sender_address (msg);
			_tmp54_ = _tmp53_;
			_tmp52_ = _tmp54_;
			if (_tmp52_ == NULL) {
				_tmp52_ = "Contact";
			}
			_tmp50_ = _tmp52_;
		}
		_tmp55_ = g_strdup (_tmp50_);
		_g_free0 (_vala_name);
		_vala_name = _tmp55_;
		_tmp56_ = dc_message_get_sender_avatar_path (msg);
		_tmp57_ = _tmp56_;
		_tmp58_ = g_strdup (_tmp57_);
		_g_free0 (_vala_avatar_path);
		_vala_avatar_path = _tmp58_;
		_g_free0 (author);
		_g_object_unref0 (member);
		_g_object_unref0 (_tmp10_);
		if (name) {
			*name = _vala_name;
		} else {
			_g_free0 (_vala_name);
		}
		if (avatar_path) {
			*avatar_path = _vala_avatar_path;
		} else {
			_g_free0 (_vala_avatar_path);
		}
		return;
	}
	if (contact_id > 0) {
		gchar* _tmp60_;
		_tmp60_ = g_strdup_printf ("Contact %d", contact_id);
		_g_free0 (_tmp59_);
		_tmp59_ = _tmp60_;
	} else {
		gchar* _tmp61_;
		_tmp61_ = g_strdup ("Unknown user");
		_g_free0 (_tmp59_);
		_tmp59_ = _tmp61_;
	}
	_tmp62_ = _tmp59_;
	_tmp59_ = NULL;
	_g_free0 (_vala_name);
	_vala_name = _tmp62_;
	_g_free0 (_tmp59_);
	_g_object_unref0 (member);
	_g_object_unref0 (_tmp10_);
	if (name) {
		*name = _vala_name;
	} else {
		_g_free0 (_vala_name);
	}
	if (avatar_path) {
		*avatar_path = _vala_avatar_path;
	} else {
		_g_free0 (_vala_avatar_path);
	}
}

static gchar*
dc_message_row_format_timestamp (gint64 ts)
{
	GDateTime* dt = NULL;
	GDateTime* _tmp1_;
	GDateTime* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	if (ts <= ((gint64) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup ("");
		result = _tmp0_;
		return result;
	}
	_tmp1_ = g_date_time_new_from_unix_local (ts);
	dt = _tmp1_;
	_tmp2_ = dt;
	_tmp3_ = g_date_time_format (_tmp2_, "%H:%M");
	result = _tmp3_;
	_g_date_time_unref0 (dt);
	return result;
}

/** Build a centered date-separator label, styled like info rows. */
GtkWidget*
dc_message_row_build_date_separator (gint64 ts)
{
	GtkLabel* label = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	GtkLabel* _tmp2_;
	GtkLabel* _tmp3_;
	GtkWidget* result;
	_tmp0_ = dc_message_row_format_date_label (ts);
	_tmp1_ = _tmp0_;
	_tmp2_ = (GtkLabel*) gtk_label_new (_tmp1_);
	g_object_ref_sink (_tmp2_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	label = _tmp3_;
	gtk_widget_add_css_class ((GtkWidget*) label, "dim-label");
	gtk_widget_add_css_class ((GtkWidget*) label, "caption");
	gtk_widget_set_hexpand ((GtkWidget*) label, TRUE);
	gtk_widget_set_halign ((GtkWidget*) label, GTK_ALIGN_CENTER);
	gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
	gtk_widget_set_margin_top ((GtkWidget*) label, 8);
	gtk_widget_set_margin_bottom ((GtkWidget*) label, 4);
	result = (GtkWidget*) label;
	return result;
}

/** Format a timestamp as a date label: "3 June" (current year) or
            "3 June 2023" (other years). */
gchar*
dc_message_row_format_date_label (gint64 ts)
{
	GDateTime* dt = NULL;
	GDateTime* _tmp1_;
	GDateTime* now = NULL;
	GDateTime* _tmp2_;
	gint day = 0;
	GDateTime* _tmp3_;
	gchar* month = NULL;
	GDateTime* _tmp4_;
	gchar* _tmp5_;
	GDateTime* _tmp6_;
	GDateTime* _tmp7_;
	const gchar* _tmp10_;
	GDateTime* _tmp11_;
	gchar* _tmp12_;
	gchar* result;
	if (ts <= ((gint64) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup ("");
		result = _tmp0_;
		return result;
	}
	_tmp1_ = g_date_time_new_from_unix_local (ts);
	dt = _tmp1_;
	_tmp2_ = g_date_time_new_now_local ();
	now = _tmp2_;
	_tmp3_ = dt;
	day = g_date_time_get_day_of_month (_tmp3_);
	_tmp4_ = dt;
	_tmp5_ = g_date_time_format (_tmp4_, "%B");
	month = _tmp5_;
	_tmp6_ = dt;
	_tmp7_ = now;
	if (g_date_time_get_year (_tmp6_) == g_date_time_get_year (_tmp7_)) {
		const gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp8_ = month;
		_tmp9_ = g_strdup_printf ("%d %s", day, _tmp8_);
		result = _tmp9_;
		_g_free0 (month);
		_g_date_time_unref0 (now);
		_g_date_time_unref0 (dt);
		return result;
	}
	_tmp10_ = month;
	_tmp11_ = dt;
	_tmp12_ = g_strdup_printf ("%d %s %d", day, _tmp10_, g_date_time_get_year (_tmp11_));
	result = _tmp12_;
	_g_free0 (month);
	_g_date_time_unref0 (now);
	_g_date_time_unref0 (dt);
	return result;
}

/** True when two unix timestamps fall on the same calendar day. */
gboolean
dc_message_row_same_day (gint64 ts1,
                         gint64 ts2)
{
	gboolean _tmp0_ = FALSE;
	GDateTime* dt1 = NULL;
	GDateTime* _tmp1_;
	GDateTime* dt2 = NULL;
	GDateTime* _tmp2_;
	gboolean _tmp3_ = FALSE;
	GDateTime* _tmp4_;
	GDateTime* _tmp5_;
	gboolean result;
	if (ts1 <= ((gint64) 0)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = ts2 <= ((gint64) 0);
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	_tmp1_ = g_date_time_new_from_unix_local (ts1);
	dt1 = _tmp1_;
	_tmp2_ = g_date_time_new_from_unix_local (ts2);
	dt2 = _tmp2_;
	_tmp4_ = dt1;
	_tmp5_ = dt2;
	if (g_date_time_get_year (_tmp4_) == g_date_time_get_year (_tmp5_)) {
		GDateTime* _tmp6_;
		GDateTime* _tmp7_;
		_tmp6_ = dt1;
		_tmp7_ = dt2;
		_tmp3_ = g_date_time_get_day_of_year (_tmp6_) == g_date_time_get_day_of_year (_tmp7_);
	} else {
		_tmp3_ = FALSE;
	}
	result = _tmp3_;
	_g_date_time_unref0 (dt2);
	_g_date_time_unref0 (dt1);
	return result;
}

gint
dc_message_row_get_message_id (DcMessageRow* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_message_id;
	return result;
}

static void
dc_message_row_set_message_id (DcMessageRow* self,
                               gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_message_row_get_message_id (self);
	if (old_value != value) {
		self->priv->_message_id = value;
		g_object_notify_by_pspec ((GObject *) self, dc_message_row_properties[DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY]);
	}
}

gboolean
dc_message_row_get_is_outgoing (DcMessageRow* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_outgoing;
	return result;
}

static void
dc_message_row_set_is_outgoing (DcMessageRow* self,
                                gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_message_row_get_is_outgoing (self);
	if (old_value != value) {
		self->priv->_is_outgoing = value;
		g_object_notify_by_pspec ((GObject *) self, dc_message_row_properties[DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY]);
	}
}

DcAudioPlayer*
dc_message_row_get_audio_player (DcMessageRow* self)
{
	DcAudioPlayer* result;
	DcAudioPlayer* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_audio_player;
	result = _tmp0_;
	return result;
}

static void
dc_message_row_set_audio_player (DcMessageRow* self,
                                 DcAudioPlayer* value)
{
	DcAudioPlayer* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_message_row_get_audio_player (self);
	if (old_value != value) {
		DcAudioPlayer* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_audio_player);
		self->priv->_audio_player = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_message_row_properties[DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY]);
	}
}

static void
g_cclosure_user_marshal_VOID__STRING_OBJECT (GClosure * closure,
                                             GValue * return_value,
                                             guint n_param_values,
                                             const GValue * param_values,
                                             gpointer invocation_hint,
                                             gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__STRING_OBJECT) (gpointer data1, const char* arg_1, gpointer arg_2, gpointer data2);
	register GMarshalFunc_VOID__STRING_OBJECT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__STRING_OBJECT) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_string (param_values + 1), g_value_get_object (param_values + 2), data2);
}

static void
g_cclosure_user_marshal_VOID__INT_BOOLEAN (GClosure * closure,
                                           GValue * return_value,
                                           guint n_param_values,
                                           const GValue * param_values,
                                           gpointer invocation_hint,
                                           gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__INT_BOOLEAN) (gpointer data1, gint arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_VOID__INT_BOOLEAN callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__INT_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_int (param_values + 1), g_value_get_boolean (param_values + 2), data2);
}

static void
g_cclosure_user_marshal_VOID__INT_STRING (GClosure * closure,
                                          GValue * return_value,
                                          guint n_param_values,
                                          const GValue * param_values,
                                          gpointer invocation_hint,
                                          gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__INT_STRING) (gpointer data1, gint arg_1, const char* arg_2, gpointer data2);
	register GMarshalFunc_VOID__INT_STRING callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__INT_STRING) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_int (param_values + 1), g_value_get_string (param_values + 2), data2);
}

static gchar**
_vala_array_dup7 (gchar** self,
                  gssize length)
{
	if (length >= 0) {
		gchar** result;
		gssize i;
		result = g_new0 (gchar*, length + 1);
		for (i = 0; i < length; i++) {
			gchar* _tmp0_;
			_tmp0_ = g_strdup (self[i]);
			result[i] = _tmp0_;
		}
		return result;
	}
	return NULL;
}

static DcMessageRowMarkdownTableRow*
dc_message_row_markdown_table_row_construct (GType object_type,
                                             gchar** cells,
                                             gint cells_length1,
                                             gboolean header)
{
	DcMessageRowMarkdownTableRow* self = NULL;
	gchar** _tmp0_;
	gint _tmp0__length1;
	self = (DcMessageRowMarkdownTableRow*) g_type_create_instance (object_type);
	_tmp0_ = (cells != NULL) ? _vala_array_dup7 (cells, cells_length1) : cells;
	_tmp0__length1 = cells_length1;
	self->cells = (_vala_array_free (self->cells, self->cells_length1, (GDestroyNotify) g_free), NULL);
	self->cells = _tmp0_;
	self->cells_length1 = _tmp0__length1;
	self->_cells_size_ = self->cells_length1;
	self->header = header;
	return self;
}

static DcMessageRowMarkdownTableRow*
dc_message_row_markdown_table_row_new (gchar** cells,
                                       gint cells_length1,
                                       gboolean header)
{
	return dc_message_row_markdown_table_row_construct (DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW, cells, cells_length1, header);
}

static void
dc_message_row_value_markdown_table_row_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
dc_message_row_value_markdown_table_row_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		dc_message_row_markdown_table_row_unref (value->data[0].v_pointer);
	}
}

static void
dc_message_row_value_markdown_table_row_copy_value (const GValue* src_value,
                                                    GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = dc_message_row_markdown_table_row_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
dc_message_row_value_markdown_table_row_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
dc_message_row_value_markdown_table_row_collect_value (GValue* value,
                                                       guint n_collect_values,
                                                       GTypeCValue* collect_values,
                                                       guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DcMessageRowMarkdownTableRow * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = dc_message_row_markdown_table_row_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
dc_message_row_value_markdown_table_row_lcopy_value (const GValue* value,
                                                     guint n_collect_values,
                                                     GTypeCValue* collect_values,
                                                     guint collect_flags)
{
	DcMessageRowMarkdownTableRow ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = dc_message_row_markdown_table_row_ref (value->data[0].v_pointer);
	}
	return NULL;
}

static GParamSpec*
dc_message_row_param_spec_markdown_table_row (const gchar* name,
                                              const gchar* nick,
                                              const gchar* blurb,
                                              GType object_type,
                                              GParamFlags flags)
{
	DcMessageRowParamSpecMarkdownTableRow* spec;
	g_return_val_if_fail (g_type_is_a (object_type, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

static gpointer
dc_message_row_value_get_markdown_table_row (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW), NULL);
	return value->data[0].v_pointer;
}

static void
dc_message_row_value_set_markdown_table_row (GValue* value,
                                             gpointer v_object)
{
	DcMessageRowMarkdownTableRow * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		dc_message_row_markdown_table_row_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_message_row_markdown_table_row_unref (old);
	}
}

static void
dc_message_row_value_take_markdown_table_row (GValue* value,
                                              gpointer v_object)
{
	DcMessageRowMarkdownTableRow * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_message_row_markdown_table_row_unref (old);
	}
}

static void
dc_message_row_markdown_table_row_class_init (DcMessageRowMarkdownTableRowClass * klass,
                                              gpointer klass_data)
{
	dc_message_row_markdown_table_row_parent_class = g_type_class_peek_parent (klass);
	((DcMessageRowMarkdownTableRowClass *) klass)->finalize = dc_message_row_markdown_table_row_finalize;
}

static void
dc_message_row_markdown_table_row_instance_init (DcMessageRowMarkdownTableRow * self,
                                                 gpointer klass)
{
	self->ref_count = 1;
}

static void
dc_message_row_markdown_table_row_finalize (DcMessageRowMarkdownTableRow * obj)
{
	DcMessageRowMarkdownTableRow * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_ROW, DcMessageRowMarkdownTableRow);
	g_signal_handlers_destroy (self);
	self->cells = (_vala_array_free (self->cells, self->cells_length1, (GDestroyNotify) g_free), NULL);
}

static GType
dc_message_row_markdown_table_row_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { dc_message_row_value_markdown_table_row_init, dc_message_row_value_markdown_table_row_free_value, dc_message_row_value_markdown_table_row_copy_value, dc_message_row_value_markdown_table_row_peek_pointer, "p", dc_message_row_value_markdown_table_row_collect_value, "p", dc_message_row_value_markdown_table_row_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DcMessageRowMarkdownTableRowClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_message_row_markdown_table_row_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcMessageRowMarkdownTableRow), 0, (GInstanceInitFunc) dc_message_row_markdown_table_row_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType dc_message_row_markdown_table_row_type_id;
	dc_message_row_markdown_table_row_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DcMessageRowMarkdownTableRow", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return dc_message_row_markdown_table_row_type_id;
}

static GType
dc_message_row_markdown_table_row_get_type (void)
{
	static volatile gsize dc_message_row_markdown_table_row_type_id__once = 0;
	if (g_once_init_enter (&dc_message_row_markdown_table_row_type_id__once)) {
		GType dc_message_row_markdown_table_row_type_id;
		dc_message_row_markdown_table_row_type_id = dc_message_row_markdown_table_row_get_type_once ();
		g_once_init_leave (&dc_message_row_markdown_table_row_type_id__once, dc_message_row_markdown_table_row_type_id);
	}
	return dc_message_row_markdown_table_row_type_id__once;
}

static gpointer
dc_message_row_markdown_table_row_ref (gpointer instance)
{
	DcMessageRowMarkdownTableRow * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

static void
dc_message_row_markdown_table_row_unref (gpointer instance)
{
	DcMessageRowMarkdownTableRow * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DC_MESSAGE_ROW_MARKDOWN_TABLE_ROW_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static void
_dc_message_row_markdown_table_row_unref0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (dc_message_row_markdown_table_row_unref (var), NULL));
}

static DcMessageRowMarkdownTableBlock*
dc_message_row_markdown_table_block_construct (GType object_type,
                                               gint columns)
{
	DcMessageRowMarkdownTableBlock* self = NULL;
	gint* _tmp0_;
	self = (DcMessageRowMarkdownTableBlock*) g_type_create_instance (object_type);
	_tmp0_ = g_new0 (gint, columns);
	self->aligns = (g_free (self->aligns), NULL);
	self->aligns = _tmp0_;
	self->aligns_length1 = columns;
	self->_aligns_size_ = self->aligns_length1;
	return self;
}

static DcMessageRowMarkdownTableBlock*
dc_message_row_markdown_table_block_new (gint columns)
{
	return dc_message_row_markdown_table_block_construct (DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK, columns);
}

static void
dc_message_row_value_markdown_table_block_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
dc_message_row_value_markdown_table_block_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		dc_message_row_markdown_table_block_unref (value->data[0].v_pointer);
	}
}

static void
dc_message_row_value_markdown_table_block_copy_value (const GValue* src_value,
                                                      GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = dc_message_row_markdown_table_block_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
dc_message_row_value_markdown_table_block_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
dc_message_row_value_markdown_table_block_collect_value (GValue* value,
                                                         guint n_collect_values,
                                                         GTypeCValue* collect_values,
                                                         guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DcMessageRowMarkdownTableBlock * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = dc_message_row_markdown_table_block_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
dc_message_row_value_markdown_table_block_lcopy_value (const GValue* value,
                                                       guint n_collect_values,
                                                       GTypeCValue* collect_values,
                                                       guint collect_flags)
{
	DcMessageRowMarkdownTableBlock ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = dc_message_row_markdown_table_block_ref (value->data[0].v_pointer);
	}
	return NULL;
}

static GParamSpec*
dc_message_row_param_spec_markdown_table_block (const gchar* name,
                                                const gchar* nick,
                                                const gchar* blurb,
                                                GType object_type,
                                                GParamFlags flags)
{
	DcMessageRowParamSpecMarkdownTableBlock* spec;
	g_return_val_if_fail (g_type_is_a (object_type, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

static gpointer
dc_message_row_value_get_markdown_table_block (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK), NULL);
	return value->data[0].v_pointer;
}

static void
dc_message_row_value_set_markdown_table_block (GValue* value,
                                               gpointer v_object)
{
	DcMessageRowMarkdownTableBlock * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		dc_message_row_markdown_table_block_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_message_row_markdown_table_block_unref (old);
	}
}

static void
dc_message_row_value_take_markdown_table_block (GValue* value,
                                                gpointer v_object)
{
	DcMessageRowMarkdownTableBlock * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_message_row_markdown_table_block_unref (old);
	}
}

static void
dc_message_row_markdown_table_block_class_init (DcMessageRowMarkdownTableBlockClass * klass,
                                                gpointer klass_data)
{
	dc_message_row_markdown_table_block_parent_class = g_type_class_peek_parent (klass);
	((DcMessageRowMarkdownTableBlockClass *) klass)->finalize = dc_message_row_markdown_table_block_finalize;
}

static void
dc_message_row_markdown_table_block_instance_init (DcMessageRowMarkdownTableBlock * self,
                                                   gpointer klass)
{
	GPtrArray* _tmp0_;
	_tmp0_ = g_ptr_array_new_full ((guint) 0, _dc_message_row_markdown_table_row_unref0_);
	self->rows = _tmp0_;
	self->ref_count = 1;
}

static void
dc_message_row_markdown_table_block_finalize (DcMessageRowMarkdownTableBlock * obj)
{
	DcMessageRowMarkdownTableBlock * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_MESSAGE_ROW_TYPE_MARKDOWN_TABLE_BLOCK, DcMessageRowMarkdownTableBlock);
	g_signal_handlers_destroy (self);
	_g_ptr_array_unref0 (self->rows);
	self->aligns = (g_free (self->aligns), NULL);
}

static GType
dc_message_row_markdown_table_block_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { dc_message_row_value_markdown_table_block_init, dc_message_row_value_markdown_table_block_free_value, dc_message_row_value_markdown_table_block_copy_value, dc_message_row_value_markdown_table_block_peek_pointer, "p", dc_message_row_value_markdown_table_block_collect_value, "p", dc_message_row_value_markdown_table_block_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DcMessageRowMarkdownTableBlockClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_message_row_markdown_table_block_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcMessageRowMarkdownTableBlock), 0, (GInstanceInitFunc) dc_message_row_markdown_table_block_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType dc_message_row_markdown_table_block_type_id;
	dc_message_row_markdown_table_block_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DcMessageRowMarkdownTableBlock", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return dc_message_row_markdown_table_block_type_id;
}

static GType
dc_message_row_markdown_table_block_get_type (void)
{
	static volatile gsize dc_message_row_markdown_table_block_type_id__once = 0;
	if (g_once_init_enter (&dc_message_row_markdown_table_block_type_id__once)) {
		GType dc_message_row_markdown_table_block_type_id;
		dc_message_row_markdown_table_block_type_id = dc_message_row_markdown_table_block_get_type_once ();
		g_once_init_leave (&dc_message_row_markdown_table_block_type_id__once, dc_message_row_markdown_table_block_type_id);
	}
	return dc_message_row_markdown_table_block_type_id__once;
}

static gpointer
dc_message_row_markdown_table_block_ref (gpointer instance)
{
	DcMessageRowMarkdownTableBlock * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

static void
dc_message_row_markdown_table_block_unref (gpointer instance)
{
	DcMessageRowMarkdownTableBlock * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DC_MESSAGE_ROW_MARKDOWN_TABLE_BLOCK_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static void
dc_message_row_class_init (DcMessageRowClass * klass,
                           gpointer klass_data)
{
	dc_message_row_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcMessageRow_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_dc_message_row_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_dc_message_row_set_property;
	G_OBJECT_CLASS (klass)->finalize = dc_message_row_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY, dc_message_row_properties[DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY] = g_param_spec_int ("message-id", "message-id", "message-id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY, dc_message_row_properties[DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY] = g_param_spec_boolean ("is-outgoing", "is-outgoing", "is-outgoing", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY, dc_message_row_properties[DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY] = g_param_spec_object ("audio-player", "audio-player", "audio-player", DC_TYPE_AUDIO_PLAYER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	dc_message_row_signals[DC_MESSAGE_ROW_QUOTE_CLICKED_SIGNAL] = g_signal_new ("quote-clicked", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
	dc_message_row_signals[DC_MESSAGE_ROW_ACTION_REQUESTED_SIGNAL] = g_signal_new ("action-requested", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_OBJECT, G_TYPE_NONE, 2, G_TYPE_STRING, gtk_widget_get_type ());
	dc_message_row_signals[DC_MESSAGE_ROW_FULL_MESSAGE_REQUESTED_SIGNAL] = g_signal_new ("full-message-requested", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
	dc_message_row_signals[DC_MESSAGE_ROW_FULL_MESSAGE_VIEW_REQUESTED_SIGNAL] = g_signal_new ("full-message-view-requested", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
	dc_message_row_signals[DC_MESSAGE_ROW_SELECTION_TOGGLED_SIGNAL] = g_signal_new ("selection-toggled", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__INT_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN);
	dc_message_row_signals[DC_MESSAGE_ROW_CHECKBOX_TOGGLE_REQUESTED_SIGNAL] = g_signal_new ("checkbox-toggle-requested", DC_TYPE_MESSAGE_ROW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__INT_STRING, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
}

static void
dc_message_row_instance_init (DcMessageRow * self,
                              gpointer klass)
{
	self->priv = dc_message_row_get_instance_private (self);
	self->priv->_audio_player = NULL;
	self->priv->mention_roster = NULL;
	self->priv->reaction_roster = NULL;
	self->priv->account_id = 0;
}

static void
dc_message_row_finalize (GObject * obj)
{
	DcMessageRow * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_MESSAGE_ROW, DcMessageRow);
	_g_object_unref0 (self->priv->_audio_player);
	_g_object_unref0 (self->priv->mention_roster);
	_g_object_unref0 (self->priv->reaction_roster);
	G_OBJECT_CLASS (dc_message_row_parent_class)->finalize (obj);
}

/**
     * A single message bubble in the conversation view.
     * Incoming messages are left-aligned, outgoing messages right-aligned.
     */
static GType
dc_message_row_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcMessageRowClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_message_row_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcMessageRow), 0, (GInstanceInitFunc) dc_message_row_instance_init, NULL };
	GType dc_message_row_type_id;
	dc_message_row_type_id = g_type_register_static (gtk_box_get_type (), "DcMessageRow", &g_define_type_info, 0);
	DcMessageRow_private_offset = g_type_add_instance_private (dc_message_row_type_id, sizeof (DcMessageRowPrivate));
	return dc_message_row_type_id;
}

GType
dc_message_row_get_type (void)
{
	static volatile gsize dc_message_row_type_id__once = 0;
	if (g_once_init_enter (&dc_message_row_type_id__once)) {
		GType dc_message_row_type_id;
		dc_message_row_type_id = dc_message_row_get_type_once ();
		g_once_init_leave (&dc_message_row_type_id__once, dc_message_row_type_id);
	}
	return dc_message_row_type_id__once;
}

static void
_vala_dc_message_row_get_property (GObject * object,
                                   guint property_id,
                                   GValue * value,
                                   GParamSpec * pspec)
{
	DcMessageRow * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_MESSAGE_ROW, DcMessageRow);
	switch (property_id) {
		case DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY:
		g_value_set_int (value, dc_message_row_get_message_id (self));
		break;
		case DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY:
		g_value_set_boolean (value, dc_message_row_get_is_outgoing (self));
		break;
		case DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY:
		g_value_set_object (value, dc_message_row_get_audio_player (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_dc_message_row_set_property (GObject * object,
                                   guint property_id,
                                   const GValue * value,
                                   GParamSpec * pspec)
{
	DcMessageRow * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_MESSAGE_ROW, DcMessageRow);
	switch (property_id) {
		case DC_MESSAGE_ROW_MESSAGE_ID_PROPERTY:
		dc_message_row_set_message_id (self, g_value_get_int (value));
		break;
		case DC_MESSAGE_ROW_IS_OUTGOING_PROPERTY:
		dc_message_row_set_is_outgoing (self, g_value_get_boolean (value));
		break;
		case DC_MESSAGE_ROW_AUDIO_PLAYER_PROPERTY:
		dc_message_row_set_audio_player (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

