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

/*
 * Copyright (c) 2025 focus-timer contributors
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 * Authors: Kamil Prusko <kamilprusko@gmail.com>
 */

#include "ft_ui.h"
#include <glib.h>
#include <gtk/gtk.h>
#include <float.h>
#include <math.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gdk/gdk.h>
#include "ft_core.h"
#include <adwaita.h>
#include <graphene-gobject.h>
#include <gsk/gsk.h>
#include <cairo-gobject.h>

#define FT_BUBBLE_CHART_MIN_BUBBLE_SIZE 16
#define FT_BUBBLE_CHART_MAX_BUBBLE_SIZE 42
#define FT_BUBBLE_CHART_BUBBLE_SPACING 0.2f
#define FT_BUBBLE_CHART_MIN_BUBBLE_RADIUS 0.01f
#define FT_BUBBLE_CHART_MIN_BUBBLE_VALUE 60.0f
#define FT_BUBBLE_CHART_BASE_RADIUS 4.0f
#define FT_BUBBLE_CHART_DEFAULT_VALUE 0.0
#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

#define FT_TYPE_CATEGORY (ft_category_get_type ())
typedef struct _FtCategory FtCategory;

#define FT_TYPE_BUCKET (ft_bucket_get_type ())
typedef struct _FtBucket FtBucket;
enum  {
	FT_BUBBLE_CHART_0_PROPERTY,
	FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY,
	FT_BUBBLE_CHART_CATEGORY_PROPERTY,
	FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY,
	FT_BUBBLE_CHART_LEVELS_PROPERTY,
	FT_BUBBLE_CHART_NUM_PROPERTIES
};
static GParamSpec* ft_bubble_chart_properties[FT_BUBBLE_CHART_NUM_PROPERTIES];
#define _ft_matrix3_d_free0(var) ((var == NULL) ? NULL : (var = (ft_matrix3_d_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _ft_matrix_free0(var) ((var == NULL) ? NULL : (var = (ft_matrix_free (var), NULL)))
typedef struct _FtGizmo FtGizmo;
typedef struct _FtGizmoClass FtGizmoClass;
#define _gsk_path_unref0(var) ((var == NULL) ? NULL : (var = (gsk_path_unref (var), NULL)))
#define __vala_GskStroke_free0(var) ((var == NULL) ? NULL : (var = (_vala_GskStroke_free (var), NULL)))
#define _gsk_path_builder_unref0(var) ((var == NULL) ? NULL : (var = (gsk_path_builder_unref (var), NULL)))
typedef struct _Block6Data Block6Data;
enum  {
	FT_BUBBLE_CHART_BUBBLE_ACTIVATED_SIGNAL,
	FT_BUBBLE_CHART_NUM_SIGNALS
};
static guint ft_bubble_chart_signals[FT_BUBBLE_CHART_NUM_SIGNALS] = {0};

struct _FtCategory {
	gchar* label;
	GdkRGBA color;
	FtUnit unit;
	gboolean visible;
};

struct _FtBucket {
	gchar* label;
	gchar* tooltip_label;
};

struct _FtBubbleChartPrivate {
	gboolean _activate_on_click;
	GtkGrid* layout_grid;
	GtkBox* columns_box;
	GtkBox* rows_box;
	GtkGrid* bubbles_grid;
	gdouble _reference_value;
	guint _category;
	guint _levels;
	FtCategory* categories;
	gint categories_length1;
	gint _categories_size_;
	FtBucket* buckets;
	gint buckets_length1;
	gint buckets_length2;
	FtMatrix3D* data;
	gdouble max_value;
	gint bubble_size;
	gfloat* level_radii;
	gint level_radii_length1;
	gint _level_radii_size_;
	gint tooltip_row;
	gint tooltip_column;
	GtkWidget* tooltip_widget;
	gchar** rows_labels;
	gint rows_labels_length1;
	gint _rows_labels_size_;
	gchar** columns_labels;
	gint columns_labels_length1;
	gint _columns_labels_size_;
	guint update_idle_id;
};

struct _Block6Data {
	int _ref_count_;
	FtBubbleChart* self;
	FtGizmo* weak_bubble;
};

static gint FtBubbleChart_private_offset;
static gpointer ft_bubble_chart_parent_class = NULL;

VALA_EXTERN GType ft_category_get_type (void) G_GNUC_CONST ;
VALA_EXTERN FtCategory* ft_category_dup (const FtCategory* self);
VALA_EXTERN void ft_category_free (FtCategory* self);
VALA_EXTERN void ft_category_copy (const FtCategory* self,
                       FtCategory* dest);
VALA_EXTERN void ft_category_destroy (FtCategory* self);
VALA_EXTERN GType ft_bucket_get_type (void) G_GNUC_CONST ;
VALA_EXTERN FtBucket* ft_bucket_dup (const FtBucket* self);
VALA_EXTERN void ft_bucket_free (FtBucket* self);
VALA_EXTERN void ft_bucket_copy (const FtBucket* self,
                     FtBucket* dest);
VALA_EXTERN void ft_bucket_destroy (FtBucket* self);
static void _vala_FtCategory_array_free (FtCategory * array,
                                  gssize array_length);
static void _vala_FtBucket_array_free (FtBucket * array,
                                gssize array_length);
static inline gchar* ft_bubble_chart_format_tooltip_value (FtBubbleChart* self,
                                             guint category_index,
                                             gdouble value);
static inline gdouble ft_bubble_chart_calculate_max_value (FtBubbleChart* self);
static inline gfloat ft_bubble_chart_calculate_bubble_radius (FtBubbleChart* self,
                                                gdouble bubble_value);
static void ft_bubble_chart_update_level_radii (FtBubbleChart* self);
static void ft_bubble_chart_invalidate_max_value (FtBubbleChart* self);
static void ft_bubble_chart_ensure_max_value (FtBubbleChart* self);
static void ft_bubble_chart_ensure_categories (FtBubbleChart* self,
                                        guint count);
static gboolean ft_bubble_chart_grow_buckets (FtBubbleChart* self,
                                       guint rows,
                                       guint columns);
static FtBucket* _vala_array_dup1 (FtBucket* self,
                            gssize length);
static gboolean ft_bubble_chart_grow_data (FtBubbleChart* self,
                                    guint row_count,
                                    guint column_count,
                                    guint category_count);
static void ft_bubble_chart_queue_update (FtBubbleChart* self);
static void ft_bubble_chart_queue_draw_bubbles (FtBubbleChart* self);
static void ft_bubble_chart_queue_resize_bubbles (FtBubbleChart* self);
static void ft_bubble_chart_ensure_bubble (FtBubbleChart* self,
                                    guint row,
                                    guint column);
static GtkWidget* ft_bubble_chart_create_bubble (FtBubbleChart* self,
                                          guint row,
                                          guint column);
static gchar* ft_bubble_chart_get_tooltip_label (FtBubbleChart* self,
                                          guint row,
                                          guint column);
static void ft_bubble_chart_update_bubbles (FtBubbleChart* self);
static void ft_bubble_chart_update_rows_labels (FtBubbleChart* self);
static void ft_bubble_chart_update_columns_labels (FtBubbleChart* self);
static void ft_bubble_chart_update (FtBubbleChart* self);
static gboolean __lambda18_ (FtBubbleChart* self);
static gboolean ___lambda18__gtk_tick_callback (GtkWidget* widget,
                                         GdkFrameClock* frame_clock,
                                         gpointer self);
static inline void ft_bubble_chart_ensure_rows (FtBubbleChart* self,
                                  guint count);
static inline void ft_bubble_chart_ensure_columns (FtBubbleChart* self,
                                     guint count);
static GtkWidget* ft_bubble_chart_create_tooltip_widget (FtBubbleChart* self,
                                                  guint row,
                                                  guint column);
static void ft_bubble_chart_measure_bubble (FtBubbleChart* self,
                                     FtGizmo* gizmo,
                                     GtkOrientation orientation,
                                     gint for_size,
                                     gint* minimum,
                                     gint* natural,
                                     gint* minimum_baseline,
                                     gint* natural_baseline);
static void ft_bubble_chart_snapshot_bubble (FtBubbleChart* self,
                                      FtGizmo* gizmo,
                                      GtkSnapshot* snapshot);
static void _vala_GskStroke_free (GskStroke* self);
static gboolean ft_bubble_chart_contains_bubble (FtBubbleChart* self,
                                          FtGizmo* gizmo,
                                          gdouble x,
                                          gdouble y);
static void ft_bubble_chart_measure_bubble_cb (FtGizmo* gizmo,
                                        GtkOrientation orientation,
                                        gint for_size,
                                        gint* minimum,
                                        gint* natural,
                                        gint* minimum_baseline,
                                        gint* natural_baseline);
static void _ft_bubble_chart_measure_bubble_cb_ft_gizmo_measure_func (FtGizmo* gizmo,
                                                               GtkOrientation orientation,
                                                               gint for_size,
                                                               gint* minimum,
                                                               gint* natural,
                                                               gint* minimum_baseline,
                                                               gint* natural_baseline,
                                                               gpointer self);
static void ft_bubble_chart_snapshot_bubble_cb (FtGizmo* gizmo,
                                         GtkSnapshot* snapshot);
static void _ft_bubble_chart_snapshot_bubble_cb_ft_gizmo_snapshot_func (FtGizmo* gizmo,
                                                                 GtkSnapshot* snapshot,
                                                                 gpointer self);
static gboolean ft_bubble_chart_contains_bubble_cb (FtGizmo* gizmo,
                                             gdouble x,
                                             gdouble y);
static gboolean _ft_bubble_chart_contains_bubble_cb_ft_gizmo_contains_func (FtGizmo* gizmo,
                                                                     gdouble x,
                                                                     gdouble y,
                                                                     gpointer self);
static gboolean ft_bubble_chart_on_query_tooltip_cb (GtkWidget* widget,
                                              gint x,
                                              gint y,
                                              gboolean keyboard_tooltip,
                                              GtkTooltip* tooltip);
static gboolean _ft_bubble_chart_on_query_tooltip_cb_gtk_widget_query_tooltip (GtkWidget* _sender,
                                                                        gint x,
                                                                        gint y,
                                                                        gboolean keyboard_tooltip,
                                                                        GtkTooltip* tooltip,
                                                                        gpointer self);
static Block6Data* block6_data_ref (Block6Data* _data6_);
static void block6_data_unref (void * _userdata_);
static void ___lambda19_ (Block6Data* _data6_,
                   gint n_press,
                   gdouble x,
                   gdouble y);
static void ft_bubble_chart_on_clicked_cb (GtkWidget* widget);
static void ____lambda19__gtk_gesture_click_released (GtkGestureClick* _sender,
                                               gint n_press,
                                               gdouble x,
                                               gdouble y,
                                               gpointer self);
static FtBubbleChart* ft_bubble_chart_from_gizmo (FtGizmo* gizmo);
static FtBubbleChart* ft_bubble_chart_from_widget (GtkWidget* widget);
static GtkSizeRequestMode ft_bubble_chart_real_get_request_mode (GtkWidget* base);
static void ft_bubble_chart_real_measure (GtkWidget* base,
                                   GtkOrientation orientation,
                                   gint for_size,
                                   gint* minimum,
                                   gint* natural,
                                   gint* minimum_baseline,
                                   gint* natural_baseline);
static void ft_bubble_chart_real_size_allocate (GtkWidget* base,
                                         gint width,
                                         gint height,
                                         gint baseline);
static void ft_bubble_chart_real_snapshot (GtkWidget* base,
                                    GtkSnapshot* snapshot);
static void ft_bubble_chart_real_dispose (GObject* base);
static void g_cclosure_user_marshal_VOID__UINT_UINT (GClosure * closure,
                                              GValue * return_value,
                                              guint n_param_values,
                                              const GValue * param_values,
                                              gpointer invocation_hint,
                                              gpointer marshal_data);
static GObject * ft_bubble_chart_constructor (GType type,
                                       guint n_construct_properties,
                                       GObjectConstructParam * construct_properties);
static void ft_bubble_chart_finalize (GObject * obj);
static GType ft_bubble_chart_get_type_once (void);
static void _vala_ft_bubble_chart_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec);
static void _vala_ft_bubble_chart_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 inline gpointer
ft_bubble_chart_get_instance_private (FtBubbleChart* self)
{
	return G_STRUCT_MEMBER_P (self, FtBubbleChart_private_offset);
}

static void
_vala_FtCategory_array_free (FtCategory * array,
                             gssize array_length)
{
	if (array != NULL) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			ft_category_destroy (&array[i]);
		}
	}
	g_free (array);
}

static void
_vala_FtBucket_array_free (FtBucket * array,
                           gssize array_length)
{
	if (array != NULL) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			ft_bucket_destroy (&array[i]);
		}
	}
	g_free (array);
}

static inline gchar*
ft_bubble_chart_format_tooltip_value (FtBubbleChart* self,
                                      guint category_index,
                                      gdouble value)
{
	gchar* _tmp0_ = NULL;
	FtCategory* _tmp1_;
	gint _tmp1__length1;
	gchar* _tmp6_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->priv->categories;
	_tmp1__length1 = self->priv->categories_length1;
	if (category_index < ((guint) _tmp1__length1)) {
		FtCategory* _tmp2_;
		gint _tmp2__length1;
		FtCategory _tmp3_;
		gchar* _tmp4_;
		_tmp2_ = self->priv->categories;
		_tmp2__length1 = self->priv->categories_length1;
		_tmp3_ = _tmp2_[category_index];
		_tmp4_ = ft_unit_format (_tmp3_.unit, value);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp4_;
	} else {
		gchar* _tmp5_;
		_tmp5_ = g_strdup_printf ("%.2f", value);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp5_;
	}
	_tmp6_ = _tmp0_;
	_tmp0_ = NULL;
	result = _tmp6_;
	_g_free0 (_tmp0_);
	return result;
}

static inline gdouble
ft_bubble_chart_calculate_max_value (FtBubbleChart* self)
{
	FtMatrix3D* _tmp0_ = NULL;
	FtMatrix3D* _tmp1_;
	FtMatrix* _tmp2_ = NULL;
	FtMatrix* category_data = NULL;
	FtMatrix* _tmp6_;
	gdouble _tmp7_ = 0.0;
	FtMatrix* _tmp8_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp1_ = self->priv->data;
	_tmp0_ = _tmp1_;
	_tmp2_ = NULL;
	if (_tmp0_ != NULL) {
		guint _tmp3_;
		guint _tmp4_;
		FtMatrix* _tmp5_;
		_tmp3_ = ft_bubble_chart_get_category (self);
		_tmp4_ = _tmp3_;
		_tmp5_ = ft_matrix3_d_get_matrix (_tmp0_, 2, (gint) _tmp4_);
		_ft_matrix_free0 (_tmp2_);
		_tmp2_ = _tmp5_;
	}
	_tmp6_ = _tmp2_;
	_tmp2_ = NULL;
	category_data = _tmp6_;
	_tmp8_ = category_data;
	if (_tmp8_ != NULL) {
		FtMatrix* _tmp9_;
		_tmp9_ = category_data;
		_tmp7_ = MAX (ft_matrix_max (_tmp9_), self->priv->_reference_value);
	} else {
		_tmp7_ = self->priv->_reference_value;
	}
	result = _tmp7_;
	_ft_matrix_free0 (category_data);
	_ft_matrix_free0 (_tmp2_);
	return result;
}

