Index: src/event-log.cpp
===================================================================
--- src/event-log.cpp	(revision 14585)
+++ src/event-log.cpp	(working copy)
@@ -256,20 +256,26 @@
 
         if(_getUndoEvent()) { 
             Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->sensitive(_document, true);
-
+            if(_repeatable()){
+                Inkscape::Verb::get(SP_VERB_EDIT_REPEAT)->sensitive(_document, true);
+            }
+            else{
+                Inkscape::Verb::get(SP_VERB_EDIT_REPEAT)->sensitive(_document, false);
+            } 
             Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->name(_document, String::ucompose("%1: %2", 
-                      Glib::ustring(_("_Undo")),
-                      Glib::ustring((*_getUndoEvent())[_columns.description])));
+                        Glib::ustring(_("_Undo")),
+                        Glib::ustring((*_getUndoEvent())[_columns.description])));
         } else {
             Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->name(_document, _("_Undo"));
             Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->sensitive(_document, false);
+            Inkscape::Verb::get(SP_VERB_EDIT_REPEAT)->sensitive(_document, false);
         }
 
         if(_getRedoEvent()) {
             Inkscape::Verb::get(SP_VERB_EDIT_REDO)->sensitive(_document, true);
             Inkscape::Verb::get(SP_VERB_EDIT_REDO)->name(_document, String::ucompose("%1: %2", 
-                      Glib::ustring(_("_Redo")),
-                      Glib::ustring((*_getRedoEvent())[_columns.description])));
+                        Glib::ustring(_("_Redo")),
+                        Glib::ustring((*_getRedoEvent())[_columns.description])));
 
         } else {
             Inkscape::Verb::get(SP_VERB_EDIT_REDO)->name(_document, _("_Redo"));
@@ -280,6 +286,11 @@
 
 }
 
+bool
+EventLog::_repeatable() const
+{
+    return ((Inkscape::Event *)_document->priv->undo->data)->repeatable();
+}
 
 EventLog::const_iterator
 EventLog::_getUndoEvent() const
Index: src/verbs.cpp
===================================================================
--- src/verbs.cpp	(revision 14585)
+++ src/verbs.cpp	(working copy)
@@ -854,6 +854,9 @@
         case SP_VERB_EDIT_UNDO:
             sp_undo(dt, sp_desktop_document(dt));
             break;
+        case SP_VERB_EDIT_REPEAT:
+            sp_repeat(dt, sp_desktop_document(dt));
+            break;
         case SP_VERB_EDIT_REDO:
             sp_redo(dt, sp_desktop_document(dt));
             break;
@@ -2087,6 +2090,8 @@
                  GTK_STOCK_UNDO),
     new EditVerb(SP_VERB_EDIT_REDO, "EditRedo", N_("_Redo"),
                  N_("Do again the last undone action"), GTK_STOCK_REDO),
+    new EditVerb(SP_VERB_EDIT_REPEAT, "EditRepeat", N_("Rep_eat"), N_("Repeat last action"),
+                 "repeat_last_action"),
     new EditVerb(SP_VERB_EDIT_CUT, "EditCut", N_("Cu_t"),
                  N_("Cut selection to clipboard"), GTK_STOCK_CUT),
     new EditVerb(SP_VERB_EDIT_COPY, "EditCopy", N_("_Copy"),
Index: src/selection-chemistry.cpp
===================================================================
--- src/selection-chemistry.cpp	(revision 14585)
+++ src/selection-chemistry.cpp	(working copy)
@@ -221,8 +221,9 @@
 
     if (tools_isactive (desktop, TOOLS_TEXT))
         if (sp_text_delete_selection(desktop->event_context)) {
-            sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
-                             _("Delete text"));
+            Inkscape::Event *event = new Inkscape::EventDelete(TRUE);
+            sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
+                             _("Delete text"), event);
             return;
         }
 
@@ -247,8 +248,9 @@
      */
     tools_switch ( desktop, tools_active ( desktop ) );
 
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_DELETE, 
-                     _("Delete"));
+    Inkscape::Event *event = new Inkscape::EventDelete(FALSE);
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_EDIT_DELETE, 
+                     _("Delete"), event);
 }
 
 /* fixme: sequencing */
@@ -287,9 +289,11 @@
         Inkscape::GC::release(copy);
     }
 
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_DUPLICATE, 
-                     _("Duplicate"));
+    Inkscape::Event *event = new Inkscape::An_Event(NULL, SP_VERB_EDIT_DUPLICATE, _("Duplicate"));
 
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_EDIT_DUPLICATE, 
+                     _("Duplicate"), event);
+
     selection->setReprList(newsel);
 
     g_slist_free(newsel);
@@ -312,8 +316,9 @@
         items = g_slist_remove(items, items->data);
     }
 
-    sp_document_done(doc, SP_VERB_EDIT_CLEAR_ALL,
-                     _("Delete all"));
+    Inkscape::Event *event = new Inkscape::EventClearAll();
+    sp_document_done_0(doc, SP_VERB_EDIT_CLEAR_ALL,
+                     _("Delete all"), event);
 }
 
 GSList *
@@ -509,8 +514,9 @@
     // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent
     group->setPosition(topmost + 1);
 
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_GROUP, 
-                     _("Group"));
+    Inkscape::Event *event = new Inkscape::An_Event(NULL, SP_VERB_SELECTION_GROUP, _("Group"));
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_SELECTION_GROUP, 
+                     _("Group"), event);
 
     selection->set(group);
     Inkscape::GC::release(group);
@@ -838,6 +844,16 @@
 }
 
 void
+sp_repeat(SPDesktop *desktop, SPDocument *)
+{
+    if (desktop == NULL) {
+        return;
+    }
+    if (!sp_document_repeat(sp_desktop_document(desktop)))
+        desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to repeat."));
+
+}
+void
 sp_redo(SPDesktop *desktop, SPDocument *)
 {
         if (!sp_document_redo(sp_desktop_document(desktop)))
@@ -1154,8 +1170,9 @@
         sp_selection_move_relative(selection, m);
     }
 
