<commit_before>/*
 *
 * Copyright (C) 2009, Intel Corporation.
 *
 * Authors: <NAME> <<EMAIL>>
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "penge-block-container.h"

/* Child class */

typedef struct _PengeBlockContainerChild PengeBlockContainerChild;
typedef struct _ClutterChildMetaClass PengeBlockContainerChildClass;

struct _PengeBlockContainerChild
{
  ClutterChildMeta parent_instance;

  gint col_span;
};

enum
{
  PROP_CHILD_0,

  PROP_CHILD_COL_SPAN
};

#define PENGE_TYPE_BLOCK_CONTAINER_CHILD (penge_block_container_child_get_type())

G_DEFINE_TYPE (PengeBlockContainerChild,
               penge_block_container_child,
               CLUTTER_TYPE_CHILD_META);

static gint
penge_block_container_get_child_column_span (PengeBlockContainer *container,
                                             ClutterActor        *child)
{
  PengeBlockContainerChild *child_meta;

  child_meta = (PengeBlockContainerChild *)
    clutter_container_get_child_meta ((ClutterContainer *)container,
                                      child);

  return child_meta->col_span;
}

static void
penge_block_container_child_set_property (GObject      *object,
                                          guint         prop_id,
                                          const GValue *value,
                                          GParamSpec   *pspec)
{
  PengeBlockContainerChild *child = (PengeBlockContainerChild *)object;

  switch (prop_id)
  {
    case PROP_CHILD_COL_SPAN:
      child->col_span = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
penge_block_container_child_get_property (GObject    *object,
                                          guint       prop_id,
                                          GValue     *value,
                                          GParamSpec *pspec)
{
  PengeBlockContainerChild *child = (PengeBlockContainerChild *)object;

  switch (prop_id)
  {
    case PROP_CHILD_COL_SPAN:
      g_value_set_int (value, child->col_span);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
penge_block_container_child_class_init (PengeBlockContainerChildClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GParamSpec *pspec;

  object_class->set_property = penge_block_container_child_set_property;
  object_class->get_property = penge_block_container_child_get_property;

  pspec = g_param_spec_int ("col-span",
                            "Column span",
                            "Number of columns for this actor to span",
                            1,
                            G_MAXINT,
                            1,
                            G_PARAM_READWRITE);
  g_object_class_install_property (object_class,
                                   PROP_CHILD_COL_SPAN,
                                   pspec);
}

static void
penge_block_container_child_init (PengeBlockContainerChild *self)
{
  self->col_span = 1;
}

/* Main class */

static void penge_block_container_iface_init (ClutterContainerIface *iface);

G_DEFINE_TYPE_WITH_CODE (PengeBlockContainer, penge_block_container, CLUTTER_TYPE_ACTOR,
                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
                                                penge_block_container_iface_init))

#define GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), PENGE_TYPE_BLOCK_CONTAINER, PengeBlockContainerPrivate))

typedef struct _PengeBlockContainerPrivate PengeBlockContainerPrivate;

struct _PengeBlockContainerPrivate {
  gfloat prev_height;
  gfloat prev_width;

  gint column_count;
  gint row_count;

  gint padding;
  gfloat spacing;

  gfloat min_tile_height;
  gfloat min_tile_width;

  gfloat actual_tile_height;
  gfloat actual_tile_width;

  GList *children;
};

enum
{
  COUNT_CHANGED_SIGNAL,
  LAST_SIGNAL
};

guint signals[LAST_SIGNAL] = { 0, };

enum
{
  PROP_0,
  PROP_SPACING,
  PROP_MIN_TILE_HEIGHT,
  PROP_MIN_TILE_WIDTH
};

static void
penge_block_container_get_property (GObject    *object,
                                    guint       property_id,
                                    GValue     *value,
                                    GParamSpec *pspec)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (object);

  switch (property_id) {
    case PROP_SPACING:
      g_value_set_int (value, priv->spacing);
      break;
    case PROP_MIN_TILE_HEIGHT:
      g_value_set_int (value, priv->min_tile_height);
      break;
    case PROP_MIN_TILE_WIDTH:
      g_value_set_int (value, priv->min_tile_width);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}

static void
penge_block_container_set_property (GObject      *object,
                                    guint         property_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (object);

  switch (property_id) {
    case PROP_SPACING:
      priv->spacing = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    case PROP_MIN_TILE_HEIGHT:
      priv->min_tile_height = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    case PROP_MIN_TILE_WIDTH:
      priv->min_tile_width = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}

static void
penge_block_container_dispose (GObject *object)
{
  G_OBJECT_CLASS (penge_block_container_parent_class)->dispose (object);
}

static void
penge_block_container_finalize (GObject *object)
{
  G_OBJECT_CLASS (penge_block_container_parent_class)->finalize (object);
}

static void
penge_block_container_get_preferred_width (ClutterActor *actor,
                                           gfloat        for_height,
                                           gfloat       *min_width_p,
                                           gfloat       *nat_width_p)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);

  if (min_width_p)
    *min_width_p = priv->min_tile_width;

  if (nat_width_p)
    *nat_width_p = priv->min_tile_width;
}

static void
penge_block_container_get_preferred_height (ClutterActor *actor,
                                            gfloat        for_width,
                                            gfloat       *min_height_p,
                                            gfloat       *nat_height_p)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);

  if (min_height_p)
    *min_height_p = priv->min_tile_height;

  if (nat_height_p)
    *nat_height_p = priv->min_tile_height;

}