static inline gfloat
ft_bubble_chart_calculate_bubble_radius (FtBubbleChart* self,
                                         gdouble bubble_value)
{
	gint levels = 0;
	gfloat* _tmp0_;
	gint _tmp0__length1;
	gfloat bubble_radius = 0.0F;
	gboolean _tmp1_ = FALSE;
	gfloat result;
	g_return_val_if_fail (self != NULL, -1.0F);
	_tmp0_ = self->priv->level_radii;
	_tmp0__length1 = self->priv->level_radii_length1;
	levels = _tmp0__length1;
	if (isnan (self->priv->max_value)) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = self->priv->max_value <= 0.0;
	}
	if (_tmp1_) {
		result = 0.0f;
		return result;
	}
	if (levels <= 1) {
		bubble_radius = (((1.0f - FT_BUBBLE_CHART_BUBBLE_SPACING) * ((gfloat) self->priv->bubble_size)) * 0.5f) * ((gfloat) sqrt (bubble_value / self->priv->max_value));
		if (bubble_radius < FT_BUBBLE_CHART_MIN_BUBBLE_RADIUS) {
			bubble_radius = 0.0f;
		}
	} else {
		if (bubble_value < ((gdouble) FT_BUBBLE_CHART_MIN_BUBBLE_VALUE)) {
			gfloat* _tmp2_;
			gint _tmp2__length1;
			gfloat _tmp3_;
			_tmp2_ = self->priv->level_radii;
			_tmp2__length1 = self->priv->level_radii_length1;
			_tmp3_ = _tmp2_[0];
			bubble_radius = _tmp3_;
		} else {
			gint level = 0;
			gfloat* _tmp4_;
			gint _tmp4__length1;
			gfloat _tmp5_;
			level = 1 + CLAMP ((gint) floor (((gdouble) (levels - 1)) * (bubble_value / self->priv->max_value)), 0, levels - 2);
			_tmp4_ = self->priv->level_radii;
			_tmp4__length1 = self->priv->level_radii_length1;
			_tmp5_ = _tmp4_[level];
			bubble_radius = _tmp5_;
		}
	}
	result = bubble_radius;
	return result;
}

static void
ft_bubble_chart_update_level_radii (FtBubbleChart* self)
{
	gint levels = 0;
	gdouble min_radius = 0.0;
	gdouble max_radius = 0.0;
	gfloat* _tmp2_;
	gint _tmp2__length1;
	g_return_if_fail (self != NULL);
	if (self->priv->_levels == ((guint) 0)) {
		gfloat* _tmp0_;
		gint _tmp0__length1;
		_tmp0_ = self->priv->level_radii;
		_tmp0__length1 = self->priv->level_radii_length1;
		if (_tmp0__length1 > 0) {
			gint _tmp1_;
			_tmp1_ = 0;
			self->priv->level_radii = g_renew (gfloat, self->priv->level_radii, 0);
			(_tmp1_ > self->priv->level_radii_length1) ? memset (self->priv->level_radii + self->priv->level_radii_length1, 0, sizeof (gfloat) * (_tmp1_ - self->priv->level_radii_length1)) : NULL;
			self->priv->level_radii_length1 = _tmp1_;
			self->priv->_level_radii_size_ = _tmp1_;
		}
		return;
	}
	if (self->priv->bubble_size <= 0) {
		return;
	}
	levels = ((gint) self->priv->_levels) + 1;
	min_radius = (gdouble) FT_BUBBLE_CHART_BASE_RADIUS;
	max_radius = ((1.0 - ((gdouble) FT_BUBBLE_CHART_BUBBLE_SPACING)) * ((gdouble) self->priv->bubble_size)) * 0.5;
	_tmp2_ = self->priv->level_radii;
	_tmp2__length1 = self->priv->level_radii_length1;
	if (_tmp2__length1 != levels) {
		gint _tmp3_;
		_tmp3_ = levels;
		self->priv->level_radii = g_renew (gfloat, self->priv->level_radii, levels);
		(_tmp3_ > self->priv->level_radii_length1) ? memset (self->priv->level_radii + self->priv->level_radii_length1, 0, sizeof (gfloat) * (_tmp3_ - self->priv->level_radii_length1)) : NULL;
		self->priv->level_radii_length1 = _tmp3_;
		self->priv->_level_radii_size_ = _tmp3_;
	}
	{
		gint level = 0;
		level = 0;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				gdouble t = 0.0;
				gfloat* _tmp6_;
				gint _tmp6__length1;
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = level;
					level = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (!(level < levels)) {
					break;
				}
				t = ((gdouble) level) / ((gdouble) (levels - 1));
				_tmp6_ = self->priv->level_radii;
				_tmp6__length1 = self->priv->level_radii_length1;
				_tmp6_[level] = (gfloat) sqrt (adw_lerp (min_radius * min_radius, max_radius * max_radius, t));
			}
		}
	}
}

static void
ft_bubble_chart_invalidate_max_value (FtBubbleChart* self)
{
	g_return_if_fail (self != NULL);
	self->priv->max_value = ((double) NAN);
	gtk_widget_queue_allocate ((GtkWidget*) self);
}

static void
ft_bubble_chart_ensure_max_value (FtBubbleChart* self)
{
	g_return_if_fail (self != NULL);
	if (isnan (self->priv->max_value)) {
		self->priv->max_value = ft_bubble_chart_calculate_max_value (self);
	}
}

static void
ft_bubble_chart_ensure_categories (FtBubbleChart* self,
                                   guint count)
{
	gint previous_count = 0;
	FtCategory* _tmp0_;
	gint _tmp0__length1;
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->categories;
	_tmp0__length1 = self->priv->categories_length1;
	previous_count = _tmp0__length1;
	if (((guint) previous_count) >= count) {
		return;
	}
	_tmp1_ = (gint) count;
	self->priv->categories = g_renew (FtCategory, self->priv->categories, (gint) count);
	(_tmp1_ > self->priv->categories_length1) ? memset (self->priv->categories + self->priv->categories_length1, 0, sizeof (FtCategory) * (_tmp1_ - self->priv->categories_length1)) : NULL;
	self->priv->categories_length1 = _tmp1_;
	self->priv->_categories_size_ = _tmp1_;
	{
		gint index = 0;
		index = previous_count;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				FtCategory* _tmp4_;
				gint _tmp4__length1;
				gchar* _tmp5_;
				GdkRGBA _tmp6_ = {0};
				FtCategory _tmp7_ = {0};
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = index;
					index = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				if (!(((guint) index) < count)) {
					break;
				}
				_tmp4_ = self->priv->categories;
				_tmp4__length1 = self->priv->categories_length1;
				_tmp5_ = g_strdup ("");
				gtk_widget_get_color ((GtkWidget*) self, &_tmp6_);
				memset (&_tmp7_, 0, sizeof (FtCategory));
				_g_free0 (_tmp7_.label);
				_tmp7_.label = _tmp5_;
				_tmp7_.color = _tmp6_;
				ft_category_destroy (&_tmp4_[index]);
				_tmp4_[index] = _tmp7_;
			}
		}
	}
}