-    sp_document_done(document, SP_VERB_EDIT_PASTE, 
-                     _("Paste"));
+    Inkscape::Event *event = new Inkscape::EventPaste(in_place);
+    sp_document_done_0(document, SP_VERB_EDIT_PASTE, 
+                     _("Paste"), event);
 }
 
 void sp_selection_paste_style()
@@ -1181,10 +1198,31 @@
 
     sp_desktop_set_style (desktop, style_clipboard);
 
-    sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_STYLE,
-                     _("Paste style"));
+    Inkscape::Event *event = new Inkscape::EventPasteStyle();
+    sp_document_done_0(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_STYLE,
+                     _("Paste style"),event);
 }
 
+/* Function used from repeating a filling from swatch */
+void sp_selection_set_color(bool secondary, guint32 rgba)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (desktop) {
+        char const * attrName = secondary ? "stroke" : "fill";
+        gchar c[64];
+        sp_svg_write_color(c, 64, rgba);
+
+        SPCSSAttr *css = sp_repr_css_attr_new();
+        sp_repr_css_set_property( css, attrName, c );
+        sp_desktop_set_style(desktop, css);
+
+        sp_repr_css_attr_unref(css);
+        Inkscape::Event *event = new Inkscape::EventFillFromSwatch(secondary, rgba);
+        sp_document_done_0 (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
+                          secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"), event);
+    }
+}
+
 void sp_selection_paste_size (bool apply_x, bool apply_y)
 {
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
@@ -1217,8 +1255,9 @@
                                      apply_x? scale_x : (desktop->isToolboxButtonActive ("lock")? scale_y : 1.0),
                                      apply_y? scale_y : (desktop->isToolboxButtonActive ("lock")? scale_x : 1.0)));
 
-    sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE,
-                     _("Paste size"));
+    Inkscape::Event *event = new Inkscape::EventPasteSize(apply_x, apply_y);
+    sp_document_done_0(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE,
+                     _("Paste size"), event);
 }
 
 void sp_selection_paste_size_separately (bool apply_x, bool apply_y)
@@ -1258,8 +1297,9 @@
 
     }
 
-    sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY,
-                     _("Paste size separately"));
+    Inkscape::Event *event = new Inkscape::EventPasteSizeSeparately(apply_x, apply_y);
+    sp_document_done_0(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY,
+                     _("Paste size separately"), event);
 }
 
 void sp_selection_to_next_layer ()
@@ -1294,8 +1334,9 @@
         g_slist_free (copied);
         if (temp_clip) g_slist_free (temp_clip);
         if (next) dt->setCurrentLayer(next);
-        sp_document_done(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_NEXT, 
-                         _("Raise to next layer"));
+        Inkscape::Event *event = new Inkscape::EventToNextLayer();
+        sp_document_done_0(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_NEXT, 
+                         _("Raise to next layer"), event);
     } else {
         no_more = true;
     }
@@ -1339,8 +1380,9 @@
         g_slist_free (copied);
         if (temp_clip) g_slist_free (temp_clip);
         if (next) dt->setCurrentLayer(next);
-        sp_document_done(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_PREV,
-                         _("Lower to previous layer"));
+        Inkscape::Event *event = new Inkscape::EventToPrevLayer();
+        sp_document_done_0(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_PREV,
+                         _("Lower to previous layer"), event);
     } else {
         no_more = true;
     }
@@ -1463,7 +1505,6 @@
             // transform and its move compensation are both cancelled out.
 
             // restore item->transform field from the repr, in case it was changed by seltrans
-            sp_object_read_attr (SP_OBJECT (item), "transform");
 
             // calculate the matrix we need to apply to the clone to cancel its induced transform from its original
             NR::Matrix parent_transform = sp_item_i2root_affine(SP_ITEM(SP_OBJECT_PARENT (item)));
@@ -1479,14 +1520,13 @@
                 NR::Matrix clone_move = parent.inverse() * t * parent;
 
                 if (prefs_parallel) {
-                    NR::Matrix move = result * clone_move * t_inv;
+                    NR::Matrix move = item->transform * clone_move.inverse();
                     sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move);
 
                 } else if (prefs_unmoved) {
                     //if (SP_IS_USE(sp_use_get_original(SP_USE(item))))
                     //    clone_move = NR::identity();
-                    NR::Matrix move = result * clone_move;
-                    sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t);
+                    sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, &t);
                 }
 
             } else {
@@ -1510,6 +1550,33 @@
     }
 }
 
+void sp_selection_affine(NR::Matrix const &affine)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    Inkscape::Selection *selection = sp_desktop_selection(desktop);
+    NR::Point const center(*(selection->center()));
+    
+
+    if (selection->isEmpty())
+        return;
+    sp_selection_apply_affine(selection,NR::translate(-center) * affine * NR::translate(center));
+    Inkscape::Event *event = new Inkscape::EventAffine(affine);
+    if (affine.is_translation()) {
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT,
+                _("Move"), event);
+    } else if (affine.is_scale()) {
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT,
+                _("Scale"), event);
+    } else if (affine.is_rotation()) {
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT,
+                _("Rotate"), event);
+    } else {
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT,
+                _("Skew"), event);
+    }
+}
+
+
 void sp_selection_remove_transform()
 {
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
@@ -1523,9 +1590,10 @@
         sp_repr_set_attr((Inkscape::XML::Node*)l->data, "transform", NULL);
         l = l->next;
     }
-
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_FLATTEN, 
-                     _("Remove transform"));
+    
+    Inkscape::Event *event = new Inkscape::EventRemoveTransform();
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_OBJECT_FLATTEN, 
+                     _("Remove transform"), event);
 }
 
 void
@@ -1632,9 +1700,9 @@
         SPItem *item = SP_ITEM(l2->data);
         sp_item_rotate_rel(item, rot_neg_90);
     }
-
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CCW, 
-                     _("Rotate 90&#176; CW"));
+    Inkscape::Event *event = new Inkscape::EventRotate90Cw();
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CW, 
+                     _("Rotate 90&#176; CW"),event);
 }
 
 
@@ -1661,16 +1729,26 @@
         sp_item_rotate_rel(item, rot_neg_90);
     }
 
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CW,
-                     _("Rotate 90&#176; CCW"));
+    Inkscape::Event *event = new Inkscape::EventRotate90Ccw();
+    sp_document_done_0(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CCW, 
+                     _("Rotate 90&#176; CCW"),event);
 }
 