static gint
_calculate_potential_column_count (PengeBlockContainer *pbc,
                                   gfloat               width)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gfloat n;
  gint excess_width;

  n = (int)((width - 2 * priv->padding + priv->spacing) /
      ((int)priv->min_tile_width + (int)priv->spacing));

  excess_width = width -
    (n * priv->min_tile_width) -
    ((n - 1) * priv->spacing) -
    2 * priv->padding;
  priv->actual_tile_width = (int) (priv->min_tile_width + excess_width / n);

  return (gint)n;
}

static gint
_calculate_potential_row_count (PengeBlockContainer *pbc,
                                gfloat               height)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gfloat n;
  gfloat ratio;

  ratio = priv->actual_tile_width / priv->min_tile_width;

  priv->actual_tile_height = (int) (priv->min_tile_height * ratio);

  n = (int)((height - 2 * priv->padding + priv->spacing) /
      ((int)priv->actual_tile_height + (int)priv->spacing));

  return (gint)n;
}

static void
penge_block_container_generate_counts (PengeBlockContainer *pbc,
                                       gfloat               width,
                                       gfloat               height)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gint row_count, column_count;

  /* The width and height has changed. We need to recalculate our counts */

  /* Must do it in this order since row count depends on column count */
  column_count = _calculate_potential_column_count (pbc, width);
  row_count = _calculate_potential_row_count (pbc, height);

  if (priv->column_count != column_count || priv->row_count != row_count)
  {
    priv->column_count = column_count;
    priv->row_count = row_count;

    if (column_count * row_count > 0)
    {
      g_signal_emit (pbc,
                     signals[COUNT_CHANGED_SIGNAL],
                     0,
                     column_count * row_count);

      g_debug (G_STRLOC ": Possible row count = %d, possible column count = %d"
               " for width = %f and height = %f and child width = %f and height = %f",
               priv->row_count,
               priv->column_count,
               width,
               height,
               priv->actual_tile_width,
               priv->actual_tile_height);
    }
  }
}