static FtBucket*
_vala_array_dup1 (FtBucket* self,
                  gssize length)
{
	if (length > 0) {
		FtBucket* result;
		gssize i;
		result = g_new0 (FtBucket, length);
		for (i = 0; i < length; i++) {
			FtBucket _tmp0_;
			FtBucket _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_bucket_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static gboolean
ft_bubble_chart_grow_buckets (FtBubbleChart* self,
                              guint rows,
                              guint columns)
{
	gboolean resized = FALSE;
	FtBucket* _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	gboolean _tmp6_ = FALSE;
	FtBucket* _tmp7_;
	gint _tmp7__length1;
	gint _tmp7__length2;
	gint _tmp8_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	resized = FALSE;
	_tmp0_ = self->priv->buckets;
	_tmp0__length1 = self->priv->buckets_length1;
	_tmp0__length2 = self->priv->buckets_length2;
	if (_tmp0_ == NULL) {
		FtBucket* _tmp1_;
		_tmp1_ = g_new0 (FtBucket, rows * columns);
		self->priv->buckets = (_vala_FtBucket_array_free (self->priv->buckets, self->priv->buckets_length1 * self->priv->buckets_length2), NULL);
		self->priv->buckets = _tmp1_;
		self->priv->buckets_length1 = rows;
		self->priv->buckets_length2 = columns;
		resized = TRUE;
	} else {
		FtBucket* _tmp2_;
		gint _tmp2__length1;
		gint _tmp2__length2;
		gint _tmp3_;
		FtBucket* _tmp4_;
		gint _tmp4__length1;
		gint _tmp4__length2;
		gint _tmp5_;
		_tmp2_ = self->priv->buckets;
		_tmp2__length1 = self->priv->buckets_length1;
		_tmp2__length2 = self->priv->buckets_length2;
		_tmp3_ = _tmp2__length1;
		rows = MAX ((guint) _tmp3_, rows);
		_tmp4_ = self->priv->buckets;
		_tmp4__length1 = self->priv->buckets_length1;
		_tmp4__length2 = self->priv->buckets_length2;
		_tmp5_ = _tmp4__length2;
		columns = MAX ((guint) _tmp5_, columns);
	}
	_tmp7_ = self->priv->buckets;
	_tmp7__length1 = self->priv->buckets_length1;
	_tmp7__length2 = self->priv->buckets_length2;
	_tmp8_ = _tmp7__length1;
	if (((guint) _tmp8_) != rows) {
		_tmp6_ = TRUE;
	} else {
		FtBucket* _tmp9_;
		gint _tmp9__length1;
		gint _tmp9__length2;
		gint _tmp10_;
		_tmp9_ = self->priv->buckets;
		_tmp9__length1 = self->priv->buckets_length1;
		_tmp9__length2 = self->priv->buckets_length2;
		_tmp10_ = _tmp9__length2;
		_tmp6_ = ((guint) _tmp10_) != columns;
	}
	if (_tmp6_) {
		gint rows_intersection = 0;
		FtBucket* _tmp11_;
		gint _tmp11__length1;
		gint _tmp11__length2;
		gint _tmp12_;
		gint columns_intersection = 0;
		FtBucket* _tmp13_;
		gint _tmp13__length1;
		gint _tmp13__length2;
		gint _tmp14_;
		FtBucket* buckets = NULL;
		FtBucket* _tmp15_;
		gint buckets_length1;
		gint buckets_length2;
		FtBucket* _tmp25_;
		gint _tmp25__length1;
		gint _tmp25__length2;
		FtBucket* _tmp26_;
		gint _tmp26__length1;
		gint _tmp26__length2;
		_tmp11_ = self->priv->buckets;
		_tmp11__length1 = self->priv->buckets_length1;
		_tmp11__length2 = self->priv->buckets_length2;
		_tmp12_ = _tmp11__length1;
		rows_intersection = MIN ((gint) rows, _tmp12_);
		_tmp13_ = self->priv->buckets;
		_tmp13__length1 = self->priv->buckets_length1;
		_tmp13__length2 = self->priv->buckets_length2;
		_tmp14_ = _tmp13__length2;
		columns_intersection = MIN ((gint) columns, _tmp14_);
		_tmp15_ = g_new0 (FtBucket, rows * columns);
		buckets = _tmp15_;
		buckets_length1 = rows;
		buckets_length2 = columns;
		{
			gint row = 0;
			row = 0;
			{
				gboolean _tmp16_ = FALSE;
				_tmp16_ = TRUE;
				while (TRUE) {
					if (!_tmp16_) {
						gint _tmp17_;
						_tmp17_ = row;
						row = _tmp17_ + 1;
					}
					_tmp16_ = FALSE;
					if (!(row < rows_intersection)) {
						break;
					}
					{
						gint column = 0;
						column = 0;
						{
							gboolean _tmp18_ = FALSE;
							_tmp18_ = TRUE;
							while (TRUE) {
								FtBucket* _tmp20_;
								gint _tmp20__length1;
								gint _tmp20__length2;
								FtBucket* _tmp21_;
								gint _tmp21__length1;
								gint _tmp21__length2;
								FtBucket _tmp22_;
								FtBucket _tmp23_;
								FtBucket _tmp24_ = {0};
								if (!_tmp18_) {
									gint _tmp19_;
									_tmp19_ = column;
									column = _tmp19_ + 1;
								}
								_tmp18_ = FALSE;
								if (!(column < columns_intersection)) {
									break;
								}
								_tmp20_ = buckets;
								_tmp20__length1 = buckets_length1;
								_tmp20__length2 = buckets_length2;
								_tmp21_ = self->priv->buckets;
								_tmp21__length1 = self->priv->buckets_length1;
								_tmp21__length2 = self->priv->buckets_length2;
								_tmp22_ = _tmp21_[(row * _tmp21__length2) + column];
								_tmp23_ = _tmp22_;
								ft_bucket_copy (&_tmp23_, &_tmp24_);
								ft_bucket_destroy (&_tmp20_[(row * _tmp20__length2) + column]);
								_tmp20_[(row * _tmp20__length2) + column] = _tmp24_;
							}
						}
					}
				}
			}
		}
		_tmp25_ = buckets;
		_tmp25__length1 = buckets_length1;
		_tmp25__length2 = buckets_length2;
		_tmp26_ = (_tmp25_ != NULL) ? _vala_array_dup1 (_tmp25_, _tmp25__length1 * _tmp25__length2) : _tmp25_;
		_tmp26__length1 = _tmp25__length1;
		_tmp26__length2 = _tmp25__length2;
		self->priv->buckets = (_vala_FtBucket_array_free (self->priv->buckets, self->priv->buckets_length1 * self->priv->buckets_length2), NULL);
		self->priv->buckets = _tmp26_;
		self->priv->buckets_length1 = _tmp26__length1;
		self->priv->buckets_length2 = _tmp26__length2;
		resized = TRUE;
		buckets = (_vala_FtBucket_array_free (buckets, buckets_length1 * buckets_length2), NULL);
	}
	result = resized;
	return result;
}

static gboolean
ft_bubble_chart_grow_data (FtBubbleChart* self,
                           guint row_count,
                           guint column_count,
                           guint category_count)
{
	FtMatrix3D* _tmp0_;
	gboolean _tmp11_ = FALSE;
	gboolean _tmp12_ = FALSE;
	FtMatrix3D* _tmp13_;
	guint* _tmp14_;
	gint _tmp14__length1;
	guint _tmp15_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->data;
	if (_tmp0_ == NULL) {
		FtMatrix3D* _tmp1_;
		row_count = MAX (row_count, 1U);
		column_count = MAX (column_count, 1U);
		category_count = MAX (category_count, 1U);
		_tmp1_ = ft_matrix3_d_new (row_count, column_count, category_count);
		_ft_matrix3_d_free0 (self->priv->data);
		self->priv->data = _tmp1_;
		ft_bubble_chart_queue_update (self);
	} else {
		FtMatrix3D* _tmp2_;
		guint* _tmp3_;
		gint _tmp3__length1;
		guint _tmp4_;
		FtMatrix3D* _tmp5_;
		guint* _tmp6_;
		gint _tmp6__length1;
		guint _tmp7_;
		FtMatrix3D* _tmp8_;
		guint* _tmp9_;
		gint _tmp9__length1;
		guint _tmp10_;
		_tmp2_ = self->priv->data;
		_tmp3_ = _tmp2_->shape;
		_tmp3__length1 = _tmp2_->shape_length1;
		_tmp4_ = _tmp3_[0];
		row_count = MAX (_tmp4_, row_count);
		_tmp5_ = self->priv->data;
		_tmp6_ = _tmp5_->shape;
		_tmp6__length1 = _tmp5_->shape_length1;
		_tmp7_ = _tmp6_[1];
		column_count = MAX (_tmp7_, column_count);
		_tmp8_ = self->priv->data;
		_tmp9_ = _tmp8_->shape;
		_tmp9__length1 = _tmp8_->shape_length1;
		_tmp10_ = _tmp9_[2];
		category_count = MAX (_tmp10_, category_count);
	}
	_tmp13_ = self->priv->data;
	_tmp14_ = _tmp13_->shape;
	_tmp14__length1 = _tmp13_->shape_length1;
	_tmp15_ = _tmp14_[0];
	if (_tmp15_ != row_count) {
		_tmp12_ = TRUE;
	} else {
		FtMatrix3D* _tmp16_;
		guint* _tmp17_;
		gint _tmp17__length1;
		guint _tmp18_;
		_tmp16_ = self->priv->data;
		_tmp17_ = _tmp16_->shape;
		_tmp17__length1 = _tmp16_->shape_length1;
		_tmp18_ = _tmp17_[1];
		_tmp12_ = _tmp18_ != column_count;
	}
	if (_tmp12_) {
		_tmp11_ = TRUE;
	} else {
		FtMatrix3D* _tmp19_;
		guint* _tmp20_;
		gint _tmp20__length1;
		guint _tmp21_;
		_tmp19_ = self->priv->data;
		_tmp20_ = _tmp19_->shape;
		_tmp20__length1 = _tmp19_->shape_length1;
		_tmp21_ = _tmp20_[2];
		_tmp11_ = _tmp21_ != category_count;
	}
	if (_tmp11_) {
		FtMatrix3D* _tmp22_;
		_tmp22_ = self->priv->data;
		ft_matrix3_d_resize (_tmp22_, row_count, column_count, category_count, FT_BUBBLE_CHART_DEFAULT_VALUE);
		ft_bubble_chart_queue_update (self);
		result = TRUE;
		return result;
	} else {
		result = FALSE;
		return result;
	}
}

static void
ft_bubble_chart_queue_draw_bubbles (FtBubbleChart* self)
{
	GtkWidget* bubble = NULL;
	GtkGrid* _tmp0_;
	GtkWidget* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->bubbles_grid;
	_tmp1_ = gtk_widget_get_first_child ((GtkWidget*) _tmp0_);
	bubble = _tmp1_;
	while (TRUE) {
		GtkWidget* _tmp2_;
		GtkWidget* _tmp3_;
		GtkWidget* _tmp4_;
		GtkWidget* _tmp5_;
		_tmp2_ = bubble;
		if (!(_tmp2_ != NULL)) {
			break;
		}
		_tmp3_ = bubble;
		gtk_widget_queue_draw (_tmp3_);
		_tmp4_ = bubble;
		_tmp5_ = gtk_widget_get_next_sibling (_tmp4_);
		bubble = _tmp5_;
	}
}

static void
ft_bubble_chart_queue_resize_bubbles (FtBubbleChart* self)
{
	GtkWidget* bubble = NULL;
	GtkGrid* _tmp0_;
	GtkWidget* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->bubbles_grid;
	_tmp1_ = gtk_widget_get_first_child ((GtkWidget*) _tmp0_);
	bubble = _tmp1_;
	while (TRUE) {
		GtkWidget* _tmp2_;
		GtkWidget* _tmp3_;
		GtkWidget* _tmp4_;
		GtkWidget* _tmp5_;
		_tmp2_ = bubble;
		if (!(_tmp2_ != NULL)) {
			break;
		}
		_tmp3_ = bubble;
		gtk_widget_queue_resize (_tmp3_);
		_tmp4_ = bubble;
		_tmp5_ = gtk_widget_get_next_sibling (_tmp4_);
		bubble = _tmp5_;
	}
}

static void
ft_bubble_chart_ensure_bubble (FtBubbleChart* self,
                               guint row,
                               guint column)
{
	GtkWidget* existing_bubble = NULL;
	GtkGrid* _tmp0_;
	GtkWidget* _tmp1_;
	GtkWidget* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->bubbles_grid;
	_tmp1_ = gtk_grid_get_child_at (_tmp0_, (gint) column, (gint) row);
	existing_bubble = _tmp1_;
	_tmp2_ = existing_bubble;
	if (_tmp2_ == NULL) {
		GtkWidget* bubble = NULL;
		GtkWidget* _tmp3_;
		GtkGrid* _tmp4_;
		GtkWidget* _tmp5_;
		_tmp3_ = ft_bubble_chart_create_bubble (self, row, column);
		bubble = _tmp3_;
		_tmp4_ = self->priv->bubbles_grid;
		_tmp5_ = bubble;
		gtk_grid_attach (_tmp4_, _tmp5_, (gint) column, (gint) row, 1, 1);
		_g_object_unref0 (bubble);
	}
}

void
ft_bubble_chart_set_category_label (FtBubbleChart* self,
                                    guint category_index,
                                    const gchar* label)
{
	FtCategory* _tmp0_;
	gint _tmp0__length1;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (label != NULL);
	ft_bubble_chart_ensure_categories (self, category_index + 1);
	_tmp0_ = self->priv->categories;
	_tmp0__length1 = self->priv->categories_length1;
	_tmp1_ = g_strdup (label);
	_g_free0 (_tmp0_[category_index].label);
	_tmp0_[category_index].label = _tmp1_;
}

void
ft_bubble_chart_set_category_color (FtBubbleChart* self,
                                    guint category_index,
                                    GdkRGBA* color)
{
	FtCategory* _tmp0_;
	gint _tmp0__length1;
	GdkRGBA _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (color != NULL);
	ft_bubble_chart_ensure_categories (self, category_index + 1);
	_tmp0_ = self->priv->categories;
	_tmp0__length1 = self->priv->categories_length1;
	_tmp1_ = *color;
	_tmp0_[category_index].color = _tmp1_;
	gtk_widget_queue_draw ((GtkWidget*) self);
}

void
ft_bubble_chart_set_category_unit (FtBubbleChart* self,
                                   guint category_index,
                                   FtUnit unit)
{
	FtCategory* _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	ft_bubble_chart_ensure_categories (self, category_index + 1);
	_tmp0_ = self->priv->categories;
	_tmp0__length1 = self->priv->categories_length1;
	_tmp0_[category_index].unit = unit;
}

gdouble
ft_bubble_chart_get_category_total (FtBubbleChart* self,
                                    guint category_index)
{
	FtMatrix3D* _tmp0_;
	FtMatrix* _tmp1_;
	FtMatrix* _tmp2_;
	gdouble _tmp3_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp0_ = self->priv->data;
	_tmp1_ = ft_matrix3_d_get_matrix (_tmp0_, -1, (gint) category_index);
	_tmp2_ = _tmp1_;
	_tmp3_ = ft_matrix_sum (_tmp2_);
	_ft_matrix_free0 (_tmp2_);
	result = _tmp3_;
	return result;
}

static gchar*
ft_bubble_chart_get_tooltip_label (FtBubbleChart* self,
                                   guint row,
                                   guint column)
{
	gboolean _tmp0_ = FALSE;
	FtBucket* _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	gint _tmp2_;
	FtBucket* _tmp6_;
	gint _tmp6__length1;
	gint _tmp6__length2;
	FtBucket _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->priv->buckets;
	_tmp1__length1 = self->priv->buckets_length1;
	_tmp1__length2 = self->priv->buckets_length2;
	_tmp2_ = _tmp1__length1;
	if (row >= ((guint) _tmp2_)) {
		_tmp0_ = TRUE;
	} else {
		FtBucket* _tmp3_;
		gint _tmp3__length1;
		gint _tmp3__length2;
		gint _tmp4_;
		_tmp3_ = self->priv->buckets;
		_tmp3__length1 = self->priv->buckets_length1;
		_tmp3__length2 = self->priv->buckets_length2;
		_tmp4_ = _tmp3__length2;
		_tmp0_ = column >= ((guint) _tmp4_);
	}
	if (_tmp0_) {
		gchar* _tmp5_;
		_tmp5_ = g_strdup ("");
		result = _tmp5_;
		return result;
	}
	_tmp6_ = self->priv->buckets;
	_tmp6__length1 = self->priv->buckets_length1;
	_tmp6__length2 = self->priv->buckets_length2;
	_tmp7_ = _tmp6_[(row * _tmp6__length2) + column];
	_tmp8_ = _tmp7_.tooltip_label;
	_tmp9_ = g_strdup (_tmp8_);
	result = _tmp9_;
	return result;
}

void
ft_bubble_chart_set_bubble_tooltip_label (FtBubbleChart* self,
                                          guint row,
                                          guint column,
                                          const gchar* label)
{
	FtBucket* _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (label != NULL);
	if (ft_bubble_chart_grow_buckets (self, row + 1, column + 1)) {
		ft_bubble_chart_queue_update (self);
	}
	_tmp0_ = self->priv->buckets;
	_tmp0__length1 = self->priv->buckets_length1;
	_tmp0__length2 = self->priv->buckets_length2;
	_tmp1_ = g_strdup (label);
	_g_free0 (_tmp0_[(row * _tmp0__length2) + column].tooltip_label);
	_tmp0_[(row * _tmp0__length2) + column].tooltip_label = _tmp1_;
}

void
ft_bubble_chart_set_bubble_inverted (FtBubbleChart* self,
                                     guint row,
                                     guint column,
                                     gboolean inverted)
{
	GtkWidget* bubble = NULL;
	GtkGrid* _tmp0_;
	GtkWidget* _tmp1_;
	g_return_if_fail (self != NULL);
	ft_bubble_chart_ensure_bubble (self, row, column);
	_tmp0_ = self->priv->bubbles_grid;
	_tmp1_ = gtk_grid_get_child_at (_tmp0_, (gint) column, (gint) row);
	bubble = _tmp1_;
	if (inverted) {
		GtkWidget* _tmp2_;
		_tmp2_ = bubble;
		gtk_widget_add_css_class (_tmp2_, "inverted");
	} else {
		GtkWidget* _tmp3_;
		_tmp3_ = bubble;
		gtk_widget_remove_css_class (_tmp3_, "inverted");
	}
	ft_bubble_chart_queue_update (self);
}

static void
ft_bubble_chart_update_bubbles (FtBubbleChart* self)
{
	guint row_count = 0U;
	FtMatrix3D* _tmp0_;
	guint* _tmp1_;
	gint _tmp1__length1;
	guint _tmp2_;
	FtBucket* _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	gint _tmp4_;
	guint column_count = 0U;
	FtMatrix3D* _tmp5_;
	guint* _tmp6_;
	gint _tmp6__length1;
	guint _tmp7_;
	FtBucket* _tmp8_;
	gint _tmp8__length1;
	gint _tmp8__length2;
	gint _tmp9_;
	gboolean _tmp10_ = FALSE;
	FtMatrix3D* _tmp11_;
	guint* _tmp12_;
	gint _tmp12__length1;
	guint _tmp13_;
	FtBucket* _tmp14_;
	gint _tmp14__length1;
	gint _tmp14__length2;
	gint _tmp15_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->data;
	_tmp1_ = _tmp0_->shape;
	_tmp1__length1 = _tmp0_->shape_length1;
	_tmp2_ = _tmp1_[0];
	_tmp3_ = self->priv->buckets;
	_tmp3__length1 = self->priv->buckets_length1;
	_tmp3__length2 = self->priv->buckets_length2;
	_tmp4_ = _tmp3__length1;
	row_count = MAX (_tmp2_, (guint) _tmp4_);
	_tmp5_ = self->priv->data;
	_tmp6_ = _tmp5_->shape;
	_tmp6__length1 = _tmp5_->shape_length1;
	_tmp7_ = _tmp6_[1];
	_tmp8_ = self->priv->buckets;
	_tmp8__length1 = self->priv->buckets_length1;
	_tmp8__length2 = self->priv->buckets_length2;
	_tmp9_ = _tmp8__length2;
	column_count = MAX (_tmp7_, (guint) _tmp9_);
	_tmp11_ = self->priv->data;
	_tmp12_ = _tmp11_->shape;
	_tmp12__length1 = _tmp11_->shape_length1;
	_tmp13_ = _tmp12_[0];
	_tmp14_ = self->priv->buckets;
	_tmp14__length1 = self->priv->buckets_length1;
	_tmp14__length2 = self->priv->buckets_length2;
	_tmp15_ = _tmp14__length1;
	if (_tmp13_ > ((guint) _tmp15_)) {
		_tmp10_ = TRUE;
	} else {
		FtMatrix3D* _tmp16_;
		guint* _tmp17_;
		gint _tmp17__length1;
		guint _tmp18_;
		FtBucket* _tmp19_;
		gint _tmp19__length1;
		gint _tmp19__length2;
		gint _tmp20_;
		_tmp16_ = self->priv->data;
		_tmp17_ = _tmp16_->shape;
		_tmp17__length1 = _tmp16_->shape_length1;
		_tmp18_ = _tmp17_[1];
		_tmp19_ = self->priv->buckets;
		_tmp19__length1 = self->priv->buckets_length1;
		_tmp19__length2 = self->priv->buckets_length2;
		_tmp20_ = _tmp19__length2;
		_tmp10_ = _tmp18_ > ((guint) _tmp20_);
	}
	if (_tmp10_) {
		FtBucket* _tmp21_;
		gint _tmp21__length1;
		gint _tmp21__length2;
		gint _tmp22_;
		FtBucket* _tmp23_;
		gint _tmp23__length1;
		gint _tmp23__length2;
		gint _tmp24_;
		FtMatrix3D* _tmp25_;
		guint* _tmp26_;
		gint _tmp26__length1;
		guint _tmp27_;
		FtMatrix3D* _tmp28_;
		guint* _tmp29_;
		gint _tmp29__length1;
		guint _tmp30_;
		_tmp21_ = self->priv->buckets;
		_tmp21__length1 = self->priv->buckets_length1;
		_tmp21__length2 = self->priv->buckets_length2;
		_tmp22_ = _tmp21__length2;
		_tmp23_ = self->priv->buckets;
		_tmp23__length1 = self->priv->buckets_length1;
		_tmp23__length2 = self->priv->buckets_length2;
		_tmp24_ = _tmp23__length1;
		_tmp25_ = self->priv->data;
		_tmp26_ = _tmp25_->shape;
		_tmp26__length1 = _tmp25_->shape_length1;
		_tmp27_ = _tmp26_[1];
		_tmp28_ = self->priv->data;
		_tmp29_ = _tmp28_->shape;
		_tmp29__length1 = _tmp28_->shape_length1;
		_tmp30_ = _tmp29_[0];
		g_warning ("bubble-chart.vala:417: Missing bucket definitions: %dx%d vs %ux%u", _tmp22_, _tmp24_, _tmp27_, _tmp30_);
	}
	{
		guint row = 0U;
		row = 0U;
		{
			gboolean _tmp31_ = FALSE;
			_tmp31_ = TRUE;
			while (TRUE) {
				if (!_tmp31_) {
					guint _tmp32_;
					_tmp32_ = row;
					row = _tmp32_ + 1;
				}
				_tmp31_ = FALSE;
				if (!(row < row_count)) {
					break;
				}
				{
					guint column = 0U;
					column = 0U;
					{
						gboolean _tmp33_ = FALSE;
						_tmp33_ = TRUE;
						while (TRUE) {
							if (!_tmp33_) {
								guint _tmp34_;
								_tmp34_ = column;
								column = _tmp34_ + 1;
							}
							_tmp33_ = FALSE;
							if (!(column < column_count)) {
								break;
							}
							ft_bubble_chart_ensure_bubble (self, row, column);
						}
					}
				}
			}
		}
	}
}

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

static void
ft_bubble_chart_update_rows_labels (FtBubbleChart* self)
{
	gint count = 0;
	gchar** _tmp0_;
	gint _tmp0__length1;
	GtkBox* box = NULL;
	GtkBox* _tmp1_;
	GtkBox* _tmp2_;
	GtkWidget* child = NULL;
	GtkBox* _tmp3_;
	GtkWidget* _tmp4_;
	GtkWidget* _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->rows_labels;
	_tmp0__length1 = self->priv->rows_labels_length1;
	count = _tmp0__length1;
	_tmp1_ = self->priv->rows_box;
	_tmp2_ = _g_object_ref0 (_tmp1_);
	box = _tmp2_;
	_tmp3_ = box;
	_tmp4_ = gtk_widget_get_first_child ((GtkWidget*) _tmp3_);
	_tmp5_ = _g_object_ref0 (_tmp4_);
	child = _tmp5_;
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				GtkWidget* _tmp8_;
				GtkWidget* _tmp21_;
				GtkWidget* _tmp22_;
				GtkWidget* _tmp23_;
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = index;
					index = _tmp7_ + 1;
				}
				_tmp6_ = FALSE;
				if (!(index < count)) {
					break;
				}
				_tmp8_ = child;
				if (_tmp8_ == NULL) {
					GtkLabel* label = NULL;
					gchar** _tmp9_;
					gint _tmp9__length1;
					const gchar* _tmp10_;
					GtkLabel* _tmp11_;
					GtkLabel* _tmp12_;
					GtkLabel* _tmp13_;
					GtkBox* _tmp14_;
					GtkLabel* _tmp15_;
					GtkLabel* _tmp16_;
					GtkWidget* _tmp17_;
					_tmp9_ = self->priv->rows_labels;
					_tmp9__length1 = self->priv->rows_labels_length1;
					_tmp10_ = _tmp9_[index];
					_tmp11_ = (GtkLabel*) gtk_label_new (_tmp10_);
					g_object_ref_sink (_tmp11_);
					label = _tmp11_;
					_tmp12_ = label;
					gtk_label_set_xalign (_tmp12_, 1.0f);
					_tmp13_ = label;
					gtk_label_set_yalign (_tmp13_, 0.5f);
					_tmp14_ = box;
					_tmp15_ = label;
					gtk_box_append (_tmp14_, (GtkWidget*) _tmp15_);
					_tmp16_ = label;
					_tmp17_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, gtk_widget_get_type (), GtkWidget));
					_g_object_unref0 (child);
					child = _tmp17_;
					_g_object_unref0 (label);
				} else {
					GtkWidget* _tmp18_;
					gchar** _tmp19_;
					gint _tmp19__length1;
					const gchar* _tmp20_;
					_tmp18_ = child;
					_tmp19_ = self->priv->rows_labels;
					_tmp19__length1 = self->priv->rows_labels_length1;
					_tmp20_ = _tmp19_[index];
					gtk_label_set_label (G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, gtk_label_get_type (), GtkLabel), _tmp20_);
				}
				_tmp21_ = child;
				_tmp22_ = gtk_widget_get_next_sibling (_tmp21_);
				_tmp23_ = _g_object_ref0 (_tmp22_);
				_g_object_unref0 (child);
				child = _tmp23_;
			}
		}
	}
	while (TRUE) {
		GtkWidget* _tmp24_;
		GtkWidget* next_child = NULL;
		GtkWidget* _tmp25_;
		GtkWidget* _tmp26_;
		GtkWidget* _tmp27_;
		GtkBox* _tmp28_;
		GtkWidget* _tmp29_;
		GtkWidget* _tmp30_;
		GtkWidget* _tmp31_;
		_tmp24_ = child;
		if (!(_tmp24_ != NULL)) {
			break;
		}
		_tmp25_ = child;
		_tmp26_ = gtk_widget_get_next_sibling (_tmp25_);
		_tmp27_ = _g_object_ref0 (_tmp26_);
		next_child = _tmp27_;
		_tmp28_ = box;
		_tmp29_ = child;
		gtk_box_remove (_tmp28_, _tmp29_);
		_tmp30_ = next_child;
		_tmp31_ = _g_object_ref0 (_tmp30_);
		_g_object_unref0 (child);
		child = _tmp31_;
		_g_object_unref0 (next_child);
	}
	_g_object_unref0 (child);
	_g_object_unref0 (box);
}