+
 void
+sp_selection_rotate( gdouble const angle_degrees)
+{
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP; 
+        Inkscape::Selection *selection = sp_desktop_selection(desktop);
+        sp_selection_rotate(selection, angle_degrees);
+}
+
+void
 sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees)
 {
     if (selection->isEmpty())
         return;
-
+    
     NR::Maybe<NR::Point> center = selection->center();
     if (!center) {
         return;
@@ -1678,18 +1756,24 @@
 
     sp_selection_rotate_relative(selection, *center, angle_degrees);
 
-    sp_document_maybe_done(sp_desktop_document(selection->desktop()),
-                           ( ( angle_degrees > 0 )
+    Inkscape::Event *event = new Inkscape::EventRotate(angle_degrees);
+    sp_document_maybe_done_0(sp_desktop_document(selection->desktop()),
+                             ( ( angle_degrees > 0 )
                              ? "selector:rotate:ccw"
-                             : "selector:rotate:cw" ), 
-                           SP_VERB_CONTEXT_SELECT, 
-                           _("Rotate"));
+                             : "selector:rotate:cw" ), SP_VERB_CONTEXT_SELECT, _("Rotate"),event);
 }
 
 /**
 \param  angle   the angle in "angular pixels", i.e. how many visible pixels must move the outermost point of the rotated object
 */
 void
+sp_selection_rotate_screen( gdouble const angle)
+{
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP; 
+        Inkscape::Selection *selection = sp_desktop_selection(desktop);
+        sp_selection_rotate_screen(selection, angle);
+}
+void
 sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle)
 {
     if (selection->isEmpty())
@@ -1709,16 +1793,25 @@
     gdouble const zangle = 180 * atan2(zmove, r) / M_PI;
 
     sp_selection_rotate_relative(selection, *center, zangle);
+    Inkscape::Event *event = new Inkscape::EventRotateScreen(angle);
 
-    sp_document_maybe_done(sp_desktop_document(selection->desktop()),
+    sp_document_maybe_done_0(sp_desktop_document(selection->desktop()),
                            ( (angle > 0)
                              ? "selector:rotate:ccw"
                              : "selector:rotate:cw" ),
                            SP_VERB_CONTEXT_SELECT, 
-                           _("Rotate by pixels"));
+                           _("Rotate by pixels"), event);
 }
 
 void
+sp_selection_scale(gdouble grow)
+{
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP; 
+        Inkscape::Selection *selection = sp_desktop_selection(desktop);
+        sp_selection_scale(selection, grow);
+}
+
+void
 sp_selection_scale(Inkscape::Selection *selection, gdouble grow)
 {
     if (selection->isEmpty())
@@ -1739,13 +1832,14 @@
 
     double const times = 1.0 + grow / max_len;
     sp_selection_scale_relative(selection, center, NR::scale(times, times));
+    Inkscape::Event *event = new Inkscape::EventScale(grow);
 
-    sp_document_maybe_done(sp_desktop_document(selection->desktop()),
+    sp_document_maybe_done_0(sp_desktop_document(selection->desktop()),
                            ( (grow > 0)
                              ? "selector:scale:larger"
                              : "selector:scale:smaller" ),
                            SP_VERB_CONTEXT_SELECT,
-                           _("Scale"));
+                           _("Scale"), event);
 }
 
 void
@@ -1756,6 +1850,14 @@
 }
 
 void
+sp_selection_scale_times( gdouble times)
+{
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP; 
+        Inkscape::Selection *selection = sp_desktop_selection(desktop);
+        sp_selection_scale_times(selection, times);
+}
+
+void
 sp_selection_scale_times(Inkscape::Selection *selection, gdouble times)
 {
     if (selection->isEmpty())
@@ -1769,8 +1871,9 @@
 
     NR::Point const center(sel_bbox->midpoint());
     sp_selection_scale_relative(selection, center, NR::scale(times, times));
-    sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, 
-                     _("Scale by whole factor"));
+    Inkscape::Event *event = new Inkscape::EventScaleTimes(times);
+    sp_document_done_0(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, 
+                     _("Scale by whole factor"), event);
 }
 
 void
@@ -1783,16 +1886,17 @@
     }
 
     sp_selection_move_relative(selection, dx, dy);
+    Inkscape::Event *event = new Inkscape::EventMove(dx,dy);
 
     if (dx == 0) {
-        sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, 
-                               _("Move vertically"));
+        sp_document_maybe_done_0(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, 
+                               _("Move vertically"),event);
     } else if (dy == 0) {
-        sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, 
-                               _("Move horizontally"));
+        sp_document_maybe_done_0(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, 
+                               _("Move horizontally"),event);
     } else {
-        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, 
-                         _("Move"));
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, 
+                         _("Move"),event);
     }
 }
 
@@ -1811,16 +1915,17 @@
     gdouble const zdx = dx / zoom;
     gdouble const zdy = dy / zoom;
     sp_selection_move_relative(selection, zdx, zdy);
+    Inkscape::Event *event = new Inkscape::EventMove(zdx,zdy);
 
     if (dx == 0) {
-        sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, 
-                               _("Move vertically by pixels"));
+        sp_document_maybe_done_0(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, 
+                               _("Move vertically by pixels"), event);
     } else if (dy == 0) {
-        sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, 
-                               _("Move horizontally by pixels"));
+        sp_document_maybe_done_0(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, 
+                               _("Move horizontally by pixels"), event);
     } else {
-        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, 
-                         _("Move"));
+        sp_document_done_0(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, 
+                         _("Move"), event);
     }
 }
 
@@ -2878,7 +2983,8 @@
     } else {
         fit_canvas_to_selection(desktop);
     }
-
+    
+//    Inkscape::Event *event = new Inkscape::EventFitCanvasToSelectionOrDrawing();
     sp_document_done(doc, SP_VERB_FIT_CANVAS_TO_DRAWING, 
                      _("Fit page to selection"));
 };
