diff --git a/extensions/fablabchemnitz/animate_order/animate_order.html b/extensions/fablabchemnitz/animate_order/animate_order.html
new file mode 100644
index 00000000..6f72a19f
--- /dev/null
+++ b/extensions/fablabchemnitz/animate_order/animate_order.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Animate Order - joinery_2021-4-25_1.24.3.svg
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/fablabchemnitz/animate_order/drawing.svg b/extensions/fablabchemnitz/animate_order/drawing.svg
new file mode 100644
index 00000000..52f3ff71
--- /dev/null
+++ b/extensions/fablabchemnitz/animate_order/drawing.svg
@@ -0,0 +1,494 @@
+
+
diff --git a/extensions/fablabchemnitz/jitter_gradients.inx b/extensions/fablabchemnitz/jitter_gradients.inx
new file mode 100644
index 00000000..db1c41bb
--- /dev/null
+++ b/extensions/fablabchemnitz/jitter_gradients.inx
@@ -0,0 +1,17 @@
+
+
+ <_name>Jitter Gradients
+ fablabchemnitz.de.jittergradients
+ 0
+
+ all
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/jitter_gradients.py b/extensions/fablabchemnitz/jitter_gradients.py
new file mode 100644
index 00000000..40143a7b
--- /dev/null
+++ b/extensions/fablabchemnitz/jitter_gradients.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+import inkex
+from inkex import Style
+import re
+import random
+
+class JitterGradients(inkex.EffectExtension):
+
+ def add_arguments(self, pars):
+ pars.add_argument('-j', '--jitter_amount', type=int, default=10, help='Relative to distance between gradient nodes')
+
+ def getUrlFromString(self, text):
+ pattern = re.compile(r"url\(#([a-zA-Z0-9_-]+)\)")
+ result = re.search(pattern, text)
+ if (result):
+ return result.group(1)
+ else:
+ return 0;
+
+ def getFill(self, element):
+ if(element.get('fill') and self.getUrlFromString(element.get('fill'))):
+ return self.getUrlFromString(element.get('fill'))
+ elif (element.get('style') and Style(element.get('style'))['fill'] and self.getUrlFromString(Style(element.get('style'))['fill'])):
+ return self.getUrlFromString(Style(element.get('style'))['fill'])
+ else:
+ return None
+
+ def getGradientFromId(self, elementId):
+ element = self.svg.getElementById(elementId)
+ if (element is not None and element.tag.find("linearGradient") >= 0):
+ return element
+ else:
+ return None
+
+ def effect(self):
+ option = self.options.jitter_amount
+ self._main_function(option)
+
+ def _main_function(self, amount):
+ for element in self.svg.selected.values():
+ fillId = self.getFill(element)
+ if (fillId is None):
+ continue
+
+ gradient = self.getGradientFromId(fillId)
+ if (gradient is None):
+ continue
+
+ x1 = self.svg.unittouu(gradient.get("x1"))
+ y1 = self.svg.unittouu(gradient.get("y1"))
+ x2 = self.svg.unittouu(gradient.get("x2"))
+ y2 = self.svg.unittouu(gradient.get("y2"))
+
+ x1 += random.uniform(-amount, amount)
+ y1 += random.uniform(-amount, amount)
+ x2 += random.uniform(-amount, amount)
+ y2 += random.uniform(-amount, amount)
+
+ gradient.set('x1', str(self.svg.uutounit(x1, self.svg.unit)) + self.svg.unit)
+ gradient.set('y1', str(self.svg.uutounit(y1, self.svg.unit)) + self.svg.unit)
+ gradient.set('x2', str(self.svg.uutounit(x2, self.svg.unit)) + self.svg.unit)
+ gradient.set('y2', str(self.svg.uutounit(y2, self.svg.unit)) + self.svg.unit)
+
+if __name__ == '__main__':
+ JitterGradients().run()
\ No newline at end of file