static void
ft_bubble_chart_update_columns_labels (FtBubbleChart* self)
{
	gint count = 0;
	gchar** _tmp0_;
	gint _tmp0__length1;
	GtkBox* box = NULL;
	GtkBox* _tmp1_;
	GtkBox* _tmp2_;
	GtkWidget* child = NULL;
	GtkBox* _tmp3_;
	GtkWidget* _tmp4_;
	GtkWidget* _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->columns_labels;
	_tmp0__length1 = self->priv->columns_labels_length1;
	count = _tmp0__length1;
	_tmp1_ = self->priv->columns_box;
	_tmp2_ = _g_object_ref0 (_tmp1_);
	box = _tmp2_;
	_tmp3_ = box;
	_tmp4_ = gtk_widget_get_first_child ((GtkWidget*) _tmp3_);
	_tmp5_ = _g_object_ref0 (_tmp4_);
	child = _tmp5_;
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				GtkWidget* _tmp8_;
				GtkWidget* _tmp21_;
				GtkWidget* _tmp22_;
				GtkWidget* _tmp23_;
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = index;
					index = _tmp7_ + 1;
				}
				_tmp6_ = FALSE;
				if (!(index < count)) {
					break;
				}
				_tmp8_ = child;
				if (_tmp8_ == NULL) {
					GtkLabel* label = NULL;
					gchar** _tmp9_;
					gint _tmp9__length1;
					const gchar* _tmp10_;
					GtkLabel* _tmp11_;
					GtkLabel* _tmp12_;
					GtkLabel* _tmp13_;
					GtkBox* _tmp14_;
					GtkLabel* _tmp15_;
					GtkLabel* _tmp16_;
					GtkWidget* _tmp17_;
					_tmp9_ = self->priv->columns_labels;
					_tmp9__length1 = self->priv->columns_labels_length1;
					_tmp10_ = _tmp9_[index];
					_tmp11_ = (GtkLabel*) gtk_label_new (_tmp10_);
					g_object_ref_sink (_tmp11_);
					label = _tmp11_;
					_tmp12_ = label;
					gtk_label_set_xalign (_tmp12_, 0.5f);
					_tmp13_ = label;
					gtk_label_set_yalign (_tmp13_, 0.5f);
					_tmp14_ = box;
					_tmp15_ = label;
					gtk_box_append (_tmp14_, (GtkWidget*) _tmp15_);
					_tmp16_ = label;
					_tmp17_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, gtk_widget_get_type (), GtkWidget));
					_g_object_unref0 (child);
					child = _tmp17_;
					_g_object_unref0 (label);
				} else {
					GtkWidget* _tmp18_;
					gchar** _tmp19_;
					gint _tmp19__length1;
					const gchar* _tmp20_;
					_tmp18_ = child;
					_tmp19_ = self->priv->columns_labels;
					_tmp19__length1 = self->priv->columns_labels_length1;
					_tmp20_ = _tmp19_[index];
					gtk_label_set_label (G_TYPE_CHECK_INSTANCE_CAST (_tmp18_, gtk_label_get_type (), GtkLabel), _tmp20_);
				}
				_tmp21_ = child;
				_tmp22_ = gtk_widget_get_next_sibling (_tmp21_);
				_tmp23_ = _g_object_ref0 (_tmp22_);
				_g_object_unref0 (child);
				child = _tmp23_;
			}
		}
	}
	while (TRUE) {
		GtkWidget* _tmp24_;
		GtkWidget* next_child = NULL;
		GtkWidget* _tmp25_;
		GtkWidget* _tmp26_;
		GtkWidget* _tmp27_;
		GtkBox* _tmp28_;
		GtkWidget* _tmp29_;
		GtkWidget* _tmp30_;
		GtkWidget* _tmp31_;
		_tmp24_ = child;
		if (!(_tmp24_ != NULL)) {
			break;
		}
		_tmp25_ = child;
		_tmp26_ = gtk_widget_get_next_sibling (_tmp25_);
		_tmp27_ = _g_object_ref0 (_tmp26_);
		next_child = _tmp27_;
		_tmp28_ = box;
		_tmp29_ = child;
		gtk_box_remove (_tmp28_, _tmp29_);
		_tmp30_ = next_child;
		_tmp31_ = _g_object_ref0 (_tmp30_);
		_g_object_unref0 (child);
		child = _tmp31_;
		_g_object_unref0 (next_child);
	}
	_g_object_unref0 (child);
	_g_object_unref0 (box);
}

static void
ft_bubble_chart_update (FtBubbleChart* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->update_idle_id != ((guint) 0)) {
		gtk_widget_remove_tick_callback ((GtkWidget*) self, self->priv->update_idle_id);
		self->priv->update_idle_id = (guint) 0;
	}
	ft_bubble_chart_update_bubbles (self);
	ft_bubble_chart_update_rows_labels (self);
	ft_bubble_chart_update_columns_labels (self);
}

static gboolean
__lambda18_ (FtBubbleChart* self)
{
	gboolean result;
	self->priv->update_idle_id = (guint) 0;
	ft_bubble_chart_update (self);
	result = G_SOURCE_REMOVE;
	return result;
}

static gboolean
___lambda18__gtk_tick_callback (GtkWidget* widget,
                                GdkFrameClock* frame_clock,
                                gpointer self)
{
	gboolean result;
	result = __lambda18_ ((FtBubbleChart*) self);
	return result;
}

static void
ft_bubble_chart_queue_update (FtBubbleChart* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->update_idle_id != ((guint) 0)) {
		return;
	}
	self->priv->update_idle_id = gtk_widget_add_tick_callback ((GtkWidget*) self, ___lambda18__gtk_tick_callback, g_object_ref (self), g_object_unref);
}

static inline void
ft_bubble_chart_ensure_rows (FtBubbleChart* self,
                             guint count)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->rows_labels;
	_tmp0__length1 = self->priv->rows_labels_length1;
	if (((guint) _tmp0__length1) < count) {
		gint _tmp1_;
		_tmp1_ = (gint) count;
		self->priv->rows_labels = g_renew (gchar*, self->priv->rows_labels, (gint) count);
		(_tmp1_ > self->priv->rows_labels_length1) ? memset (self->priv->rows_labels + self->priv->rows_labels_length1, 0, sizeof (gchar*) * (_tmp1_ - self->priv->rows_labels_length1)) : NULL;
		self->priv->rows_labels_length1 = _tmp1_;
		self->priv->_rows_labels_size_ = _tmp1_;
	}
}

static inline void
ft_bubble_chart_ensure_columns (FtBubbleChart* self,
                                guint count)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->columns_labels;
	_tmp0__length1 = self->priv->columns_labels_length1;
	if (((guint) _tmp0__length1) < count) {
		gint _tmp1_;
		_tmp1_ = (gint) count;
		self->priv->columns_labels = g_renew (gchar*, self->priv->columns_labels, (gint) count);
		(_tmp1_ > self->priv->columns_labels_length1) ? memset (self->priv->columns_labels + self->priv->columns_labels_length1, 0, sizeof (gchar*) * (_tmp1_ - self->priv->columns_labels_length1)) : NULL;
		self->priv->columns_labels_length1 = _tmp1_;
		self->priv->_columns_labels_size_ = _tmp1_;
	}
}

void
ft_bubble_chart_set_row_label (FtBubbleChart* self,
                               guint row,
                               const gchar* label)
{
	guint _tmp0_ = 0U;
	FtMatrix3D* _tmp1_;
	gchar** _tmp5_;
	gint _tmp5__length1;
	gchar* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (label != NULL);
	_tmp1_ = self->priv->data;
	if (_tmp1_ != NULL) {
		FtMatrix3D* _tmp2_;
		guint* _tmp3_;
		gint _tmp3__length1;
		guint _tmp4_;
		_tmp2_ = self->priv->data;
		_tmp3_ = _tmp2_->shape;
		_tmp3__length1 = _tmp2_->shape_length1;
		_tmp4_ = _tmp3_[0];
		_tmp0_ = _tmp4_;
	} else {
		_tmp0_ = 0U;
	}
	ft_bubble_chart_ensure_rows (self, MAX (row + 1U, _tmp0_));
	_tmp5_ = self->priv->rows_labels;
	_tmp5__length1 = self->priv->rows_labels_length1;
	_tmp6_ = g_strdup (label);
	_g_free0 (_tmp5_[row]);
	_tmp5_[row] = _tmp6_;
	ft_bubble_chart_queue_update (self);
}

void
ft_bubble_chart_set_column_label (FtBubbleChart* self,
                                  guint column,
                                  const gchar* label)
{
	guint _tmp0_ = 0U;
	FtMatrix3D* _tmp1_;
	gchar** _tmp5_;
	gint _tmp5__length1;
	gchar* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (label != NULL);
	_tmp1_ = self->priv->data;
	if (_tmp1_ != NULL) {
		FtMatrix3D* _tmp2_;
		guint* _tmp3_;
		gint _tmp3__length1;
		guint _tmp4_;
		_tmp2_ = self->priv->data;
		_tmp3_ = _tmp2_->shape;
		_tmp3__length1 = _tmp2_->shape_length1;
		_tmp4_ = _tmp3_[1];
		_tmp0_ = _tmp4_;
	} else {
		_tmp0_ = 0U;
	}
	ft_bubble_chart_ensure_columns (self, MAX (column + 1U, _tmp0_));
	_tmp5_ = self->priv->columns_labels;
	_tmp5__length1 = self->priv->columns_labels_length1;
	_tmp6_ = g_strdup (label);
	_g_free0 (_tmp5_[column]);
	_tmp5_[column] = _tmp6_;
	ft_bubble_chart_queue_update (self);
}

void
ft_bubble_chart_fill (FtBubbleChart* self,
                      gdouble value)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	FtBucket* _tmp1_;
	gint _tmp1__length1;
	gint _tmp1__length2;
	gint _tmp2_;
	gchar** _tmp3_;
	gint _tmp3__length1;
	FtBucket* _tmp4_;
	gint _tmp4__length1;
	gint _tmp4__length2;
	gint _tmp5_;
	FtCategory* _tmp6_;
	gint _tmp6__length1;
	FtMatrix3D* _tmp7_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->rows_labels;
	_tmp0__length1 = self->priv->rows_labels_length1;
	_tmp1_ = self->priv->buckets;
	_tmp1__length1 = self->priv->buckets_length1;
	_tmp1__length2 = self->priv->buckets_length2;
	_tmp2_ = _tmp1__length1;
	_tmp3_ = self->priv->columns_labels;
	_tmp3__length1 = self->priv->columns_labels_length1;
	_tmp4_ = self->priv->buckets;
	_tmp4__length1 = self->priv->buckets_length1;
	_tmp4__length2 = self->priv->buckets_length2;
	_tmp5_ = _tmp4__length2;
	_tmp6_ = self->priv->categories;
	_tmp6__length1 = self->priv->categories_length1;
	ft_bubble_chart_grow_data (self, MAX ((guint) _tmp0__length1, (guint) _tmp2_), MAX ((guint) _tmp3__length1, (guint) _tmp5_), (guint) _tmp6__length1);
	_tmp7_ = self->priv->data;
	ft_matrix3_d_fill (_tmp7_, value);
	ft_bubble_chart_invalidate_max_value (self);
	ft_bubble_chart_queue_update (self);
}