Index: src/selection-chemistry.h
===================================================================
--- src/selection-chemistry.h	(revision 14585)
+++ src/selection-chemistry.h	(working copy)
@@ -17,6 +17,7 @@
 
 #include "forward.h"
 #include "libnr/nr-forward.h"
+#include "svg/svg-color.h"
 
 namespace Inkscape { class Selection; }
 
@@ -53,12 +54,15 @@
 void sp_selection_paste(bool in_place);
 void sp_selection_paste_style();
 
+void sp_selection_set_color(bool secondary, guint32 rgba);
+
 void sp_selection_paste_size(bool apply_x, bool apply_y);
 void sp_selection_paste_size_separately(bool apply_x, bool apply_y);
 
 void sp_selection_to_next_layer ();
 void sp_selection_to_prev_layer ();
 
+void sp_selection_affine(NR::Matrix const &affine);
 void sp_selection_apply_affine(Inkscape::Selection *selection, NR::Matrix const &affine, bool set_i2d = true);
 void sp_selection_remove_transform (void);
 void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1);
@@ -70,11 +74,15 @@
 
 void sp_selection_rotate_90_cw (void);
 void sp_selection_rotate_90_ccw (void);
+void sp_selection_rotate (gdouble angle);
 void sp_selection_rotate (Inkscape::Selection *selection, gdouble angle);
+void sp_selection_rotate_screen (gdouble angle);
 void sp_selection_rotate_screen (Inkscape::Selection *selection, gdouble angle);
 
+void sp_selection_scale (gdouble grow);
 void sp_selection_scale (Inkscape::Selection *selection, gdouble grow);
 void sp_selection_scale_screen (Inkscape::Selection *selection, gdouble grow_pixels);
+void sp_selection_scale_times (gdouble times);
 void sp_selection_scale_times (Inkscape::Selection *selection, gdouble times);
 
 void sp_selection_move (gdouble dx, gdouble dy);
@@ -86,6 +94,7 @@
 void scroll_to_show_item(SPDesktop *desktop, SPItem *item);
 
 void sp_undo (SPDesktop *desktop, SPDocument *doc);
+void sp_repeat (SPDesktop *desktop, SPDocument *doc);
 void sp_redo (SPDesktop *desktop, SPDocument *doc);
 
 void sp_selection_get_export_hints (Inkscape::Selection *selection, const char **filename, float *xdpi, float *ydpi);
Index: src/document-undo.cpp
===================================================================
--- src/document-undo.cpp	(revision 14585)
+++ src/document-undo.cpp	(working copy)
@@ -117,6 +117,12 @@
 }
 
 void
+sp_document_done_0 (SPDocument *doc, const unsigned int event_type, Glib::ustring event_description, Inkscape::Event *event)
+{
+        sp_document_maybe_done_0 (doc, NULL, event_type, event_description, event);
+}
+
+void
 sp_document_done (SPDocument *doc, const unsigned int event_type, Glib::ustring event_description)
 {
         sp_document_maybe_done (doc, NULL, event_type, event_description);
@@ -128,11 +134,18 @@
 	SPDocument *doc = (SPDocument *) base;
 	doc->actionkey = NULL;
 }
-
 void
 sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int event_type,
                         Glib::ustring event_description)
 {
+    Inkscape::Event *event = new Inkscape::An_Event(NULL, event_type, event_description);
+    sp_document_maybe_done_0 (doc, NULL, event_type, event_description, event );
+}
+
+void
+sp_document_maybe_done_0 (SPDocument *doc, const gchar *key, const unsigned int event_type,
+                        Glib::ustring event_description, Inkscape::Event *event)
+{
 	g_assert (doc != NULL);
 	g_assert (doc->priv != NULL);
 	g_assert (doc->priv->sensitive);
@@ -145,18 +158,19 @@
 
 	Inkscape::XML::Event *log = sp_repr_coalesce_log (doc->priv->partial, sp_repr_commit_undoable (doc->rdoc));
 	doc->priv->partial = NULL;
-
+        if (event) //XXX doit etre toujours vrai
+            event->event=log;
 	if (!log) {
 		sp_repr_begin_transaction (doc->rdoc);
 		return;
 	}
 
 	if (key && doc->actionkey && !strcmp (key, doc->actionkey) && doc->priv->undo) {
-                doc->priv->undo->data = 
-                    new Inkscape::Event(sp_repr_coalesce_log (((Inkscape::Event *)
-                                                               doc->priv->undo->data)->event, log));
+                doc->priv->undo->data = event;
+                    //new Inkscape::Event(sp_repr_coalesce_log (((Inkscape::Event *)
+                    //                                           doc->priv->undo->data)->event, log));
 	} else {
-                Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description);
+                //Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description);
                 doc->priv->undo = g_slist_prepend (doc->priv->undo, event);
 		doc->priv->history_size++;
 		doc->priv->undoStackObservers.notifyUndoCommitEvent(event);
@@ -208,6 +222,7 @@
 
 }
 
+
 gboolean
 sp_document_undo (SPDocument *doc)
 {
@@ -255,6 +270,42 @@
 }
 
 gboolean