static void
penge_block_container_allocate (ClutterActor           *actor,
                                const ClutterActorBox  *box,
                                ClutterAllocationFlags  flags)
{
  PengeBlockContainer *pbc = PENGE_BLOCK_CONTAINER (actor);
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);
  GList *l, *children;
  gfloat width, height;
  gint col_span;
  gint y_count, x_count;
  ClutterActor *child;
  ClutterActorBox child_box;
  gboolean fit_found = FALSE;

  width = box->x2 - box->x1;
  height = box->y2 - box->y1;

  CLUTTER_ACTOR_CLASS (penge_block_container_parent_class)->allocate (actor,
                                                                      box,
                                                                      flags);


  if (priv->prev_width != width || priv->prev_height != height)
  {
    penge_block_container_generate_counts (pbc,
                                           width,
                                           height);
  }

  children = g_list_copy (priv->children);

  if (!children)
    return;

  children = g_list_reverse (children);

  for (y_count = 0; y_count < priv->row_count; y_count++)
  {
    for (x_count = 0; x_count < priv->column_count; /* nop */)
    {
      /* Find first that can fit */
      fit_found = FALSE;

      for (l = children; l; l = l->next)
      {
        child = (ClutterActor *)l->data;
        col_span = penge_block_container_get_child_column_span (pbc,
                                                                child);

        /* Check if it fits */
        if (x_count + col_span <= priv->column_count)
        {
          child_box.x1 = x_count * priv->actual_tile_width +
                         x_count * priv->spacing +
                         priv->padding;
          child_box.x2 = child_box.x1 +
                         priv->actual_tile_width * col_span +
                         priv->spacing * (col_span - 1);
          child_box.y1 = y_count * priv->actual_tile_height +
                         y_count * priv->spacing +
                         priv->padding;
          child_box.y2 = child_box.y1 + priv->actual_tile_height;

          clutter_actor_allocate (child, &child_box, flags);
#if DEBUG
          g_debug (G_STRLOC ": y_count = %d, x_count = %d, " \
                   "box = (%f, %f) (%f, %f)",
                   y_count, x_count,
                   child_box.x1, child_box.y1,
                   child_box.x2, child_box.y2);
#endif
          children = g_list_remove (children, child);

          /* Increment with the col-span to take into consideration how many
           * "blocks" we are occupying
           */
          x_count += col_span;

          fit_found = TRUE;
        }
      }

      /* If we didn't find something that fits then we just leave a gap. This
       * is basically fine.
       */
      if (!fit_found)
      {
        /* We couldn't find something that fitted */
        break;<commit_msg>block-container: Break out of the inner loop when we've found a fit<commit_after>/*
 *
 * Copyright (C) 2009, Intel Corporation.
 *
 * Authors: <NAME> <<EMAIL>>
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "penge-block-container.h"

/* Child class */

typedef struct _PengeBlockContainerChild PengeBlockContainerChild;
typedef struct _ClutterChildMetaClass PengeBlockContainerChildClass;

struct _PengeBlockContainerChild
{
  ClutterChildMeta parent_instance;

  gint col_span;
};

enum
{
  PROP_CHILD_0,

  PROP_CHILD_COL_SPAN
};

#define PENGE_TYPE_BLOCK_CONTAINER_CHILD (penge_block_container_child_get_type())

G_DEFINE_TYPE (PengeBlockContainerChild,
               penge_block_container_child,
               CLUTTER_TYPE_CHILD_META);

static gint
penge_block_container_get_child_column_span (PengeBlockContainer *container,
                                             ClutterActor        *child)
{
  PengeBlockContainerChild *child_meta;

  child_meta = (PengeBlockContainerChild *)
    clutter_container_get_child_meta ((ClutterContainer *)container,
                                      child);

  return child_meta->col_span;
}

static void
penge_block_container_child_set_property (GObject      *object,
                                          guint         prop_id,
                                          const GValue *value,
                                          GParamSpec   *pspec)
{
  PengeBlockContainerChild *child = (PengeBlockContainerChild *)object;

  switch (prop_id)
  {
    case PROP_CHILD_COL_SPAN:
      child->col_span = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
penge_block_container_child_get_property (GObject    *object,
                                          guint       prop_id,
                                          GValue     *value,
                                          GParamSpec *pspec)
{
  PengeBlockContainerChild *child = (PengeBlockContainerChild *)object;

  switch (prop_id)
  {
    case PROP_CHILD_COL_SPAN:
      g_value_set_int (value, child->col_span);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
penge_block_container_child_class_init (PengeBlockContainerChildClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GParamSpec *pspec;

  object_class->set_property = penge_block_container_child_set_property;
  object_class->get_property = penge_block_container_child_get_property;

  pspec = g_param_spec_int ("col-span",
                            "Column span",
                            "Number of columns for this actor to span",
                            1,
                            G_MAXINT,
                            1,
                            G_PARAM_READWRITE);
  g_object_class_install_property (object_class,
                                   PROP_CHILD_COL_SPAN,
                                   pspec);
}

static void
penge_block_container_child_init (PengeBlockContainerChild *self)
{
  self->col_span = 1;
}

/* Main class */

static void penge_block_container_iface_init (ClutterContainerIface *iface);

G_DEFINE_TYPE_WITH_CODE (PengeBlockContainer, penge_block_container, CLUTTER_TYPE_ACTOR,
                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
                                                penge_block_container_iface_init))

#define GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), PENGE_TYPE_BLOCK_CONTAINER, PengeBlockContainerPrivate))

typedef struct _PengeBlockContainerPrivate PengeBlockContainerPrivate;

struct _PengeBlockContainerPrivate {
  gfloat prev_height;
  gfloat prev_width;

  gint column_count;
  gint row_count;

  gint padding;
  gfloat spacing;

  gfloat min_tile_height;
  gfloat min_tile_width;

  gfloat actual_tile_height;
  gfloat actual_tile_width;

  GList *children;
};

enum
{
  COUNT_CHANGED_SIGNAL,
  LAST_SIGNAL
};

guint signals[LAST_SIGNAL] = { 0, };

enum
{
  PROP_0,
  PROP_SPACING,
  PROP_MIN_TILE_HEIGHT,
  PROP_MIN_TILE_WIDTH
};

static void
penge_block_container_get_property (GObject    *object,
                                    guint       property_id,
                                    GValue     *value,
                                    GParamSpec *pspec)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (object);

  switch (property_id) {
    case PROP_SPACING:
      g_value_set_int (value, priv->spacing);
      break;
    case PROP_MIN_TILE_HEIGHT:
      g_value_set_int (value, priv->min_tile_height);
      break;
    case PROP_MIN_TILE_WIDTH:
      g_value_set_int (value, priv->min_tile_width);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}

static void
penge_block_container_set_property (GObject      *object,
                                    guint         property_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (object);

  switch (property_id) {
    case PROP_SPACING:
      priv->spacing = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    case PROP_MIN_TILE_HEIGHT:
      priv->min_tile_height = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    case PROP_MIN_TILE_WIDTH:
      priv->min_tile_width = g_value_get_float (value);
      clutter_actor_queue_relayout (CLUTTER_ACTOR (object));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}

static void
penge_block_container_dispose (GObject *object)
{
  G_OBJECT_CLASS (penge_block_container_parent_class)->dispose (object);
}

static void
penge_block_container_finalize (GObject *object)
{
  G_OBJECT_CLASS (penge_block_container_parent_class)->finalize (object);
}

static void
penge_block_container_get_preferred_width (ClutterActor *actor,
                                           gfloat        for_height,
                                           gfloat       *min_width_p,
                                           gfloat       *nat_width_p)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);

  if (min_width_p)
    *min_width_p = priv->min_tile_width;

  if (nat_width_p)
    *nat_width_p = priv->min_tile_width;
}

static void
penge_block_container_get_preferred_height (ClutterActor *actor,
                                            gfloat        for_width,
                                            gfloat       *min_height_p,
                                            gfloat       *nat_height_p)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);

  if (min_height_p)
    *min_height_p = priv->min_tile_height;

  if (nat_height_p)
    *nat_height_p = priv->min_tile_height;

}

static gint
_calculate_potential_column_count (PengeBlockContainer *pbc,
                                   gfloat               width)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gfloat n;
  gint excess_width;

  n = (int)((width - 2 * priv->padding + priv->spacing) /
      ((int)priv->min_tile_width + (int)priv->spacing));

  excess_width = width -
    (n * priv->min_tile_width) -
    ((n - 1) * priv->spacing) -
    2 * priv->padding;
  priv->actual_tile_width = (int) (priv->min_tile_width + excess_width / n);

  return (gint)n;
}

static gint
_calculate_potential_row_count (PengeBlockContainer *pbc,
                                gfloat               height)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gfloat n;
  gfloat ratio;

  ratio = priv->actual_tile_width / priv->min_tile_width;

  priv->actual_tile_height = (int) (priv->min_tile_height * ratio);

  n = (int)((height - 2 * priv->padding + priv->spacing) /
      ((int)priv->actual_tile_height + (int)priv->spacing));

  return (gint)n;
}

static void
penge_block_container_generate_counts (PengeBlockContainer *pbc,
                                       gfloat               width,
                                       gfloat               height)
{
  PengeBlockContainerPrivate *priv = GET_PRIVATE (pbc);
  gint row_count, column_count;

  /* The width and height has changed. We need to recalculate our counts */

  /* Must do it in this order since row count depends on column count */
  column_count = _calculate_potential_column_count (pbc, width);
  row_count = _calculate_potential_row_count (pbc, height);

  if (priv->column_count != column_count || priv->row_count != row_count)
  {
    priv->column_count = column_count;
    priv->row_count = row_count;

    if (column_count * row_count > 0)
    {
      g_signal_emit (pbc,
                     signals[COUNT_CHANGED_SIGNAL],
                     0,
                     column_count * row_count);

      g_debug (G_STRLOC ": Possible row count = %d, possible column count = %d"
               " for width = %f and height = %f and child width = %f and height = %f",
               priv->row_count,
               priv->column_count,
               width,
               height,
               priv->actual_tile_width,
               priv->actual_tile_height);
    }
  }
}

static void
penge_block_container_allocate (ClutterActor           *actor,
                                const ClutterActorBox  *box,
                                ClutterAllocationFlags  flags)
{
  PengeBlockContainer *pbc = PENGE_BLOCK_CONTAINER (actor);
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);
  GList *l, *children;
  gfloat width, height;
  gint col_span;
  gint y_count, x_count;
  ClutterActor *child;
  ClutterActorBox child_box;
  gboolean fit_found = FALSE;

  width = box->x2 - box->x1;
  height = box->y2 - box->y1;

  CLUTTER_ACTOR_CLASS (penge_block_container_parent_class)->allocate (actor,
                                                                      box,
                                                                      flags);


  if (priv->prev_width != width || priv->prev_height != height)
  {
    penge_block_container_generate_counts (pbc,
                                           width,
                                           height);
  }

  children = g_list_copy (priv->children);

  if (!children)
    return;

  children = g_list_reverse (children);

  for (y_count = 0; y_count < priv->row_count; y_count++)
  {
    for (x_count = 0; x_count < priv->column_count; /* nop */)
    {
      /* Find first that can fit */
      fit_found = FALSE;

      for (l = children; l; l = l->next)
      {
        child = (ClutterActor *)l->data;
        col_span = penge_block_container_get_child_column_span (pbc,
                                                                child);

        /* Check if it fits */
        if (x_count + col_span <= priv->column_count)
        {
          child_box.x1 = x_count * priv->actual_tile_width +
                         x_count * priv->spacing +
                         priv->padding;
          child_box.x2 = child_box.x1 +
                         priv->actual_tile_width * col_span +
                         priv->spacing * (col_span - 1);
          child_box.y1 = y_count * priv->actual_tile_height +
                         y_count * priv->spacing +
                         priv->padding;
          child_box.y2 = child_box.y1 + priv->actual_tile_height;

          clutter_actor_allocate (child, &child_box, flags);
#if DEBUG
          g_debug (G_STRLOC ": y_count = %d, x_count = %d, " \
                   "box = (%f, %f) (%f, %f)",
                   y_count, x_count,
                   child_box.x1, child_box.y1,
                   child_box.x2, child_box.y2);
#endif
          children = g_list_remove (children, child);

          /* Increment with the col-span to take into consideration how many
           * "blocks" we are occupying
           */
          x_count += col_span;

          fit_found = TRUE;
          break;
        }
      }

      /* If we didn't find something that fits then we just leave a gap. This
       * is basically fine.
       */
      if (!fit_found)
      {
        /* We couldn't find something that fitted */
        break;
{'fraction_non_alphanumeric': 0.07844964853004, 'fraction_numerical': 0.0035729542894869706, 'mean_word_length': 2.0315516835413234, 'pattern_counts': {'":': 4, '<': 15, '<?xml version=': 0, '>': 141, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 104, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5874339', 'n_tokens_mistral': 7801, 'n_tokens_neox': 7532, 'n_words': 1687}