void
ft_bubble_chart_set_values (FtBubbleChart* self,
                            guint row,
                            guint column,
                            gdouble* values,
                            gint values_length1)
{
	gint category_index = 0;
	g_return_if_fail (self != NULL);
	ft_bubble_chart_grow_data (self, row + 1, column + 1, (guint) values_length1);
	category_index = 0;
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = TRUE;
		while (TRUE) {
			FtMatrix3D* _tmp2_;
			gdouble _tmp3_;
			if (!_tmp0_) {
				gint _tmp1_;
				_tmp1_ = category_index;
				category_index = _tmp1_ + 1;
			}
			_tmp0_ = FALSE;
			if (!(category_index < values_length1)) {
				break;
			}
			_tmp2_ = self->priv->data;
			_tmp3_ = values[category_index];
			ft_matrix3_d_set (_tmp2_, (gint) row, (gint) column, category_index, _tmp3_);
		}
	}
	{
		gboolean _tmp4_ = FALSE;
		_tmp4_ = TRUE;
		while (TRUE) {
			FtMatrix3D* _tmp6_;
			guint* _tmp7_;
			gint _tmp7__length1;
			guint _tmp8_;
			FtMatrix3D* _tmp9_;
			if (!_tmp4_) {
				gint _tmp5_;
				_tmp5_ = category_index;
				category_index = _tmp5_ + 1;
			}
			_tmp4_ = FALSE;
			_tmp6_ = self->priv->data;
			_tmp7_ = _tmp6_->shape;
			_tmp7__length1 = _tmp6_->shape_length1;
			_tmp8_ = _tmp7_[2];
			if (!(((guint) category_index) < _tmp8_)) {
				break;
			}
			_tmp9_ = self->priv->data;
			ft_matrix3_d_set (_tmp9_, (gint) row, (gint) column, category_index, 0.0);
		}
	}
	ft_bubble_chart_invalidate_max_value (self);
}

gdouble
ft_bubble_chart_get_value (FtBubbleChart* self,
                           guint row,
                           guint column,
                           guint category_index)
{
	gdouble _tmp0_ = 0.0;
	FtMatrix3D* _tmp1_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp1_ = self->priv->data;
	if (_tmp1_ != NULL) {
		FtMatrix3D* _tmp2_;
		_tmp2_ = self->priv->data;
		_tmp0_ = ft_matrix3_d_get (_tmp2_, (gint) row, (gint) column, (gint) category_index, FT_BUBBLE_CHART_DEFAULT_VALUE);
	} else {
		_tmp0_ = FT_BUBBLE_CHART_DEFAULT_VALUE;
	}
	result = _tmp0_;
	return result;
}

void
ft_bubble_chart_set_value (FtBubbleChart* self,
                           guint row,
                           guint column,
                           guint category_index,
                           gdouble value)
{
	FtMatrix3D* _tmp0_;
	g_return_if_fail (self != NULL);
	ft_bubble_chart_grow_data (self, row + 1, column + 1, category_index + 1);
	_tmp0_ = self->priv->data;
	ft_matrix3_d_set (_tmp0_, (gint) row, (gint) column, (gint) category_index, value);
	ft_bubble_chart_invalidate_max_value (self);
}

inline void
ft_bubble_chart_add_value (FtBubbleChart* self,
                           guint row,
                           guint column,
                           guint category_index,
                           gdouble value)
{
	g_return_if_fail (self != NULL);
	ft_bubble_chart_set_value (self, row, column, category_index, value + ft_bubble_chart_get_value (self, row, column, category_index));
}

static const gchar*
string_to_string (const gchar* self)
{
	const gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}

static GtkWidget*
ft_bubble_chart_create_tooltip_widget (FtBubbleChart* self,
                                       guint row,
                                       guint column)
{
	gint category_count = 0;
	FtCategory* _tmp0_;
	gint _tmp0__length1;
	GtkGrid* grid = NULL;
	GtkGrid* _tmp1_;
	GtkGrid* _tmp2_;
	GtkGrid* _tmp3_;
	GtkGrid* _tmp4_;
	GtkGrid* _tmp5_;
	GtkLabel* header_label = NULL;
	gchar* _tmp6_;
	gchar* _tmp7_;
	GtkLabel* _tmp8_;
	GtkLabel* _tmp9_;
	GtkLabel* _tmp10_;
	GtkGrid* _tmp11_;
	GtkLabel* _tmp12_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->categories;
	_tmp0__length1 = self->priv->categories_length1;
	category_count = _tmp0__length1;
	_tmp1_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp1_);
	grid = _tmp1_;
	_tmp2_ = grid;
	gtk_grid_set_column_spacing (_tmp2_, 10);
	_tmp3_ = grid;
	gtk_grid_set_row_spacing (_tmp3_, 5);
	_tmp4_ = grid;
	gtk_grid_set_row_homogeneous (_tmp4_, TRUE);
	_tmp5_ = grid;
	gtk_widget_add_css_class ((GtkWidget*) _tmp5_, "tooltip-contents");
	_tmp6_ = ft_bubble_chart_get_tooltip_label (self, row, column);
	_tmp7_ = _tmp6_;
	_tmp8_ = (GtkLabel*) gtk_label_new (_tmp7_);
	g_object_ref_sink (_tmp8_);
	_tmp9_ = _tmp8_;
	_g_free0 (_tmp7_);
	header_label = _tmp9_;
	_tmp10_ = header_label;
	gtk_widget_add_css_class ((GtkWidget*) _tmp10_, "tooltip-header");
	_tmp11_ = grid;
	_tmp12_ = header_label;
	gtk_grid_attach (_tmp11_, (GtkWidget*) _tmp12_, 0, 0, 2, 1);
	{
		gint category_index = 0;
		category_index = category_count - 1;
		{
			gboolean _tmp13_ = FALSE;
			_tmp13_ = TRUE;
			while (TRUE) {
				FtCategory category = {0};
				FtCategory* _tmp15_;
				gint _tmp15__length1;
				FtCategory _tmp16_;
				FtCategory _tmp17_;
				FtCategory _tmp18_ = {0};
				gdouble category_value = 0.0;
				GtkLabel* category_label = NULL;
				FtCategory _tmp19_;
				const gchar* _tmp20_;
				const gchar* _tmp21_;
				gchar* _tmp22_;
				gchar* _tmp23_;
				GtkLabel* _tmp24_;
				GtkLabel* _tmp25_;
				GtkLabel* _tmp26_;
				GtkGrid* _tmp27_;
				GtkLabel* _tmp28_;
				GtkLabel* value_label = NULL;
				gchar* _tmp29_;
				gchar* _tmp30_;
				GtkLabel* _tmp31_;
				GtkLabel* _tmp32_;
				GtkLabel* _tmp33_;
				GtkGrid* _tmp34_;
				GtkLabel* _tmp35_;
				if (!_tmp13_) {
					gint _tmp14_;
					_tmp14_ = category_index;
					category_index = _tmp14_ - 1;
				}
				_tmp13_ = FALSE;
				if (!(category_index >= 0)) {
					break;
				}
				_tmp15_ = self->priv->categories;
				_tmp15__length1 = self->priv->categories_length1;
				_tmp16_ = _tmp15_[category_index];
				_tmp17_ = _tmp16_;
				ft_category_copy (&_tmp17_, &_tmp18_);
				category = _tmp18_;
				category_value = ft_bubble_chart_get_value (self, row, column, (guint) category_index);
				_tmp19_ = category;
				_tmp20_ = _tmp19_.label;
				_tmp21_ = string_to_string (_tmp20_);
				_tmp22_ = g_strconcat (_tmp21_, ":", NULL);
				_tmp23_ = _tmp22_;
				_tmp24_ = (GtkLabel*) gtk_label_new (_tmp23_);
				g_object_ref_sink (_tmp24_);
				_tmp25_ = _tmp24_;
				_g_free0 (_tmp23_);
				category_label = _tmp25_;
				_tmp26_ = category_label;
				gtk_widget_set_halign ((GtkWidget*) _tmp26_, GTK_ALIGN_START);
				_tmp27_ = grid;
				_tmp28_ = category_label;
				gtk_grid_attach (_tmp27_, (GtkWidget*) _tmp28_, 0, 1 + category_index, 1, 1);
				_tmp29_ = ft_bubble_chart_format_tooltip_value (self, (guint) category_index, category_value);
				_tmp30_ = _tmp29_;
				_tmp31_ = (GtkLabel*) gtk_label_new (_tmp30_);
				g_object_ref_sink (_tmp31_);
				_tmp32_ = _tmp31_;
				_g_free0 (_tmp30_);
				value_label = _tmp32_;
				_tmp33_ = value_label;
				gtk_widget_set_halign ((GtkWidget*) _tmp33_, GTK_ALIGN_END);
				_tmp34_ = grid;
				_tmp35_ = value_label;
				gtk_grid_attach (_tmp34_, (GtkWidget*) _tmp35_, 1, 1 + category_index, 1, 1);
				_g_object_unref0 (value_label);
				_g_object_unref0 (category_label);
				ft_category_destroy (&category);
			}
		}
	}
	result = (GtkWidget*) grid;
	_g_object_unref0 (header_label);
	return result;
}

static void
ft_bubble_chart_measure_bubble (FtBubbleChart* self,
                                FtGizmo* gizmo,
                                GtkOrientation orientation,
                                gint for_size,
                                gint* minimum,
                                gint* natural,
                                gint* minimum_baseline,
                                gint* natural_baseline)
{
	gint _vala_minimum = 0;
	gint _vala_natural = 0;
	gint _vala_minimum_baseline = 0;
	gint _vala_natural_baseline = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gizmo != NULL);
	_vala_minimum = FT_BUBBLE_CHART_MIN_BUBBLE_SIZE;
	_vala_natural = self->priv->bubble_size;
	_vala_minimum_baseline = -1;
	_vala_natural_baseline = -1;
	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
_vala_GskStroke_free (GskStroke* self)
{
	g_boxed_free (gsk_stroke_get_type (), self);
}

static void
ft_bubble_chart_snapshot_bubble (FtBubbleChart* self,
                                 FtGizmo* gizmo,
                                 GtkSnapshot* snapshot)
{
	guint row = 0U;
	gconstpointer _tmp0_;
	guint column = 0U;
	gconstpointer _tmp1_;
	guint category_index = 0U;
	guint _tmp2_;
	guint _tmp3_;
	gdouble bubble_value = 0.0;
	gfloat bubble_radius = 0.0F;
	graphene_point_t bubble_origin = {0};
	graphene_point_t _tmp4_ = {0};
	gboolean bubble_inverted = FALSE;
	GdkRGBA bubble_color = {0};
	FtCategory* _tmp5_;
	gint _tmp5__length1;
	FtCategory _tmp6_;
	GdkRGBA _tmp7_;
	gboolean _tmp8_ = FALSE;
	gfloat* _tmp9_;
	gint _tmp9__length1;
	gboolean is_empty = FALSE;
	gboolean _tmp12_ = FALSE;
	gboolean _tmp13_ = FALSE;
	GskPathBuilder* path_builder = NULL;
	GskPathBuilder* _tmp14_;
	GskPathBuilder* _tmp15_;
	graphene_point_t _tmp16_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gizmo != NULL);
	g_return_if_fail (snapshot != NULL);
	_tmp0_ = g_object_get_data ((GObject*) gizmo, "row");
	row = (guint) ((guintptr) _tmp0_);
	_tmp1_ = g_object_get_data ((GObject*) gizmo, "column");
	column = (guint) ((guintptr) _tmp1_);
	_tmp2_ = ft_bubble_chart_get_category (self);
	_tmp3_ = _tmp2_;
	category_index = (guint) _tmp3_;
	bubble_value = ft_bubble_chart_get_value (self, row, column, category_index);
	bubble_radius = ft_bubble_chart_calculate_bubble_radius (self, bubble_value);
	memset (&_tmp4_, 0, sizeof (graphene_point_t));
	_tmp4_.x = ((gfloat) gtk_widget_get_width ((GtkWidget*) gizmo)) / 2.0f;
	_tmp4_.y = ((gfloat) gtk_widget_get_height ((GtkWidget*) gizmo)) / 2.0f;
	bubble_origin = _tmp4_;
	bubble_inverted = gtk_widget_has_css_class ((GtkWidget*) gizmo, "inverted");
	_tmp5_ = self->priv->categories;
	_tmp5__length1 = self->priv->categories_length1;
	_tmp6_ = _tmp5_[category_index];
	_tmp7_ = _tmp6_.color;
	bubble_color = _tmp7_;
	_tmp9_ = self->priv->level_radii;
	_tmp9__length1 = self->priv->level_radii_length1;
	if (_tmp9__length1 > 0) {
		gfloat* _tmp10_;
		gint _tmp10__length1;
		gfloat _tmp11_;
		_tmp10_ = self->priv->level_radii;
		_tmp10__length1 = self->priv->level_radii_length1;
		_tmp11_ = _tmp10_[0];
		_tmp8_ = bubble_radius == _tmp11_;
	} else {
		_tmp8_ = FALSE;
	}
	is_empty = _tmp8_;
	if (is_empty) {
		_tmp12_ = bubble_inverted;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		return;
	}
	if (is_empty) {
		_tmp13_ = TRUE;
	} else {
		_tmp13_ = bubble_inverted;
	}
	if (_tmp13_) {
		bubble_color.alpha = 0.1f;
	}
	_tmp14_ = gsk_path_builder_new ();
	path_builder = _tmp14_;
	_tmp15_ = path_builder;
	_tmp16_ = bubble_origin;
	gsk_path_builder_add_circle (_tmp15_, &_tmp16_, bubble_radius);
	if (bubble_inverted) {
		GskStroke* stroke = NULL;
		GskStroke* _tmp17_;
		GskPathBuilder* _tmp18_;
		GskPath* _tmp19_;
		GskPath* _tmp20_;
		GskStroke* _tmp21_;
		GdkRGBA _tmp22_;
		bubble_color.alpha = bubble_color.alpha * 0.9f;
		_tmp17_ = gsk_stroke_new (2.2f);
		stroke = _tmp17_;
		_tmp18_ = path_builder;
		_tmp19_ = gsk_path_builder_to_path (_tmp18_);
		_tmp20_ = _tmp19_;
		_tmp21_ = stroke;
		_tmp22_ = bubble_color;
		gtk_snapshot_append_stroke (snapshot, _tmp20_, _tmp21_, &_tmp22_);
		_gsk_path_unref0 (_tmp20_);
		__vala_GskStroke_free0 (stroke);
	} else {
		GskPathBuilder* _tmp23_;
		GskPath* _tmp24_;
		GskPath* _tmp25_;
		GdkRGBA _tmp26_;
		_tmp23_ = path_builder;
		_tmp24_ = gsk_path_builder_to_path (_tmp23_);
		_tmp25_ = _tmp24_;
		_tmp26_ = bubble_color;
		gtk_snapshot_append_fill (snapshot, _tmp25_, GSK_FILL_RULE_WINDING, &_tmp26_);
		_gsk_path_unref0 (_tmp25_);
	}
	_gsk_path_builder_unref0 (path_builder);
}

static gboolean
ft_bubble_chart_contains_bubble (FtBubbleChart* self,
                                 FtGizmo* gizmo,
                                 gdouble x,
                                 gdouble y)
{
	graphene_point_t point = {0};
	graphene_point_t _tmp0_ = {0};
	graphene_rect_t bounds = {0};
	graphene_rect_t _tmp1_ = {0};
	gboolean _tmp2_;
	graphene_point_t _tmp3_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (gizmo != NULL, FALSE);
	if (!gtk_widget_get_mapped ((GtkWidget*) gizmo)) {
		result = FALSE;
		return result;
	}
	memset (&_tmp0_, 0, sizeof (graphene_point_t));
	_tmp0_.x = (gfloat) x;
	_tmp0_.y = (gfloat) y;
	point = _tmp0_;
	_tmp2_ = gtk_widget_compute_bounds ((GtkWidget*) gizmo, (GtkWidget*) gizmo, &_tmp1_);
	bounds = _tmp1_;
	if (!_tmp2_) {
		result = FALSE;
		return result;
	}
	_tmp3_ = point;
	result = graphene_rect_contains_point (&bounds, &_tmp3_);
	return result;
}