+sp_document_repeat (SPDocument *doc)
+{
+	using Inkscape::Debug::EventTracker;
+	using Inkscape::Debug::SimpleEvent;
+
+	gboolean ret;
+
+	EventTracker<SimpleEvent<Inkscape::Debug::Event::DOCUMENT> > tracker("repeat");
+
+	g_assert (doc != NULL);
+	g_assert (doc->priv != NULL);
+        g_assert (doc->priv->sensitive);
+
+
+	doc->actionkey = NULL;
+
+//	finish_incomplete_transaction(*doc);
+
+	if (doc->priv->undo) {
+		Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data;
+		log->repeat();
+                doc->rroot->setAttribute("sodipodi:modified", "true");
+		ret = TRUE;
+	} else {
+		ret = FALSE;
+	}
+
+//	sp_repr_begin_transaction (doc->rdoc);
+
+
+	if (ret)
+		inkscape_external_change();
+
+	return ret;
+}
+gboolean
 sp_document_redo (SPDocument *doc)
 {
 	using Inkscape::Debug::EventTracker;
Index: src/document.h
===================================================================
--- src/document.h	(revision 14585)
+++ src/document.h	(working copy)
@@ -28,6 +28,7 @@
 #include "gc-anchored.h"
 #include <glibmm/ustring.h>
 #include "verbs.h"
+#include "event.h"
 
 namespace Avoid {
 class Router;
@@ -193,7 +194,9 @@
 gint sp_document_ensure_up_to_date (SPDocument *doc);
 
 /* Save all previous actions to stack, as one undo step */
+void sp_document_done_0 (SPDocument *document, unsigned int event_type, Glib::ustring event_description, Inkscape::Event *event);
 void sp_document_done (SPDocument *document, unsigned int event_type, Glib::ustring event_description);
+void sp_document_maybe_done_0 (SPDocument *document, const gchar *keyconst, unsigned int event_type, Glib::ustring event_description, Inkscape::Event *event);
 void sp_document_maybe_done (SPDocument *document, const gchar *keyconst, unsigned int event_type, Glib::ustring event_description);
 void sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base);
 
@@ -203,6 +206,7 @@
 /* Undo and redo */
 gboolean sp_document_undo (SPDocument * document);
 gboolean sp_document_redo (SPDocument * document);
+gboolean sp_document_repeat (SPDocument * document);
 
 /* Resource management */
 gboolean sp_document_add_resource (SPDocument *document, const gchar *key, SPObject *object);
Index: src/verbs.h
===================================================================
--- src/verbs.h	(revision 14585)
+++ src/verbs.h	(working copy)
@@ -48,6 +48,7 @@
     /* Edit */
     SP_VERB_EDIT_UNDO,
     SP_VERB_EDIT_REDO,
+    SP_VERB_EDIT_REPEAT,
     SP_VERB_EDIT_CUT,
     SP_VERB_EDIT_COPY,
     SP_VERB_EDIT_PASTE,
Index: src/event-log.h
===================================================================
--- src/event-log.h	(revision 14585)
+++ src/event-log.h	(working copy)
@@ -32,6 +32,7 @@
 
 #include "undo-stack-observer.h"
 #include "event.h"
+#include "document-private.h"
 
 namespace Inkscape {
 
@@ -132,6 +133,7 @@
     // Map of connections used to temporary block/unblock callbacks in a TreeView
     CallbackMap *_callback_connections;
 
+    bool _repeatable() const;
     const_iterator _getUndoEvent() const; //< returns the current undoable event or NULL if none
     const_iterator _getRedoEvent() const; //< returns the current redoable event or NULL if none
 
Index: src/sp-use.cpp
===================================================================
--- src/sp-use.cpp	(revision 14585)
+++ src/sp-use.cpp	(working copy)
@@ -470,7 +470,6 @@
         return;
 
     // restore item->transform field from the repr, in case it was changed by seltrans
-    sp_object_read_attr (SP_OBJECT (self), "transform");
 
     NR::Matrix t = sp_use_get_parent_transform(self);
     NR::Matrix clone_move = t.inverse() * m * t;
Index: src/event.h
===================================================================
--- src/event.h	(revision 14585)
+++ src/event.h	(working copy)
@@ -18,6 +18,8 @@
 
 #include "xml/event-fns.h"
 #include "verbs.h"
+#include "selection-chemistry.h"
+#include "libnr/nr-matrix.h"
 
 namespace Inkscape {
 namespace XML {
@@ -27,20 +29,175 @@
 
 namespace Inkscape {
 
-struct Event {
-     
-    Event(XML::Event *_event, unsigned int _type=SP_VERB_NONE, Glib::ustring _description="")
-        : event (_event), type (_type), description (_description)  { }
+    class Event {
+        public:
+            virtual  ~Event(){sp_repr_free_log (event);}
+            void set_description(Glib::ustring _description) {description=_description;};
+            XML::Event *event;
+            unsigned int type;
+            Glib::ustring description;
+            bool is_repeatable;
+            virtual void repeat(){};
+            virtual bool repeatable(){return is_repeatable;};
+        protected:
+            Event(XML::Event *_event, unsigned int _type=SP_VERB_NONE, Glib::ustring
+                _description="", bool _repeatable=false)
+                    : event (_event), type (_type), description (_description),
+                    is_repeatable(_repeatable)  { }
 
-    ~Event() { sp_repr_free_log (event); }
+    };
+    class An_Event : public Event{
+        public:
+            An_Event(XML::Event *_event, unsigned int _type=SP_VERB_NONE, Glib::ustring _description="")
+                : Event(_event, _type, _description,false) { }
+            void repeat() {};
+    };
 
-    XML::Event *event;
-    const unsigned int type;
-    Glib::ustring description;
-};
+    class EventRotate90Cw : public Event {
+        public:
+            EventRotate90Cw()
+                : Event(NULL, SP_VERB_OBJECT_ROTATE_90_CW , "Rotate 90&#176; CW", true) { }
 
+            void repeat() { sp_selection_rotate_90_cw(); };
+    };
+    class EventRotate90Ccw : public Event {
+        public:
+            EventRotate90Ccw()
+                : Event(NULL, SP_VERB_OBJECT_ROTATE_90_CCW , "Rotate 90&#176; CCW", true) { }
+
+            void repeat() { sp_selection_rotate_90_ccw(); };
+    };
+    class EventRotate : public Event {
+        public:
+            EventRotate( gdouble _angle=0.)
+                : Event(NULL,  SP_VERB_CONTEXT_SELECT , "Rotate", true), angle(_angle) { }
+            gdouble angle;
+            void repeat() {sp_selection_rotate(angle); };
+    };
+    
+    class EventRotateScreen : public Event {
+        public:
+            EventRotateScreen( gdouble _angle=0.)
+                : Event(NULL,  SP_VERB_CONTEXT_SELECT , "Rotate by pixels", true), angle(_angle) { }
+            gdouble angle;
+            void repeat() {sp_selection_rotate_screen(angle); };
+    };
+
+    class EventMove : public Event {
+        public:
+            EventMove( gdouble _dx, gdouble _dy)
+                : Event(NULL,  SP_VERB_CONTEXT_SELECT , "Move", true), dx(_dx), dy(_dy) { }
+            gdouble dx,dy;
+            void repeat() {sp_selection_move(dx, dy); };
+    };
+
+    class EventScaleTimes : public Event {
+        public:
+            EventScaleTimes(gdouble _times)
+                : Event(NULL,  SP_VERB_CONTEXT_SELECT , "Scale by whole factor", true), times(_times) { }
+            gdouble times;
+            void repeat() {sp_selection_scale_times(times); };
+    };
+    class EventScale : public Event {
+        public:
+            EventScale(gdouble _grow)
+                : Event(NULL,  SP_VERB_CONTEXT_SELECT , "Scale", true), grow(_grow) { }
+            gdouble grow;
+            void repeat() {sp_selection_scale(grow); };
+    };
+    class EventRemoveTransform : public Event {
+        public:
+            EventRemoveTransform()
+                : Event(NULL,  SP_VERB_OBJECT_FLATTEN , "transform", true) { }
+            void repeat() {sp_selection_remove_transform(); };
+    };
+    class EventToPrevLayer : public Event {
+        public:
+            EventToPrevLayer()
+                : Event(NULL,  SP_VERB_LAYER_MOVE_TO_PREV , "Lower to previous layer", true) { }
+            void repeat() {sp_selection_to_prev_layer(); };
+    };
+    class EventToNextLayer : public Event {
+        public:
+            EventToNextLayer()
+                : Event(NULL,  SP_VERB_LAYER_MOVE_TO_NEXT , "Raise to next layer", true) { }
+            void repeat() {sp_selection_to_next_layer(); };
+    };
+    class EventPasteSizeSeparately : public Event {
+        public:
+            EventPasteSizeSeparately(bool _apply_x, bool _apply_y)
+                : Event(NULL,  SP_VERB_EDIT_PASTE_SIZE_SEPARATELY , "Paste size separately", true), apply_x(_apply_x), apply_y(_apply_y) { }
+            bool apply_x, apply_y;
+            void repeat() {sp_selection_paste_size_separately(apply_x, apply_y); };
+    };
+
+    class EventPasteSize : public Event {
+        public:
+            EventPasteSize(bool _apply_x, bool _apply_y)
+                : Event(NULL,  SP_VERB_EDIT_PASTE_SIZE, "Paste size", true), apply_x(_apply_x), apply_y(_apply_y) { }
+            bool apply_x, apply_y;
+            void repeat() {sp_selection_paste_size(apply_x, apply_y); };
+    };
+    class EventPasteStyle : public Event {
+        public:
+            EventPasteStyle()
+                : Event(NULL,  SP_VERB_EDIT_PASTE_STYLE, "Paste style", true) { }
+            void repeat() {sp_selection_paste_style(); };
+    };
+    class EventPaste : public Event {
+        public:
+            EventPaste(bool _in_place)
+                : Event(NULL,  SP_VERB_EDIT_PASTE, "Paste", true), in_place(_in_place) { }
+            bool in_place;
+            void repeat() {sp_selection_paste(in_place); };
+    };
+    class EventAffine : public Event {
+        public:
+            EventAffine(NR::Matrix const &_affine)
+                : Event(NULL,  SP_VERB_EDIT_PASTE, "Move", true), affine(_affine ) {
+                    if (affine.is_translation()) {
+                        set_description("Move");
+                    } else if (affine.is_scale()) {
+                        set_description("Scale");
+                    } else if (affine.is_rotation()) {
+                        set_description("Rotate");
+                    } else {
+                        set_description("Skew");
+                    }
+                }
+            NR::Matrix const affine;
+            void repeat() {sp_selection_affine(affine);};
+    };
+    class EventClearAll : public Event {
+        public:
+            EventClearAll()
+                : Event(NULL,  SP_VERB_EDIT_CLEAR_ALL, "Delete All", true){ }
+            void repeat() {sp_edit_clear_all(); };
+    };
+    class EventGroup : public Event {
+        public:
+            EventGroup()
+                : Event(NULL,  SP_VERB_SELECTION_GROUP, "Group", true){ }
+            void repeat() {sp_selection_group(); };
+    };
+    class EventDelete : public Event {
+        public:
+            EventDelete(bool is_text)
+                : Event(NULL,  is_text?SP_VERB_CONTEXT_TEXT : SP_VERB_EDIT_DELETE, is_text? "Delete text" : "Delete", true){ }
+            void repeat() {sp_selection_delete(); };
+    };
+    class EventFillFromSwatch : public Event {
+        public:
+            EventFillFromSwatch( bool _secondary, guint32 _rgba)
+                : Event(NULL,  SP_VERB_DIALOG_SWATCHES, secondary? "Set stroke color from swatch" : "Set fill color from swatch", true), secondary(_secondary), rgba( _rgba) { }
+           bool secondary;
+           guint32 rgba;
+            void repeat() {sp_selection_set_color(secondary, rgba); };
+    };
 } // namespace Inkscape
 
+
+
 #endif // INKSCAPE_EVENT_H
 
 /*
Index: src/interface.cpp
===================================================================
--- src/interface.cpp	(revision 14585)
+++ src/interface.cpp	(working copy)
@@ -905,6 +905,7 @@
     /* Undo and Redo */
     sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_UNDO), view);
     sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_REDO), view);