static void
_ft_bubble_chart_measure_bubble_cb_ft_gizmo_measure_func (FtGizmo* gizmo,
                                                          GtkOrientation orientation,
                                                          gint for_size,
                                                          gint* minimum,
                                                          gint* natural,
                                                          gint* minimum_baseline,
                                                          gint* natural_baseline,
                                                          gpointer self)
{
	ft_bubble_chart_measure_bubble_cb (gizmo, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
}

static void
_ft_bubble_chart_snapshot_bubble_cb_ft_gizmo_snapshot_func (FtGizmo* gizmo,
                                                            GtkSnapshot* snapshot,
                                                            gpointer self)
{
	ft_bubble_chart_snapshot_bubble_cb (gizmo, snapshot);
}

static gboolean
_ft_bubble_chart_contains_bubble_cb_ft_gizmo_contains_func (FtGizmo* gizmo,
                                                            gdouble x,
                                                            gdouble y,
                                                            gpointer self)
{
	gboolean result;
	result = ft_bubble_chart_contains_bubble_cb (gizmo, x, y);
	return result;
}

static gboolean
_ft_bubble_chart_on_query_tooltip_cb_gtk_widget_query_tooltip (GtkWidget* _sender,
                                                               gint x,
                                                               gint y,
                                                               gboolean keyboard_tooltip,
                                                               GtkTooltip* tooltip,
                                                               gpointer self)
{
	gboolean result;
	result = ft_bubble_chart_on_query_tooltip_cb (_sender, x, y, keyboard_tooltip, tooltip);
	return result;
}

static Block6Data*
block6_data_ref (Block6Data* _data6_)
{
	g_atomic_int_inc (&_data6_->_ref_count_);
	return _data6_;
}

static void
block6_data_unref (void * _userdata_)
{
	Block6Data* _data6_;
	_data6_ = (Block6Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data6_->_ref_count_)) {
		FtBubbleChart* self;
		self = _data6_->self;
		_g_object_unref0 (self);
		g_slice_free (Block6Data, _data6_);
	}
}

static void
___lambda19_ (Block6Data* _data6_,
              gint n_press,
              gdouble x,
              gdouble y)
{
	FtBubbleChart* self;
	FtGizmo* _tmp0_;
	self = _data6_->self;
	_tmp0_ = _data6_->weak_bubble;
	ft_bubble_chart_on_clicked_cb ((GtkWidget*) _tmp0_);
}

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

static GtkWidget*
ft_bubble_chart_create_bubble (FtBubbleChart* self,
                               guint row,
                               guint column)
{
	FtGizmo* bubble = NULL;
	FtGizmo* _tmp0_;
	FtGizmo* _tmp1_;
	FtGizmo* _tmp2_;
	FtGizmo* _tmp3_;
	FtGizmo* _tmp4_;
	FtGizmo* _tmp5_;
	FtGizmo* _tmp6_;
	gboolean _tmp7_;
	FtGizmo* _tmp16_;
	GtkWidget* _tmp17_;
	GtkWidget* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = ft_gizmo_new (_ft_bubble_chart_measure_bubble_cb_ft_gizmo_measure_func, NULL, NULL, NULL, NULL, NULL, _ft_bubble_chart_snapshot_bubble_cb_ft_gizmo_snapshot_func, NULL, NULL, _ft_bubble_chart_contains_bubble_cb_ft_gizmo_contains_func, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	g_object_ref_sink (_tmp0_);
	bubble = _tmp0_;
	_tmp1_ = bubble;
	gtk_widget_set_focusable ((GtkWidget*) _tmp1_, FALSE);
	_tmp2_ = bubble;
	gtk_widget_set_has_tooltip ((GtkWidget*) _tmp2_, TRUE);
	_tmp3_ = bubble;
	gtk_widget_add_css_class ((GtkWidget*) _tmp3_, "bubble");
	_tmp4_ = bubble;
	g_object_set_data_full ((GObject*) _tmp4_, "row", (gpointer) ((guintptr) row), NULL);
	_tmp5_ = bubble;
	g_object_set_data_full ((GObject*) _tmp5_, "column", (gpointer) ((guintptr) column), NULL);
	_tmp6_ = bubble;
	g_signal_connect ((GtkWidget*) _tmp6_, "query-tooltip", (GCallback) _ft_bubble_chart_on_query_tooltip_cb_gtk_widget_query_tooltip, NULL);
	_tmp7_ = self->priv->_activate_on_click;
	if (_tmp7_) {
		Block6Data* _data6_;
		FtGizmo* _tmp8_;
		GtkGestureClick* click_gesture = NULL;
		GtkGestureClick* _tmp9_;
		GtkGestureClick* _tmp10_;
		GtkGestureClick* _tmp11_;
		FtGizmo* _tmp12_;
		GtkGestureClick* _tmp13_;
		GtkEventController* _tmp14_;
		_data6_ = g_slice_new0 (Block6Data);
		_data6_->_ref_count_ = 1;
		_data6_->self = g_object_ref (self);
		_tmp8_ = bubble;
		_data6_->weak_bubble = _tmp8_;
		_tmp9_ = (GtkGestureClick*) gtk_gesture_click_new ();
		click_gesture = _tmp9_;
		_tmp10_ = click_gesture;
		gtk_gesture_single_set_button ((GtkGestureSingle*) _tmp10_, (guint) GDK_BUTTON_PRIMARY);
		_tmp11_ = click_gesture;
		g_signal_connect_data (_tmp11_, "released", (GCallback) ____lambda19__gtk_gesture_click_released, block6_data_ref (_data6_), (GClosureNotify) block6_data_unref, 0);
		_tmp12_ = bubble;
		_tmp13_ = click_gesture;
		_tmp14_ = _g_object_ref0 ((GtkEventController*) _tmp13_);
		gtk_widget_add_controller ((GtkWidget*) _tmp12_, _tmp14_);
		_g_object_unref0 (click_gesture);
		block6_data_unref (_data6_);
		_data6_ = NULL;
	} else {
		FtGizmo* _tmp15_;
		_tmp15_ = bubble;
		gtk_widget_set_state_flags ((GtkWidget*) _tmp15_, GTK_STATE_FLAG_INSENSITIVE, FALSE);
	}
	_tmp16_ = bubble;
	_tmp17_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, gtk_widget_get_type (), GtkWidget));
	result = _tmp17_;
	_g_object_unref0 (bubble);
	return result;
}

static FtBubbleChart*
ft_bubble_chart_from_gizmo (FtGizmo* gizmo)
{
	GtkWidget* widget = NULL;
	GtkWidget* _tmp0_;
	FtBubbleChart* result;
	g_return_val_if_fail (gizmo != NULL, NULL);
	_tmp0_ = _g_object_ref0 ((GtkWidget*) gizmo);
	widget = _tmp0_;
	while (TRUE) {
		GtkWidget* _tmp1_;
		FtBubbleChart* chart = NULL;
		GtkWidget* _tmp2_;
		FtBubbleChart* _tmp3_;
		FtBubbleChart* _tmp4_;
		GtkWidget* _tmp5_;
		GtkWidget* _tmp6_;
		GtkWidget* _tmp7_;
		_tmp1_ = widget;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = widget;
		_tmp3_ = _g_object_ref0 (FT_IS_BUBBLE_CHART (_tmp2_) ? ((FtBubbleChart*) _tmp2_) : NULL);
		chart = _tmp3_;
		_tmp4_ = chart;
		if (_tmp4_ != NULL) {
			result = chart;
			_g_object_unref0 (widget);
			return result;
		}
		_tmp5_ = widget;
		_tmp6_ = gtk_widget_get_parent (_tmp5_);
		_tmp7_ = _g_object_ref0 (_tmp6_);
		_g_object_unref0 (widget);
		widget = _tmp7_;
		_g_object_unref0 (chart);
	}
	result = NULL;
	_g_object_unref0 (widget);
	return result;
}

static FtBubbleChart*
ft_bubble_chart_from_widget (GtkWidget* widget)
{
	GtkWidget* current = NULL;
	GtkWidget* _tmp0_;
	FtBubbleChart* result;
	g_return_val_if_fail (widget != NULL, NULL);
	_tmp0_ = _g_object_ref0 (widget);
	current = _tmp0_;
	while (TRUE) {
		GtkWidget* _tmp1_;
		FtBubbleChart* chart = NULL;
		GtkWidget* _tmp2_;
		FtBubbleChart* _tmp3_;
		FtBubbleChart* _tmp4_;
		GtkWidget* _tmp5_;
		GtkWidget* _tmp6_;
		GtkWidget* _tmp7_;
		_tmp1_ = current;
		if (!(_tmp1_ != NULL)) {
			break;
		}
		_tmp2_ = current;
		_tmp3_ = _g_object_ref0 (FT_IS_BUBBLE_CHART (_tmp2_) ? ((FtBubbleChart*) _tmp2_) : NULL);
		chart = _tmp3_;
		_tmp4_ = chart;
		if (_tmp4_ != NULL) {
			result = chart;
			_g_object_unref0 (current);
			return result;
		}
		_tmp5_ = current;
		_tmp6_ = gtk_widget_get_parent (_tmp5_);
		_tmp7_ = _g_object_ref0 (_tmp6_);
		_g_object_unref0 (current);
		current = _tmp7_;
		_g_object_unref0 (chart);
	}
	result = NULL;
	_g_object_unref0 (current);
	return result;
}