+    //sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_REPEAT), view);
 
     /* Separator */
     sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL);
Index: src/xml/event-fns.h
===================================================================
--- src/xml/event-fns.h	(revision 14585)
+++ src/xml/event-fns.h	(working copy)
@@ -1,6 +1,5 @@
 #ifndef SEEN_INKSCAPE_XML_SP_REPR_ACTION_FNS_H
 #define SEEN_INKSCAPE_XML_SP_REPR_ACTION_FNS_H
-
 namespace Inkscape {
 namespace XML {
 
Index: src/xml/event.cpp
===================================================================
--- src/xml/event.cpp	(revision 14585)
+++ src/xml/event.cpp	(working copy)
@@ -20,7 +20,6 @@
 #include "xml/node-observer.h"
 #include "debug/event-tracker.h"
 #include "debug/simple-event.h"
-
 using Inkscape::Util::List;
 using Inkscape::Util::reverse_list;
 
Index: src/dialogs/stroke-style.cpp
===================================================================
--- src/dialogs/stroke-style.cpp	(revision 14585)
+++ src/dialogs/stroke-style.cpp	(working copy)
@@ -1884,4 +1884,4 @@
   fill-column:99
   End:
 */
-// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
Index: src/dialogs/swatches.cpp
===================================================================
--- src/dialogs/swatches.cpp	(revision 14585)
+++ src/dialogs/swatches.cpp	(working copy)
@@ -552,8 +552,9 @@
         sp_desktop_set_style(desktop, css);
 
         sp_repr_css_attr_unref(css);
-        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
-                          secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"));
+        Inkscape::Event *event = new Inkscape::EventFillFromSwatch(secondary, rgba);
+        sp_document_done_0 (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
+                          secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"), event);
     }
 }
 
Index: src/seltrans.cpp
===================================================================
--- src/seltrans.cpp	(revision 14585)
+++ src/seltrans.cpp	(working copy)
@@ -401,18 +401,19 @@
         _items.clear();
         _items_centers.clear();
 
+        Inkscape::Event *event = new Inkscape::EventAffine(NR::translate(_origin) * _current * NR::translate(-_origin));
         if (_current.is_translation()) {
-            sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
-                             _("Move"));
+            sp_document_done_0(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
+                             _("Move"), event);
         } else if (_current.is_scale()) {
-            sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
-                             _("Scale"));
+            sp_document_done_0(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
+                             _("Scale"), event);
         } else if (_current.is_rotation()) {
-            sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
-                             _("Rotate"));
+            sp_document_done_0(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
+                             _("Rotate"), event);
         } else {
-            sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
-                             _("Skew"));
+            sp_document_done_0(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT,
+                             _("Skew"), event);
         }
 
     } else {
Index: src/ui/stock.cpp
===================================================================
--- src/ui/stock.cpp	(revision 14585)
+++ src/ui/stock.cpp	(working copy)
@@ -21,6 +21,7 @@
 Gtk::StockID const EXPORT("export");
 Gtk::StockID const VACUUM_DEFS("vacuum-defs");
 // Edit menu
+Gtk::StockID const REPEAT("repeat-last-action");
 Gtk::StockID const UNDO_HISTORY("undo-history");
 Gtk::StockID const PASTE_IN_PLACE("paste-in-place");
 Gtk::StockID const PASTE_STYLE("paste-style");
Index: src/ui/stock.h
===================================================================
--- src/ui/stock.h	(revision 14585)
+++ src/ui/stock.h	(working copy)
@@ -24,6 +24,7 @@
 extern Gtk::StockID const EXPORT;
 extern Gtk::StockID const VACUUM_DEFS;
 // Edit menu
+extern Gtk::StockID const REPEAT;
 extern Gtk::StockID const UNDO_HISTORY;
 extern Gtk::StockID const PASTE_IN_PLACE;
 extern Gtk::StockID const PASTE_STYLE;
Index: src/ui/view/edit-widget.cpp
===================================================================
--- src/ui/view/edit-widget.cpp	(revision 14585)
+++ src/ui/view/edit-widget.cpp	(working copy)
@@ -414,6 +414,10 @@
     _act_grp->add(Gtk::Action::create("Redo",
                                       Gtk::Stock::REDO, Glib::ustring(),
                                       _("PLACEHOLDER, do not translate")));
+    
+    _act_grp->add(Gtk::Action::create("Repeat",
+                                      Stock::REPEAT, Glib::ustring(),
+                                      _("PLACEHOLDER, do not translate")));
 
     _act_grp->add(Gtk::Action::create("UndoHistory",
                                       Stock::UNDO_HISTORY, Glib::ustring(),
Index: src/nodepath.cpp
===================================================================
--- src/nodepath.cpp	(revision 14585)
+++ src/nodepath.cpp	(working copy)
@@ -514,8 +514,9 @@
     }
 
     update_repr_internal(np);
-    sp_document_maybe_done(sp_desktop_document(np->desktop), key, SP_VERB_CONTEXT_NODE, 
-                           annotation);
+    Inkscape::Event *event = new Inkscape::An_Event(NULL, SP_VERB_CONTEXT_NODE, annotation);
+    sp_document_maybe_done_0(sp_desktop_document(np->desktop), key, SP_VERB_CONTEXT_NODE, 
+                           annotation, event);
 }
 
 /**
Index: src/menus-skeleton.h
===================================================================
--- src/menus-skeleton.h	(revision 14585)
+++ src/menus-skeleton.h	(working copy)
@@ -55,6 +55,7 @@
 "   <submenu name=\"" N_("_Edit") "\">\n"
 "       <verb verb-id=\"EditUndo\" />\n"
 "       <verb verb-id=\"EditRedo\" />\n"
+"       <verb verb-id=\"EditRepeat\" />\n"
 "       <verb verb-id=\"DialogUndoHistory\" />\n"
 "       <separator/>\n"
 "       <verb verb-id=\"EditCut\" />\n"
Index: share/keys/default.xml
===================================================================
--- share/keys/default.xml	(revision 14585)
+++ share/keys/default.xml	(working copy)
@@ -239,6 +239,9 @@
   <bind key="y" modifiers="Ctrl" action="EditRedo" />
   <bind key="Y" modifiers="Ctrl" action="EditRedo" />
 
+  <bind key="r" modifiers="Ctrl,Shift" action="EditRepeat" display="true" />
+  <bind key="R" modifiers="Ctrl,Shift" action="EditRepeat" />
+  
   <bind key="h" modifiers="Ctrl,Shift" action="DialogUndoHistory" display="true" />
   <bind key="H" modifiers="Ctrl,Shift" action="DialogUndoHistory" display="true" />
 
Index: share/keys/inkscape.xml
===================================================================
--- share/keys/inkscape.xml	(revision 14585)
+++ share/keys/inkscape.xml	(working copy)
@@ -239,6 +239,10 @@
   <bind key="y" modifiers="Ctrl" action="EditRedo" />
   <bind key="Y" modifiers="Ctrl" action="EditRedo" />
 
+
+  <bind key="r" modifiers="Ctrl,Shift" action="EditRepeat" display="true" />
+  <bind key="R" modifiers="Ctrl,Shift" action="EditRepeat" />
+  
   <bind key="h" modifiers="Ctrl,Shift" action="DialogUndoHistory" display="true" />
   <bind key="H" modifiers="Ctrl,Shift" action="DialogUndoHistory" display="true" />
 
Index: share/icons/icons.svg
===================================================================
--- share/icons/icons.svg	(revision 14585)
+++ share/icons/icons.svg	(working copy)
@@ -2491,4 +2491,13 @@
 <path sodipodi:type="arc" style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:#2e3436;stroke-width:1.138871;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path31981" sodipodi:cx="12.875" sodipodi:cy="14.875" sodipodi:rx="1.3125" sodipodi:ry="1.3125" d="M 14.1875,14.875 A 1.3125,1.3125 0 1 1 11.5625,14.875 A 1.3125,1.3125 0 1 1 14.1875,14.875 z" transform="matrix(1.12392,0,0,1.12392,0.83338,-2.58525)" />
 <path style="fill:url(#radialGradient4365);fill-opacity:1.0;stroke:#000000;stroke-width:1.000001;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:1;color:#000000;fill-rule:nonzero;stroke-linecap:butt;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-dashoffset:0;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="M 456.281,449.062 C 456.213,449.07 456.154,449.096 456.094,449.125 C 455.133,449.59 455.637,452.694 457.25,456.062 C 458.238,458.125 459.43,459.799 460.406,460.688 C 460.405,460.698 460.407,460.708 460.406,460.719 C 460.337,461.549 459.647,462.428 459.378,463.219 C 449.286,463.539 450.416,467.696 460.031,467.742 C 478.573,467.83 478.246,463.266 462.875,463.188 C 462.602,462.532 462.317,461.864 462.094,461.188 C 462.821,460.45 462.262,457.533 460.75,454.375 C 459.238,451.217 457.308,448.951 456.281,449.062 z" transform="matrix(1.28,0,0,1.28,-578.362,-566.08)" id="path22088" sodipodi:nodetypes="csscscsccsc" />
 </g>
+<g id="repeat_last_action" transform="matrix(9.461201e-3,0,0,9.461201e-3,576.48447,377.673)">
+<g id="g5361" transform="translate(-52424.643,-2959.4562)">
+<g transform="matrix(3.9711052,-3.9711052,3.9711052,3.9711052,-1572.7771,-5669.0537)" id="g7823" style="fill:#000000;filter:url(#filter7909)">
+<path style="fill:#000000;fill-opacity:1;stroke:#4d4d4d;stroke-width:3.38766026;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.64779873" d="M -646.8253,413.4763 L -646.8253,443.5826 C -733.0867,452.7128 -799.8878,501.8755 -799.8878,538.4763 C -799.8878,570.7345 -754.8514,597.2465 -684.0753,607.7888 L -670.2003,601.1013 C -741.6975,592.2499 -799.2003,567.3027 -799.2003,539.4451 C -799.2003,507.8692 -733.374,487.4192 -646.8253,482.1116 L -646.8253,506.6638 L -564.7316,469.3513 L -545.2316,460.7888 L -545.5753,460.6326 L -544.3566,460.0701 L -646.8253,413.4763 z " id="path7825" sodipodi:nodetypes="ccsccsccccccc" />
+<path style="fill:#000000;fill-opacity:1;stroke:#4d4d4d;stroke-width:3.38766026;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.6540881" d="M -550.2316,468.2888 L -566.9816,476.7888 C -491.2042,484.7784 -429.9191,510.5262 -429.9191,539.4451 C -429.9191,571.3616 -497.1777,589.6968 -585.1066,594.6056 L -585.1066,568.3826 L -687.6066,614.9451 L -585.1066,661.5388 L -585.1066,634.1908 C -497.0349,626.0753 -429.2628,575.6742 -429.2628,538.4763 C -429.2628,506.1492 -479.2179,478.7867 -550.2316,468.2888 z " id="path7827" sodipodi:nodetypes="ccscccccsc" />
+</g>
+<path style="fill:url(#linearGradient5368);fill-opacity:1;stroke:#4d4d4d;stroke-width:19.02506828;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.64779873" d="M -2552.6862,-1511.7402 L -2433.1309,-1392.1849 C -2739.4271,-1013.3748 -2809.471,-552.87039 -2664.1254,-407.52476 C -2536.0247,-279.42406 -2251.8984,-352.9864 -1928.9745,-592.18115 L -1900.4322,-673.83701 C -2219.5049,-425.06394 -2546.9226,-295.78223 -2657.548,-406.40769 C -2782.9392,-531.79891 -2602.7452,-874.41118 -2280.1282,-1239.1822 L -2182.6289,-1141.6828 C -2141.9637,-1369.9772 -2062.2529,-1559.2259 -1961.364,-1727.2966 L -1963.3492,-1726.552 L -1960.7434,-1733.6253 C -2163.7123,-1687.9368 -2364.6159,-1631.9217 -2552.6862,-1511.7402 z " id="path5589" sodipodi:nodetypes="ccsccscccccc" /> <path style="fill:url(#linearGradient5370);fill-opacity:1;stroke:#4d4d4d;stroke-width:19.02506828;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.6540881" d="M -1951.4363,-1677.6577 L -1984.1979,-1577.3873 C -1651.5503,-1846.5798 -1305.9335,-1987.7022 -1191.0935,-1872.8622 C -1064.3498,-1746.1184 -1258.6297,-1406.2164 -1588.3113,-1037.5481 L -1692.4456,-1141.6824 C -1707.4985,-924.70423 -1811.2056,-737.27748 -1914.5793,-549.73957 C -1657.3381,-612.85457 -1416.3472,-678.92415 -1322.5125,-771.74937 L -1431.1143,-880.35115 C -1113.5998,-1262.3206 -1044.6177,-1731.5989 -1192.3345,-1879.3156 C -1320.7088,-2007.6899 -1627.7451,-1917.9724 -1951.4363,-1677.6577 z " id="path5341" sodipodi:nodetypes="ccscccccsc" />
+</g>
+</g>
 </svg>