static void
ft_bubble_chart_measure_bubble_cb (FtGizmo* gizmo,
                                   GtkOrientation orientation,
                                   gint for_size,
                                   gint* minimum,
                                   gint* natural,
                                   gint* minimum_baseline,
                                   gint* natural_baseline)
{
	gint _vala_minimum = 0;
	gint _vala_natural = 0;
	gint _vala_minimum_baseline = 0;
	gint _vala_natural_baseline = 0;
	FtBubbleChart* _self_ = NULL;
	FtBubbleChart* _tmp0_;
	FtBubbleChart* _tmp1_;
	g_return_if_fail (gizmo != NULL);
	_tmp0_ = ft_bubble_chart_from_gizmo (gizmo);
	_self_ = _tmp0_;
	_tmp1_ = _self_;
	if (_tmp1_ != NULL) {
		FtBubbleChart* _tmp2_;
		gint _tmp3_ = 0;
		gint _tmp4_ = 0;
		gint _tmp5_ = 0;
		gint _tmp6_ = 0;
		_tmp2_ = _self_;
		ft_bubble_chart_measure_bubble (_tmp2_, gizmo, orientation, for_size, &_tmp3_, &_tmp4_, &_tmp5_, &_tmp6_);
		_vala_minimum = _tmp3_;
		_vala_natural = _tmp4_;
		_vala_minimum_baseline = _tmp5_;
		_vala_natural_baseline = _tmp6_;
	} else {
		_vala_minimum = 0;
		_vala_natural = 0;
		_vala_minimum_baseline = -1;
		_vala_natural_baseline = -1;
	}
	_g_object_unref0 (_self_);
	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
ft_bubble_chart_snapshot_bubble_cb (FtGizmo* gizmo,
                                    GtkSnapshot* snapshot)
{
	FtBubbleChart* _self_ = NULL;
	FtBubbleChart* _tmp0_;
	FtBubbleChart* _tmp1_;
	g_return_if_fail (gizmo != NULL);
	g_return_if_fail (snapshot != NULL);
	_tmp0_ = ft_bubble_chart_from_gizmo (gizmo);
	_self_ = _tmp0_;
	_tmp1_ = _self_;
	if (_tmp1_ != NULL) {
		FtBubbleChart* _tmp2_;
		_tmp2_ = _self_;
		ft_bubble_chart_snapshot_bubble (_tmp2_, gizmo, snapshot);
	}
	_g_object_unref0 (_self_);
}

static gboolean
ft_bubble_chart_contains_bubble_cb (FtGizmo* gizmo,
                                    gdouble x,
                                    gdouble y)
{
	FtBubbleChart* _self_ = NULL;
	FtBubbleChart* _tmp0_;
	gboolean _tmp1_ = FALSE;
	FtBubbleChart* _tmp2_;
	gboolean result;
	g_return_val_if_fail (gizmo != NULL, FALSE);
	_tmp0_ = ft_bubble_chart_from_gizmo (gizmo);
	_self_ = _tmp0_;
	_tmp2_ = _self_;
	if (_tmp2_ != NULL) {
		FtBubbleChart* _tmp3_;
		_tmp3_ = _self_;
		_tmp1_ = ft_bubble_chart_contains_bubble (_tmp3_, gizmo, x, y);
	} else {
		_tmp1_ = FALSE;
	}
	result = _tmp1_;
	_g_object_unref0 (_self_);
	return result;
}

static gboolean
ft_bubble_chart_on_query_tooltip_cb (GtkWidget* widget,
                                     gint x,
                                     gint y,
                                     gboolean keyboard_tooltip,
                                     GtkTooltip* tooltip)
{
	FtBubbleChart* _self_ = NULL;
	FtBubbleChart* _tmp0_;
	guint row = 0U;
	gconstpointer _tmp1_;
	guint column = 0U;
	gconstpointer _tmp2_;
	FtBubbleChart* _tmp3_;
	gboolean _tmp4_ = FALSE;
	FtBubbleChart* _tmp5_;
	FtBubbleChart* _tmp12_;
	GtkWidget* _tmp13_;
	FtBubbleChart* _tmp14_;
	GtkWidget* _tmp15_;
	gboolean result;
	g_return_val_if_fail (widget != NULL, FALSE);
	g_return_val_if_fail (tooltip != NULL, FALSE);
	_tmp0_ = ft_bubble_chart_from_widget (widget);
	_self_ = _tmp0_;
	_tmp1_ = g_object_get_data ((GObject*) widget, "row");
	row = (guint) ((guintptr) _tmp1_);
	_tmp2_ = g_object_get_data ((GObject*) widget, "column");
	column = (guint) ((guintptr) _tmp2_);
	_tmp3_ = _self_;
	if (_tmp3_ == NULL) {
		result = FALSE;
		_g_object_unref0 (_self_);
		return result;
	}
	_tmp5_ = _self_;
	if (((guint) _tmp5_->priv->tooltip_row) != row) {
		_tmp4_ = TRUE;
	} else {
		FtBubbleChart* _tmp6_;
		_tmp6_ = _self_;
		_tmp4_ = ((guint) _tmp6_->priv->tooltip_column) != column;
	}
	if (_tmp4_) {
		FtBubbleChart* _tmp7_;
		FtBubbleChart* _tmp8_;
		FtBubbleChart* _tmp9_;
		FtBubbleChart* _tmp10_;
		GtkWidget* _tmp11_;
		_tmp7_ = _self_;
		_tmp7_->priv->tooltip_row = (gint) row;
		_tmp8_ = _self_;
		_tmp8_->priv->tooltip_column = (gint) column;
		_tmp9_ = _self_;
		_tmp10_ = _self_;
		_tmp11_ = ft_bubble_chart_create_tooltip_widget (_tmp10_, row, column);
		_g_object_unref0 (_tmp9_->priv->tooltip_widget);
		_tmp9_->priv->tooltip_widget = _tmp11_;
	}
	_tmp12_ = _self_;
	_tmp13_ = _tmp12_->priv->tooltip_widget;
	gtk_tooltip_set_custom (tooltip, _tmp13_);
	_tmp14_ = _self_;
	_tmp15_ = _tmp14_->priv->tooltip_widget;
	result = _tmp15_ != NULL;
	_g_object_unref0 (_self_);
	return result;
}

static void
ft_bubble_chart_on_clicked_cb (GtkWidget* widget)
{
	FtBubbleChart* _self_ = NULL;
	FtBubbleChart* _tmp0_;
	guint row = 0U;
	gconstpointer _tmp1_;
	guint column = 0U;
	gconstpointer _tmp2_;
	FtBubbleChart* _tmp3_;
	gdouble bubble_value = 0.0;
	FtBubbleChart* _tmp4_;
	FtBubbleChart* _tmp5_;
	guint _tmp6_;
	guint _tmp7_;
	gboolean _tmp8_ = FALSE;
	g_return_if_fail (widget != NULL);
	_tmp0_ = ft_bubble_chart_from_gizmo (G_TYPE_CHECK_INSTANCE_CAST (widget, FT_TYPE_GIZMO, FtGizmo));
	_self_ = _tmp0_;
	_tmp1_ = g_object_get_data ((GObject*) widget, "row");
	row = (guint) ((guintptr) _tmp1_);
	_tmp2_ = g_object_get_data ((GObject*) widget, "column");
	column = (guint) ((guintptr) _tmp2_);
	_tmp3_ = _self_;
	if (_tmp3_ == NULL) {
		_g_object_unref0 (_self_);
		return;
	}
	_tmp4_ = _self_;
	_tmp5_ = _self_;
	_tmp6_ = ft_bubble_chart_get_category (_tmp5_);
	_tmp7_ = _tmp6_;
	bubble_value = ft_bubble_chart_get_value (_tmp4_, row, column, (guint) _tmp7_);
	if (!isnan (bubble_value)) {
		_tmp8_ = bubble_value > 0.0;
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		FtBubbleChart* _tmp9_;
		_tmp9_ = _self_;
		g_signal_emit (_tmp9_, ft_bubble_chart_signals[FT_BUBBLE_CHART_BUBBLE_ACTIVATED_SIGNAL], 0, row, column);
	}
	_g_object_unref0 (_self_);
}

static GtkSizeRequestMode
ft_bubble_chart_real_get_request_mode (GtkWidget* base)
{
	FtBubbleChart * self;
	GtkSizeRequestMode result;
	self = (FtBubbleChart*) base;
	result = GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
	return result;
}

static void
ft_bubble_chart_real_measure (GtkWidget* base,
                              GtkOrientation orientation,
                              gint for_size,
                              gint* minimum,
                              gint* natural,
                              gint* minimum_baseline,
                              gint* natural_baseline)
{
	FtBubbleChart * self;
	gint _vala_minimum = 0;
	gint _vala_natural = 0;
	gint _vala_minimum_baseline = 0;
	gint _vala_natural_baseline = 0;
	gint columns_box_minimum = 0;
	gint columns_box_natural = 0;
	gint rows_box_minimum = 0;
	gint rows_box_natural = 0;
	gint _tmp0_ = 0;
	FtMatrix3D* _tmp1_;
	gint rows = 0;
	gchar** _tmp5_;
	gint _tmp5__length1;
	gint _tmp6_ = 0;
	FtMatrix3D* _tmp7_;
	gint columns = 0;
	gchar** _tmp11_;
	gint _tmp11__length1;
	GtkBox* _tmp12_;
	gint _tmp13_ = 0;
	gint _tmp14_ = 0;
	GtkBox* _tmp15_;
	gint _tmp16_ = 0;
	gint _tmp17_ = 0;
	self = (FtBubbleChart*) base;
	columns_box_minimum = 0;
	columns_box_natural = 0;
	rows_box_minimum = 0;
	rows_box_natural = 0;
	_tmp1_ = self->priv->data;
	if (_tmp1_ != NULL) {
		FtMatrix3D* _tmp2_;
		guint* _tmp3_;
		gint _tmp3__length1;
		guint _tmp4_;
		_tmp2_ = self->priv->data;
		_tmp3_ = _tmp2_->shape;
		_tmp3__length1 = _tmp2_->shape_length1;
		_tmp4_ = _tmp3_[0];
		_tmp0_ = (gint) _tmp4_;
	} else {
		_tmp0_ = 0;
	}
	_tmp5_ = self->priv->rows_labels;
	_tmp5__length1 = self->priv->rows_labels_length1;
	rows = MAX (_tmp0_, _tmp5__length1);
	_tmp7_ = self->priv->data;
	if (_tmp7_ != NULL) {
		FtMatrix3D* _tmp8_;
		guint* _tmp9_;
		gint _tmp9__length1;
		guint _tmp10_;
		_tmp8_ = self->priv->data;
		_tmp9_ = _tmp8_->shape;
		_tmp9__length1 = _tmp8_->shape_length1;
		_tmp10_ = _tmp9_[1];
		_tmp6_ = (gint) _tmp10_;
	} else {
		_tmp6_ = 0;
	}
	_tmp11_ = self->priv->columns_labels;
	_tmp11__length1 = self->priv->columns_labels_length1;
	columns = MAX (_tmp6_, _tmp11__length1);
	_tmp12_ = self->priv->columns_box;
	gtk_widget_measure ((GtkWidget*) _tmp12_, orientation, for_size, &_tmp13_, &_tmp14_, NULL, NULL);
	columns_box_minimum = _tmp13_;
	columns_box_natural = _tmp14_;
	_tmp15_ = self->priv->rows_box;
	gtk_widget_measure ((GtkWidget*) _tmp15_, orientation, for_size, &_tmp16_, &_tmp17_, NULL, NULL);
	rows_box_minimum = _tmp16_;
	rows_box_natural = _tmp17_;
	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
		GtkGrid* _tmp18_;
		gint _tmp19_;
		gint _tmp20_;
		GtkGrid* _tmp21_;
		gint _tmp22_;
		gint _tmp23_;
		GtkGrid* _tmp24_;
		gint _tmp25_;
		gint _tmp26_;
		GtkGrid* _tmp27_;
		gint _tmp28_;
		gint _tmp29_;
		_tmp18_ = self->priv->layout_grid;
		_tmp19_ = gtk_grid_get_column_spacing (_tmp18_);
		_tmp20_ = _tmp19_;
		_tmp21_ = self->priv->bubbles_grid;
		_tmp22_ = gtk_grid_get_column_spacing (_tmp21_);
		_tmp23_ = _tmp22_;
		_vala_minimum = (rows_box_minimum + _tmp20_) + MAX ((FT_BUBBLE_CHART_MIN_BUBBLE_SIZE * columns) + (_tmp23_ * (columns - 1)), columns_box_minimum);
		_tmp24_ = self->priv->layout_grid;
		_tmp25_ = gtk_grid_get_column_spacing (_tmp24_);
		_tmp26_ = _tmp25_;
		_tmp27_ = self->priv->bubbles_grid;
		_tmp28_ = gtk_grid_get_column_spacing (_tmp27_);
		_tmp29_ = _tmp28_;
		_vala_natural = (rows_box_natural + _tmp26_) + MAX ((FT_BUBBLE_CHART_MIN_BUBBLE_SIZE * columns) + (_tmp29_ * (columns - 1)), columns_box_natural);
	} else {
		gint minimum_bubble_size = 0;
		gint natural_bubble_size = 0;
		gboolean _tmp30_ = FALSE;
		GtkGrid* _tmp40_;
		gint _tmp41_;
		gint _tmp42_;
		GtkGrid* _tmp43_;
		gint _tmp44_;
		gint _tmp45_;
		GtkGrid* _tmp46_;
		gint _tmp47_;
		gint _tmp48_;
		GtkGrid* _tmp49_;
		gint _tmp50_;
		gint _tmp51_;
		minimum_bubble_size = FT_BUBBLE_CHART_MIN_BUBBLE_SIZE;
		natural_bubble_size = FT_BUBBLE_CHART_MIN_BUBBLE_SIZE;
		if (for_size > 0) {
			_tmp30_ = columns > 0;
		} else {
			_tmp30_ = FALSE;
		}
		if (_tmp30_) {
			gint total_column_spacing = 0;
			GtkGrid* _tmp31_;
			gint _tmp32_;
			gint _tmp33_;
			GtkGrid* _tmp34_;
			gint _tmp35_;
			gint _tmp36_;
			gint rows_box_minimum_width = 0;
			gint rows_box_natural_width = 0;
			GtkBox* _tmp37_;
			gint _tmp38_ = 0;
			gint _tmp39_ = 0;
			_tmp31_ = self->priv->layout_grid;
			_tmp32_ = gtk_grid_get_column_spacing (_tmp31_);
			_tmp33_ = _tmp32_;
			_tmp34_ = self->priv->bubbles_grid;
			_tmp35_ = gtk_grid_get_column_spacing (_tmp34_);
			_tmp36_ = _tmp35_;
			total_column_spacing = _tmp33_ + (_tmp36_ * (columns - 1));
			rows_box_minimum_width = 0;
			rows_box_natural_width = 0;
			_tmp37_ = self->priv->rows_box;
			gtk_widget_measure ((GtkWidget*) _tmp37_, GTK_ORIENTATION_HORIZONTAL, -1, &_tmp38_, &_tmp39_, NULL, NULL);
			rows_box_minimum_width = _tmp38_;
			rows_box_natural_width = _tmp39_;
			minimum_bubble_size = CLAMP (((for_size - rows_box_minimum_width) - total_column_spacing) / columns, FT_BUBBLE_CHART_MIN_BUBBLE_SIZE, FT_BUBBLE_CHART_MAX_BUBBLE_SIZE);
			natural_bubble_size = CLAMP (((for_size - rows_box_natural_width) - total_column_spacing) / columns, FT_BUBBLE_CHART_MIN_BUBBLE_SIZE, FT_BUBBLE_CHART_MAX_BUBBLE_SIZE);
		}
		_tmp40_ = self->priv->layout_grid;
		_tmp41_ = gtk_grid_get_row_spacing (_tmp40_);
		_tmp42_ = _tmp41_;
		_tmp43_ = self->priv->bubbles_grid;
		_tmp44_ = gtk_grid_get_row_spacing (_tmp43_);
		_tmp45_ = _tmp44_;
		_vala_minimum = (columns_box_minimum + _tmp42_) + MAX ((minimum_bubble_size * rows) + (_tmp45_ * (rows - 1)), rows_box_minimum);
		_tmp46_ = self->priv->layout_grid;
		_tmp47_ = gtk_grid_get_row_spacing (_tmp46_);
		_tmp48_ = _tmp47_;
		_tmp49_ = self->priv->bubbles_grid;
		_tmp50_ = gtk_grid_get_row_spacing (_tmp49_);
		_tmp51_ = _tmp50_;
		_vala_natural = (columns_box_natural + _tmp48_) + MAX ((natural_bubble_size * rows) + (_tmp51_ * (rows - 1)), rows_box_natural);
	}
	if (_vala_natural < _vala_minimum) {
		_vala_natural = _vala_minimum;
	}
	_vala_minimum_baseline = -1;
	_vala_natural_baseline = -1;
	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
ft_bubble_chart_real_size_allocate (GtkWidget* base,
                                    gint width,
                                    gint height,
                                    gint baseline)
{
	FtBubbleChart * self;
	gint _tmp0_ = 0;
	FtMatrix3D* _tmp1_;
	gint rows = 0;
	gchar** _tmp5_;
	gint _tmp5__length1;
	gint _tmp6_ = 0;
	FtMatrix3D* _tmp7_;
	gint columns = 0;
	gchar** _tmp11_;
	gint _tmp11__length1;
	gint columns_box_height = 0;
	gint rows_box_width = 0;
	GtkBox* _tmp12_;
	gint _tmp13_ = 0;
	GtkBox* _tmp14_;
	GtkGrid* _tmp15_;
	gint _tmp16_;
	gint _tmp17_;
	gint _tmp18_ = 0;
	gint total_column_spacing = 0;
	GtkGrid* _tmp19_;
	gint _tmp20_;
	gint _tmp21_;
	GtkGrid* _tmp22_;
	gint _tmp23_;
	gint _tmp24_;
	gint total_row_spacing = 0;
	GtkGrid* _tmp25_;
	gint _tmp26_;
	gint _tmp27_;
	GtkGrid* _tmp28_;
	gint _tmp29_;
	gint _tmp30_;
	gint _tmp31_ = 0;
	gint h_bubble_size = 0;
	gint _tmp32_ = 0;
	gint v_bubble_size = 0;
	gint bubble_size = 0;
	GtkAllocation allocation = {0};
	GtkAllocation _tmp33_ = {0};
	GtkGrid* _tmp34_;
	GtkAllocation _tmp35_;
	self = (FtBubbleChart*) base;
	_tmp1_ = self->priv->data;
	if (_tmp1_ != NULL) {
		FtMatrix3D* _tmp2_;
		guint* _tmp3_;
		gint _tmp3__length1;
		guint _tmp4_;
		_tmp2_ = self->priv->data;
		_tmp3_ = _tmp2_->shape;
		_tmp3__length1 = _tmp2_->shape_length1;
		_tmp4_ = _tmp3_[0];
		_tmp0_ = (gint) _tmp4_;
	} else {
		_tmp0_ = 0;
	}
	_tmp5_ = self->priv->rows_labels;
	_tmp5__length1 = self->priv->rows_labels_length1;
	rows = MAX (_tmp0_, _tmp5__length1);
	_tmp7_ = self->priv->data;
	if (_tmp7_ != NULL) {
		FtMatrix3D* _tmp8_;
		guint* _tmp9_;
		gint _tmp9__length1;
		guint _tmp10_;
		_tmp8_ = self->priv->data;
		_tmp9_ = _tmp8_->shape;
		_tmp9__length1 = _tmp8_->shape_length1;
		_tmp10_ = _tmp9_[1];
		_tmp6_ = (gint) _tmp10_;
	} else {
		_tmp6_ = 0;
	}
	_tmp11_ = self->priv->columns_labels;
	_tmp11__length1 = self->priv->columns_labels_length1;
	columns = MAX (_tmp6_, _tmp11__length1);
	columns_box_height = 0;
	rows_box_width = 0;
	ft_bubble_chart_ensure_max_value (self);
	_tmp12_ = self->priv->columns_box;
	gtk_widget_measure ((GtkWidget*) _tmp12_, GTK_ORIENTATION_VERTICAL, -1, NULL, &_tmp13_, NULL, NULL);
	columns_box_height = _tmp13_;
	_tmp14_ = self->priv->rows_box;
	_tmp15_ = self->priv->layout_grid;
	_tmp16_ = gtk_grid_get_row_spacing (_tmp15_);
	_tmp17_ = _tmp16_;
	gtk_widget_measure ((GtkWidget*) _tmp14_, GTK_ORIENTATION_HORIZONTAL, (height - columns_box_height) - _tmp17_, NULL, &_tmp18_, NULL, NULL);
	rows_box_width = _tmp18_;
	_tmp19_ = self->priv->layout_grid;
	_tmp20_ = gtk_grid_get_column_spacing (_tmp19_);
	_tmp21_ = _tmp20_;
	_tmp22_ = self->priv->bubbles_grid;
	_tmp23_ = gtk_grid_get_column_spacing (_tmp22_);
	_tmp24_ = _tmp23_;
	total_column_spacing = _tmp21_ + (_tmp24_ * (columns - 1));
	_tmp25_ = self->priv->layout_grid;
	_tmp26_ = gtk_grid_get_row_spacing (_tmp25_);
	_tmp27_ = _tmp26_;
	_tmp28_ = self->priv->bubbles_grid;
	_tmp29_ = gtk_grid_get_row_spacing (_tmp28_);
	_tmp30_ = _tmp29_;
	total_row_spacing = _tmp27_ + (_tmp30_ * (rows - 1));
	if (columns > 0) {
		_tmp31_ = ((width - rows_box_width) - total_column_spacing) / columns;
	} else {
		_tmp31_ = FT_BUBBLE_CHART_MIN_BUBBLE_SIZE;
	}
	h_bubble_size = _tmp31_;
	if (rows > 0) {
		_tmp32_ = ((height - columns_box_height) - total_row_spacing) / rows;
	} else {
		_tmp32_ = FT_BUBBLE_CHART_MIN_BUBBLE_SIZE;
	}
	v_bubble_size = _tmp32_;
	bubble_size = CLAMP (MIN (h_bubble_size, v_bubble_size), FT_BUBBLE_CHART_MIN_BUBBLE_SIZE, FT_BUBBLE_CHART_MAX_BUBBLE_SIZE);
	if (self->priv->bubble_size != bubble_size) {
		self->priv->bubble_size = bubble_size;
		ft_bubble_chart_update_level_radii (self);
		ft_bubble_chart_queue_resize_bubbles (self);
	}
	memset (&_tmp33_, 0, sizeof (GtkAllocation));
	_tmp33_.width = width;
	_tmp33_.height = height;
	allocation = _tmp33_;
	_tmp34_ = self->priv->layout_grid;
	_tmp35_ = allocation;
	gtk_widget_size_allocate ((GtkWidget*) _tmp34_, &_tmp35_, -1);
}

static void
ft_bubble_chart_real_snapshot (GtkWidget* base,
                               GtkSnapshot* snapshot)
{
	FtBubbleChart * self;
	GtkGrid* _tmp0_;
	self = (FtBubbleChart*) base;
	g_return_if_fail (snapshot != NULL);
	_tmp0_ = self->priv->layout_grid;
	gtk_widget_snapshot_child ((GtkWidget*) self, (GtkWidget*) _tmp0_, snapshot);
}

static void
ft_bubble_chart_real_dispose (GObject* base)
{
	FtBubbleChart * self;
	self = (FtBubbleChart*) base;
	_ft_matrix3_d_free0 (self->priv->data);
	self->priv->data = NULL;
	self->priv->categories = (_vala_FtCategory_array_free (self->priv->categories, self->priv->categories_length1), NULL);
	self->priv->categories = NULL;
	self->priv->categories_length1 = 0;
	self->priv->_categories_size_ = self->priv->categories_length1;
	self->priv->buckets = (_vala_FtBucket_array_free (self->priv->buckets, self->priv->buckets_length1 * self->priv->buckets_length2), NULL);
	self->priv->buckets = NULL;
	self->priv->buckets_length1 = 0;
	self->priv->buckets_length2 = 0;
	self->priv->rows_labels = (_vala_array_free (self->priv->rows_labels, self->priv->rows_labels_length1, (GDestroyNotify) g_free), NULL);
	self->priv->rows_labels = NULL;
	self->priv->rows_labels_length1 = 0;
	self->priv->_rows_labels_size_ = self->priv->rows_labels_length1;
	self->priv->columns_labels = (_vala_array_free (self->priv->columns_labels, self->priv->columns_labels_length1, (GDestroyNotify) g_free), NULL);
	self->priv->columns_labels = NULL;
	self->priv->columns_labels_length1 = 0;
	self->priv->_columns_labels_size_ = self->priv->columns_labels_length1;
	self->priv->level_radii = (g_free (self->priv->level_radii), NULL);
	self->priv->level_radii = NULL;
	self->priv->level_radii_length1 = 0;
	self->priv->_level_radii_size_ = self->priv->level_radii_length1;
	_g_object_unref0 (self->priv->tooltip_widget);
	self->priv->tooltip_widget = NULL;
	G_OBJECT_CLASS (ft_bubble_chart_parent_class)->dispose ((GObject*) G_TYPE_CHECK_INSTANCE_CAST (self, gtk_widget_get_type (), GtkWidget));
}

FtBubbleChart*
ft_bubble_chart_construct (GType object_type)
{
	FtBubbleChart * self = NULL;
	self = (FtBubbleChart*) g_object_new (object_type, NULL);
	return self;
}

FtBubbleChart*
ft_bubble_chart_new (void)
{
	return ft_bubble_chart_construct (FT_TYPE_BUBBLE_CHART);
}

gdouble
ft_bubble_chart_get_reference_value (FtBubbleChart* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	result = self->priv->_reference_value;
	return result;
}

void
ft_bubble_chart_set_reference_value (FtBubbleChart* self,
                                     gdouble value)
{
	g_return_if_fail (self != NULL);
	if (self->priv->_reference_value == value) {
		return;
	}
	self->priv->_reference_value = value;
	ft_bubble_chart_invalidate_max_value (self);
	g_object_notify_by_pspec ((GObject *) self, ft_bubble_chart_properties[FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY]);
}

guint
ft_bubble_chart_get_category (FtBubbleChart* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_category;
	return result;
}

void
ft_bubble_chart_set_category (FtBubbleChart* self,
                              guint value)
{
	g_return_if_fail (self != NULL);
	if (self->priv->_category == value) {
		return;
	}
	self->priv->_category = value;
	ft_bubble_chart_invalidate_max_value (self);
	g_object_notify_by_pspec ((GObject *) self, ft_bubble_chart_properties[FT_BUBBLE_CHART_CATEGORY_PROPERTY]);
}

gboolean
ft_bubble_chart_get_activate_on_click (FtBubbleChart* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_activate_on_click;
	return result;
}

void
ft_bubble_chart_set_activate_on_click (FtBubbleChart* self,
                                       gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_bubble_chart_get_activate_on_click (self);
	if (old_value != value) {
		self->priv->_activate_on_click = value;
		g_object_notify_by_pspec ((GObject *) self, ft_bubble_chart_properties[FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY]);
	}
}

guint
ft_bubble_chart_get_levels (FtBubbleChart* self)
{
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_levels;
	return result;
}

void
ft_bubble_chart_set_levels (FtBubbleChart* self,
                            guint value)
{
	g_return_if_fail (self != NULL);
	if (self->priv->_levels == value) {
		return;
	}
	self->priv->_levels = value;
	ft_bubble_chart_update_level_radii (self);
	ft_bubble_chart_queue_draw_bubbles (self);
	g_object_notify_by_pspec ((GObject *) self, ft_bubble_chart_properties[FT_BUBBLE_CHART_LEVELS_PROPERTY]);
}

static void
g_cclosure_user_marshal_VOID__UINT_UINT (GClosure * closure,
                                         GValue * return_value,
                                         guint n_param_values,
                                         const GValue * param_values,
                                         gpointer invocation_hint,
                                         gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1, guint arg_1, guint arg_2, gpointer data2);
	register GMarshalFunc_VOID__UINT_UINT 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__UINT_UINT) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_uint (param_values + 1), g_value_get_uint (param_values + 2), data2);
}

static GObject *
ft_bubble_chart_constructor (GType type,
                             guint n_construct_properties,
                             GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	FtBubbleChart * self;
	FtCategory* _tmp0_;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gfloat* _tmp3_;
	parent_class = G_OBJECT_CLASS (ft_bubble_chart_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_BUBBLE_CHART, FtBubbleChart);
	_tmp0_ = g_new0 (FtCategory, 0);
	self->priv->categories = (_vala_FtCategory_array_free (self->priv->categories, self->priv->categories_length1), NULL);
	self->priv->categories = _tmp0_;
	self->priv->categories_length1 = 0;
	self->priv->_categories_size_ = self->priv->categories_length1;
	_tmp1_ = g_new0 (gchar*, 0 + 1);
	self->priv->rows_labels = (_vala_array_free (self->priv->rows_labels, self->priv->rows_labels_length1, (GDestroyNotify) g_free), NULL);
	self->priv->rows_labels = _tmp1_;
	self->priv->rows_labels_length1 = 0;
	self->priv->_rows_labels_size_ = self->priv->rows_labels_length1;
	_tmp2_ = g_new0 (gchar*, 0 + 1);
	self->priv->columns_labels = (_vala_array_free (self->priv->columns_labels, self->priv->columns_labels_length1, (GDestroyNotify) g_free), NULL);
	self->priv->columns_labels = _tmp2_;
	self->priv->columns_labels_length1 = 0;
	self->priv->_columns_labels_size_ = self->priv->columns_labels_length1;
	_tmp3_ = g_new0 (gfloat, 0);
	self->priv->level_radii = (g_free (self->priv->level_radii), NULL);
	self->priv->level_radii = _tmp3_;
	self->priv->level_radii_length1 = 0;
	self->priv->_level_radii_size_ = self->priv->level_radii_length1;
	return obj;
}

static void
ft_bubble_chart_class_init (FtBubbleChartClass * klass,
                            gpointer klass_data)
{
	ft_bubble_chart_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtBubbleChart_private_offset);
	((GtkWidgetClass *) klass)->get_request_mode = (GtkSizeRequestMode (*) (GtkWidget*)) ft_bubble_chart_real_get_request_mode;
	((GtkWidgetClass *) klass)->measure = (void (*) (GtkWidget*, GtkOrientation, gint, gint*, gint*, gint*, gint*)) ft_bubble_chart_real_measure;
	((GtkWidgetClass *) klass)->size_allocate = (void (*) (GtkWidget*, gint, gint, gint)) ft_bubble_chart_real_size_allocate;
	((GtkWidgetClass *) klass)->snapshot = (void (*) (GtkWidget*, GtkSnapshot*)) ft_bubble_chart_real_snapshot;
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_bubble_chart_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_bubble_chart_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_bubble_chart_set_property;
	G_OBJECT_CLASS (klass)->constructor = ft_bubble_chart_constructor;
	G_OBJECT_CLASS (klass)->finalize = ft_bubble_chart_finalize;
	/**
	         * Value that should be visible on the chart.
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY, ft_bubble_chart_properties[FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY] = g_param_spec_double ("reference-value", "reference-value", "reference-value", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_BUBBLE_CHART_CATEGORY_PROPERTY, ft_bubble_chart_properties[FT_BUBBLE_CHART_CATEGORY_PROPERTY] = g_param_spec_uint ("category", "category", "category", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY, ft_bubble_chart_properties[FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY] = g_param_spec_boolean ("activate-on-click", "activate-on-click", "activate-on-click", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_BUBBLE_CHART_LEVELS_PROPERTY, ft_bubble_chart_properties[FT_BUBBLE_CHART_LEVELS_PROPERTY] = g_param_spec_uint ("levels", "levels", "levels", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/io/github/focustimerhq/FocusTimer/ui/main/stats/charts/bubble-chart.ui");
	ft_bubble_chart_signals[FT_BUBBLE_CHART_BUBBLE_ACTIVATED_SIGNAL] = g_signal_new ("bubble-activated", FT_TYPE_BUBBLE_CHART, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
	gtk_widget_class_bind_template_child_full (GTK_WIDGET_CLASS (klass), "layout_grid", FALSE, FtBubbleChart_private_offset + G_STRUCT_OFFSET (FtBubbleChartPrivate, layout_grid));
	gtk_widget_class_bind_template_child_full (GTK_WIDGET_CLASS (klass), "columns_box", FALSE, FtBubbleChart_private_offset + G_STRUCT_OFFSET (FtBubbleChartPrivate, columns_box));
	gtk_widget_class_bind_template_child_full (GTK_WIDGET_CLASS (klass), "rows_box", FALSE, FtBubbleChart_private_offset + G_STRUCT_OFFSET (FtBubbleChartPrivate, rows_box));
	gtk_widget_class_bind_template_child_full (GTK_WIDGET_CLASS (klass), "bubbles_grid", FALSE, FtBubbleChart_private_offset + G_STRUCT_OFFSET (FtBubbleChartPrivate, bubbles_grid));
	gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "chart");
}

static void
ft_bubble_chart_instance_init (FtBubbleChart * self,
                               gpointer klass)
{
	self->priv = ft_bubble_chart_get_instance_private (self);
	self->priv->_activate_on_click = FALSE;
	self->priv->_reference_value = 1.0;
	self->priv->_category = 0U;
	self->priv->_levels = 4U;
	self->priv->max_value = 0.0;
	self->priv->tooltip_row = -1;
	self->priv->tooltip_column = -1;
	self->priv->update_idle_id = (guint) 0;
	gtk_widget_init_template (GTK_WIDGET (self));
}

static void
ft_bubble_chart_finalize (GObject * obj)
{
	FtBubbleChart * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_BUBBLE_CHART, FtBubbleChart);
	self->priv->categories = (_vala_FtCategory_array_free (self->priv->categories, self->priv->categories_length1), NULL);
	self->priv->buckets = (_vala_FtBucket_array_free (self->priv->buckets, self->priv->buckets_length1 * self->priv->buckets_length2), NULL);
	_ft_matrix3_d_free0 (self->priv->data);
	self->priv->level_radii = (g_free (self->priv->level_radii), NULL);
	_g_object_unref0 (self->priv->tooltip_widget);
	self->priv->rows_labels = (_vala_array_free (self->priv->rows_labels, self->priv->rows_labels_length1, (GDestroyNotify) g_free), NULL);
	self->priv->columns_labels = (_vala_array_free (self->priv->columns_labels, self->priv->columns_labels_length1, (GDestroyNotify) g_free), NULL);
	G_OBJECT_CLASS (ft_bubble_chart_parent_class)->finalize (obj);
}

static GType
ft_bubble_chart_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtBubbleChartClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_bubble_chart_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtBubbleChart), 0, (GInstanceInitFunc) ft_bubble_chart_instance_init, NULL };
	GType ft_bubble_chart_type_id;
	ft_bubble_chart_type_id = g_type_register_static (gtk_widget_get_type (), "FtBubbleChart", &g_define_type_info, 0);
	FtBubbleChart_private_offset = g_type_add_instance_private (ft_bubble_chart_type_id, sizeof (FtBubbleChartPrivate));
	return ft_bubble_chart_type_id;
}

GType
ft_bubble_chart_get_type (void)
{
	static volatile gsize ft_bubble_chart_type_id__once = 0;
	if (g_once_init_enter (&ft_bubble_chart_type_id__once)) {
		GType ft_bubble_chart_type_id;
		ft_bubble_chart_type_id = ft_bubble_chart_get_type_once ();
		g_once_init_leave (&ft_bubble_chart_type_id__once, ft_bubble_chart_type_id);
	}
	return ft_bubble_chart_type_id__once;
}

static void
_vala_ft_bubble_chart_get_property (GObject * object,
                                    guint property_id,
                                    GValue * value,
                                    GParamSpec * pspec)
{
	FtBubbleChart * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_BUBBLE_CHART, FtBubbleChart);
	switch (property_id) {
		case FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY:
		g_value_set_double (value, ft_bubble_chart_get_reference_value (self));
		break;
		case FT_BUBBLE_CHART_CATEGORY_PROPERTY:
		g_value_set_uint (value, ft_bubble_chart_get_category (self));
		break;
		case FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY:
		g_value_set_boolean (value, ft_bubble_chart_get_activate_on_click (self));
		break;
		case FT_BUBBLE_CHART_LEVELS_PROPERTY:
		g_value_set_uint (value, ft_bubble_chart_get_levels (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_bubble_chart_set_property (GObject * object,
                                    guint property_id,
                                    const GValue * value,
                                    GParamSpec * pspec)
{
	FtBubbleChart * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_BUBBLE_CHART, FtBubbleChart);
	switch (property_id) {
		case FT_BUBBLE_CHART_REFERENCE_VALUE_PROPERTY:
		ft_bubble_chart_set_reference_value (self, g_value_get_double (value));
		break;
		case FT_BUBBLE_CHART_CATEGORY_PROPERTY:
		ft_bubble_chart_set_category (self, g_value_get_uint (value));
		break;
		case FT_BUBBLE_CHART_ACTIVATE_ON_CLICK_PROPERTY:
		ft_bubble_chart_set_activate_on_click (self, g_value_get_boolean (value));
		break;
		case FT_BUBBLE_CHART_LEVELS_PROPERTY:
		ft_bubble_chart_set_levels (self, g_value_get_uint (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);
}

