diff --git a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY b/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY
deleted file mode 100644
index 57af0098..00000000
--- a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY
+++ /dev/null
@@ -1,1223 +0,0 @@
-# -*- coding: utf-8 -*-
-import bpy
-import math
-
-from bpy.types import PropertyGroup
-from mathutils import Vector
-
-from . import cfg
-from . import at_panel
-from . import at_operators
-from . at_calc_func import(
-    x_axis,
-    y_axis,
-    z_axis,
-    xyz_axis,
-    at_all_in_one,
-    at_random,
-    sum_serie,
-    tsr
-)
-
-"""not used yet
-if check on update, may really slow the addon """
-def check_list(alist):
-    """check all the objects"""
-    for elem in alist:
-        if elem in bpy.data.objects:
-            pass
-        else:
-            cfg.display_error(str(elem)+" isn't valid.")
-            print("Check_list : a name isn't valid ", elem)
-            return False
-    return True
-
-
-def elem_in_row(column, row, indice):
-    """Number of elements in a row"""
-    elements = column + (row - 1) * indice
-    # print("row elements =", elements)
-    return elements
-
-
-# ---------------------------- Properties ---------------------------
-class ArrayTools_props(PropertyGroup):
-    """Properties for array tools"""
-
-    def add_in_column(self, row, nb_column=-1):
-        """Add nb_column element(s) in each row"""
-        column = cfg.at_count_values[0]
-        if nb_column == -1:
-            nb_column = cfg.at_count_values[1] - column
-
-        ref_name = cfg.atools_objs[0][0]
-        if ref_name in bpy.data.objects:
-            ref_obj = bpy.data.objects[ref_name]
-            # update the ref_mtx if object's transforms have changed
-            cfg.ref_mtx = ref_obj.matrix_world.copy()
-            # with offset no need to replace all elements, only the last
-            if self.is_tr_off_last:
-                for i in range(row):
-                    col = column + i*self.alter
-                    for j in range(col, col + nb_column):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-
-                        self.transforms_lsr(j, i, cfg.ref_mtx, objcp.name)
-                # update the global ui
-                tr, sc, rot = self.calc_global()
-                self.up_ui_tr_global(tr)
-                self.up_ui_sc_global(sc)
-                self.up_ui_rot_global(rot)
-
-            else: # replace all elements
-                for i in range(row):
-                    col = column + i*self.alter
-                    for j in range(col, col + nb_column):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-                self.update_global(bpy.context)
-            del objcp
-            del ref_obj
-        else:
-            message = "Problem with reference object's name."
-            cfg.display_error(message)
-            print("Error in 'add_in_column' : ", message)
-
-
-    def del_in_column(self, row, nb_column=-1):
-        """Remove nb_column element(s) in each row"""
-        if nb_column == -1:
-            nb_column = cfg.at_count_values[0] - cfg.at_count_values[1]
-        array_col = bpy.data.collections.get(cfg.col_name)
-        for i in range(row-1, -1, -1):
-            for j in range(nb_column):
-                del_name = cfg.atools_objs[i].pop()
-                if del_name in bpy.data.objects:
-                    obj = bpy.data.objects[del_name]
-                    array_col.objects.unlink(obj)
-                    bpy.data.objects.remove(obj, do_unlink=True)
-                else:
-                    cfg.display_error(del_name + " doesn't exist anymore.")
-                    print("Error in 'del_in_column' : ", del_name)
-
-                # if no more element in list, remove the row
-                if not cfg.atools_objs[i]:
-                    cfg.atools_objs.pop()
-                    self.up_ui_updateRow(row - 1)
-                    continue
-        if not self.is_tr_off_last:
-            # if global is used last
-            self.update_global(bpy.context)
-        else:
-            tr, sc, rot = self.calc_global()
-            self.up_ui_tr_global(tr)
-            self.up_ui_sc_global(sc)
-            self.up_ui_rot_global(rot)
-
-
-    def add_in_col_alter(self, row, nb_column):
-        """Add elements in all rows except the first for variation"""
-        array_col = bpy.data.collections.get(cfg.col_name)
-        ref_name = cfg.atools_objs[0][0]
-        column = self.count
-        if ref_name in bpy.data.objects:
-            ref_obj = bpy.data.objects[ref_name]
-            cfg.ref_mtx = ref_obj.matrix_world.copy()
-            if self.is_tr_off_last:
-                for i in range(1, row):
-                    for j in range(column, column + i * nb_column):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-                        # print("objs=", cfg.atools_objs)
-
-                self.update_offset(bpy.context)
-            else: # replace all elements
-                for i in range(1, row):
-                    for j in range(column, column + i * nb_column):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-                self.update_global(bpy.context)
-            del objcp
-            del ref_obj
-        else:
-            message = "Problem with reference object's name."
-            cfg.display_error(message)
-            print("Error in 'add_in_column' : ", message)
-
-
-    def del_in_col_alter(self, row, nb_column):
-        """Remove elements in all rows except the first"""
-        array_col = bpy.data.collections.get(cfg.col_name)
-        for i in range(row -1 , 0, -1):
-            for j in range(nb_column * i):
-                del_name = cfg.atools_objs[i].pop()
-                # print("del name=", del_name)
-                if del_name in bpy.data.objects:
-                    obj = bpy.data.objects[del_name]
-                    array_col.objects.unlink(obj)
-                    bpy.data.objects.remove(obj, do_unlink=True)
-                else:
-                    cfg.display_error(del_name + " doesn't exist anymore.")
-                    print("Error in 'del_in_column' : ", del_name)
-        if self.is_tr_off_last:
-            self.update_offset(bpy.context)
-        else:
-            self.update_global(bpy.context)
-
-    def add_in_row(self, column, nb_row=-1):
-        """Add column elements in nb_row new row(s)"""
-        row = cfg.at_row_values[0]
-        if nb_row == -1:
-            nb_row = cfg.at_row_values[1] - row
-
-        ref_name = cfg.atools_objs[0][0]
-        if ref_name in bpy.data.objects:
-            ref_obj = bpy.data.objects[ref_name]
-            cfg.ref_mtx = ref_obj.matrix_world.copy()
-            if self.is_tr_off_last:
-                for i in range(row, row + nb_row):
-                    cfg.atools_objs.append([])
-                    for j in range(column + i*self.alter):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-                        self.transforms_lsr(j, i, cfg.ref_mtx, objcp.name)
-            else:
-                for i in range(row, row + nb_row):
-                    cfg.atools_objs.append([])
-                    for j in range(column):
-                        objcp = ref_obj.copy()
-                        array_col = bpy.data.collections.get(cfg.col_name)
-                        array_col.objects.link(objcp)
-                        if self.is_copy:
-                            objcp.data = ref_obj.data.copy()
-                        cfg.atools_objs[i].append(objcp.name)
-                self.update_global(bpy.context)
-        else:
-            message = "Problem with reference object's name."
-            cfg.display_error(message)
-            print("Error in 'add in row' : ", message)
-
-
-    def del_in_row(self, nb_row=-1):
-        """Remove nb_row row(s) : (column * nb_row) elements"""
-        if nb_row == -1:
-            nb_row = cfg.at_row_values[0] - cfg.at_row_values[1]
-        array_col = bpy.data.collections.get(cfg.col_name)
-        for i in range(nb_row):
-            names = cfg.atools_objs.pop()
-            for del_name in names:
-                if del_name in bpy.data.objects:
-                    obj = bpy.data.objects[del_name]
-                    array_col.objects.unlink(obj)
-                    bpy.data.objects.remove(obj, do_unlink=True)
-                else:
-                    cfg.display_error(del_name + " doesn't exist anymore.")
-                    print("Error in 'del_in_column' : ", del_name)
-
-
-    def at_del_all(self, del_rall):
-        """Delete all copies and remove objects from lists
-        del_rall : boolean, True to del reference object from list
-        """
-        array_col = bpy.data.collections.get(cfg.col_name)
-        ref_name = cfg.atools_objs[0][0]
-        for i in range(self.row):
-            names = cfg.atools_objs.pop()
-            for obj_name in reversed(names):
-                if obj_name == ref_name:
-                    continue
-                # test if object exist
-                if obj_name in bpy.data.objects:
-                    obj = bpy.data.objects[obj_name]
-                    array_col.objects.unlink(obj)
-                    bpy.data.objects.remove(obj, do_unlink=True)
-                else:
-                    cfg.display_error(obj_name + " not exist!")
-                    print("Error in 'del_all' : ", obj_name)
-
-        if del_rall:
-            cfg.atools_objs.clear()
-
-            # removing the collection if empty
-            if not array_col.objects:
-                bpy.data.collections.remove(array_col)
-        else:
-            cfg.atools_objs.append([ref_name])
-        # print("Del_all done!")
-
-    # ----------------------- UI update -----------------------------
-    # ---------------------------------------------------------------
-    # ----------------------- count update --------------------------
-    def updateCount(self, context):
-        """update the number of element(s) in column"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            cfg.add_count(int(self.count))
-            cfg.del_count()
-
-            # cfg.count_values[0] always store old count value
-            difference = self.count - cfg.at_count_values[0]
-
-            self.update_infos()
-
-            if difference > 0:
-                self.add_in_column(self.row, difference)
-            elif difference < 0:
-                self.del_in_column(self.row, -difference)
-        # print("objs =", cfg.atools_objs)
-
-
-    def up_ui_updateCount(self, val):
-        """Update the value of the property count in UI"""
-        self.is_prog_change = True
-        self.count = val
-
-    # ----------------------- row update ----------------------------
-    def update_row(self, context):
-        """Update row property"""
-        cfg.add_row(self.row)
-        cfg.del_row()
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            if self.alter < 0 and cfg.maxrow < self.row:
-                cfg.display_error("Maximun rows for these setting is : " + str(cfg.maxrow))
-                self.up_ui_updateRow(cfg.maxrow)
-                return
-
-            # cfg.at_row_values[0] always store old row value
-            difference = self.row - cfg.at_row_values[0]
-            if difference > 0:
-                self.add_in_row(self.count, difference)
-            elif difference < 0:
-                self.del_in_row(-difference)
-
-            line = elem_in_row(self.count, self.row, self.alter)
-
-            self.update_infos()
-
-    def up_ui_updateRow(self, val):
-        """Update the value of the property row in UI"""
-        self.is_prog_change = True
-        self.row = val
-
-    def update_alter(self, context):
-        """Update alter property"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            # alter must have at least 2 rows
-            if self.row == 1 and self.alter != 0:
-                cfg.display_error("Add more rows first.")
-                self.up_ui_updateAlter(0)
-                return
-            if self.alter < 0:
-                # (column + (row-1)* variation) is the number of elements
-                # of the last row and must be at least >= 1
-                alter = int((1 - self.count) / (self.row - 1))
-                if self.alter < alter:
-                    cfg.display_error("Min variation is '"+str(alter)+"' for these settings.")
-                    self.up_ui_updateAlter(alter)
-                    return
-
-            cfg.add_alter(self.alter)
-            cfg.del_alter()
-            self.update_ralign()
-
-            difference = self.alter - cfg.at_alter[0]
-            if difference > 0:
-                self.add_in_col_alter(self.row, difference)
-            elif difference < 0:
-                self.del_in_col_alter(self.row, -difference)
-            # print(f"count={self.count}, row={self.row}, alter={self.alter}")
-            line = elem_in_row(self.count, self.row, self.alter)
-            # print("elems in row =", line)
-
-            self.update_infos()
-
-
-    def up_ui_updateAlter(self, val):
-        """Update the value of the property alter in UI"""
-        self.is_prog_change = True
-        self.alter = val
-
-
-    def update_ralign(self):
-        """Update the value of ralign"""
-        decal = -self.alter * self.tr_offset
-        if self.align == 'LEFT':
-            self.ralign = Vector((0.0, 0.0, 0.0))
-        elif self.align == 'CENTER':
-            self.ralign = decal / 2
-        elif self.align == 'RIGHT':
-            self.ralign = decal
-
-
-    def update_align(self, context):
-        """According to the value of align, calculate ralign"""
-        self.update_ralign()
-        
-        if self.is_tr_off_last:
-            self.update_offset(bpy.context)
-        else:
-            self.update_global(bpy.context)
-
-
-    def update_infos(self):
-        """Update properties total and erow"""
-        sum = sum_serie(self.row, self.alter)
-        square = self.count * self.row
-        if self.alter >= 0:
-            cfg.maxrow = self.row
-        else:
-            ca = self.count // -self.alter
-            cfg.maxrow = ca if self.count % self.alter == 0 else ca + 1
-        self.total = str(int(square + sum))
-        self.erow = str(elem_in_row(self.count, self.row, self.alter))
-
-    # ----------------------- translation update --------------------
-    def up_ui_tr_offset(self, val):
-        """Update the value of the property tr_offset in UI"""
-        self.is_prog_change = True
-        self.tr_offset = val
-
-    def up_ui_tr_global(self, val):
-        """Update the value of the property tr_global in UI"""
-        self.is_prog_change = True
-        self.tr_global = val
-
-    # ----------------------- scale update --------------------------
-    def up_ui_sc_offset(self, val):
-        """Update the value of the property sc_offset in UI"""
-        self.is_prog_change = True
-        self.sc_offset = val
-
-    def up_ui_sc_global(self, val):
-        """Update the value of the property sc_global in UI"""
-        self.is_prog_change = True
-        self.sc_global = val
-
-    # ----------------------- rotation update -----------------------
-    def up_ui_rot_offset(self, val):
-        """Update the value of the property rot_offset in UI"""
-        self.is_prog_change = True
-        self.rot_offset = val
-
-    def up_ui_rot_global(self, val):
-        """Update the value of the property rot_global in UI"""
-        self.is_prog_change = True
-        self.rot_global = val
-
-    # ---------------------------------------------------------------
-    def calc_global(self):
-        """Calculate global for column"""
-        tg = (self.count-1) * self.tr_offset
-        sg = (xyz_axis() - (self.count-1) *
-            (cfg.ref_mtx.to_scale() - (self.sc_offset/100))) * 100
-        rg = self.count * Vector(self.rot_offset)
-        return tg,sg,rg
-
-
-    def transforms_lsr(self, column, row, mat, ename):
-        """Calculate transforms according to the position of the element
-        column : indice of the element's column
-        row : indice of the element's row
-        mat : matrix of the reference object
-        ename : element's name to put in place
-        """
-        localxyz = (x_axis(), y_axis(), z_axis())
-
-        translate, scaling, rotate = tsr(mat, column, row, self.tr_offset, self.tr_second,
-            self.sc_offset, self.sc_second, self.rot_offset, self.rot_second, self.ralign)
-        if ename in bpy.data.objects:
-            obj = bpy.data.objects[ename]
-        if self.at_pivot is not None:
-            obj.matrix_world = at_all_in_one(mat, rotate, localxyz, translate,
-                scaling, self.at_pivot.location)
-        else:
-            obj.matrix_world = at_all_in_one(mat, rotate, localxyz, translate,
-                scaling, mat.translation)
-
-
-    def apply_transforms(self, matx, nb_column, nb_row, tr, sc, rot):
-        """Move, scale and rotate the selected elements
-        tr : translation offset of the first row
-        sc : scale offset of the first row
-        rot : rotation offset of the first row
-        return global transforms
-        """
-        # local axis always (1,0,0) (0,1,0) (0,0,1)
-        localxyz = (x_axis(), y_axis(), z_axis())
-
-        ref_scale = matx.to_scale()
-        # duplicate code but avoid looping the test
-        if self.at_pivot is not None:
-            for i in range(nb_row):
-                for j in range(nb_column + i*self.alter):
-                    elem = cfg.atools_objs[i][j]
-                    if elem in bpy.data.objects:
-                        obj = bpy.data.objects[elem]
-                    else:
-                        cfg.display_error(elem + " no more exist !")
-                        print("Error in 'apply_transforms', name no more exist : ", elem)
-                        continue
-                    t_off, s_off, r_off = tsr(matx, j, i, tr, self.tr_second, sc,
-                        self.sc_second, rot, self.rot_second, self.ralign)
-
-                    obj.matrix_world = at_all_in_one(matx, r_off,
-                        localxyz, t_off, s_off, self.at_pivot.location)
-        else:
-            for i in range(nb_row):
-                for j in range(nb_column + i*self.alter):
-                    ref_loc = cfg.ref_mtx.translation
-                    elem = cfg.atools_objs[i][j]
-                    if elem in bpy.data.objects:
-                        obj = bpy.data.objects[elem]
-                    else:
-                        cfg.display_error(elem + " no more exist !")
-                        print("Error in 'apply_transforms', name no more exist : ", elem)
-                        continue
-                    t_off, s_off, r_off = tsr(matx, j, i, tr, self.tr_second, sc,
-                        self.sc_second, rot, self.rot_second, self.ralign)
-
-                    obj.matrix_world = at_all_in_one(matx, r_off,
-                        localxyz, t_off, s_off, ref_loc)
-        tr_col,sc_col,rot_col = self.calc_global()
-        return(tr_col, sc_col, rot_col)
-
-    def update_offset(self, context):
-        """Update for all offsets"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else: # user change offset
-            self.is_tr_off_last = True
-
-            ref_name = cfg.atools_objs[0][0]
-            if bpy.data.objects[ref_name]:
-                cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy()
-            aloc, asc, arot = self.apply_transforms(cfg.ref_mtx, self.count, self.row,
-                self.tr_offset, self.sc_offset, Vector(self.rot_offset))
-
-            # since offset changes, global too
-            self.up_ui_tr_global(aloc)
-            self.up_ui_sc_global(asc)
-            self.up_ui_rot_global(arot)
-
-
-    def update_global(self, context):
-        """Update for all globals"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else: # user change global
-            self.is_tr_off_last = False
-
-            ref_name = cfg.atools_objs[0][0]
-            if bpy.data.objects[ref_name]:
-                cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy()
-            ref_scale = cfg.ref_mtx.to_scale()
-
-            translation_offset = Vector(self.tr_global) / (self.count - 1)
-            scale_offset = ref_scale - ((ref_scale-(self.sc_global/100)) / (self.count - 1))
-            rotation_offset = Vector(self.rot_global) / self.count
-
-            self.apply_transforms(cfg.ref_mtx, self.count, self.row, translation_offset,
-                Vector(scale_offset)*100, rotation_offset)
-
-            # since global changes, offset too
-            self.up_ui_tr_offset(translation_offset)
-            self.up_ui_sc_offset(Vector(scale_offset*100))
-            self.up_ui_rot_offset(rotation_offset)
-
-
-    def update_second(self, context):
-        """Update the secondary transforms"""
-        ref_name = cfg.atools_objs[0][0]
-        if bpy.data.objects[ref_name]:
-            cfg.ref_mtx = bpy.data.objects[ref_name].matrix_world.copy()
-        self.apply_transforms(cfg.ref_mtx, self.count, self.row, self.tr_offset,
-            self.sc_offset, self.rot_offset)
-
-
-    # ----------------------- is_copy update ------------------------
-    def up_ui_is_copy(self):
-        """Update the value of the property is_copy in UI"""
-        self.is_prog_change = True
-        self.is_copy = False
-
-
-    def update_is_copy(self, context):
-        """Allow a copy or duplicate(copy link by default)"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            if self.is_copy:  # no need to rebuild all
-                for i in range(self.row):
-                    for j in range(self.count):
-                        if i == 0 and j == 0:
-                            continue
-                        ref_name = cfg.atools_objs[0][0]
-                        elem_name = cfg.atools_objs[i][j]
-                        bpy.data.objects[elem_name].data = bpy.data.objects[ref_name].data.copy()
-            else:  # since the value change (now duplicate), need to rebuild
-                count = self.count
-                row = self.row
-                ref_name = cfg.atools_objs[0][0]
-                array_col = bpy.data.collections.get(cfg.col_name)
-
-                # DO NOT USE BLENDER CRASH WITH IT
-                # self.at_del_all(False)
-
-                bpy.ops.object.delete({"selected_objects": array_col.objects})
-                cfg.atools_objs.clear()
-                cfg.atools_objs.append([ref_name])
-
-                ref_obj = bpy.data.objects[ref_name]
-                for i in range(row):
-                    if i != 0:
-                        cfg.atools_objs.append([])
-                    for j in range(count + i*self.alter):
-                        objcp = ref_obj.copy()
-                        array_col.objects.link(objcp)
-                        cfg.atools_objs[i].append(objcp.name)
-                del objcp
-                del ref_obj
-
-                if self.is_tr_off_last:
-                    self.update_offset(bpy.context)
-                else:
-                    self.update_global(bpy.context)
-
-                print("Rebuild done!")
-
-    # ----------------------- random part ---------------------------
-    # ---------------------------------------------------------------
-    def update_seed(self, context):
-        if self.at_mode == 'ADV':
-            sc_min = (self.sc_min_x, self.sc_min_y, self.sc_min_z)
-            sc_max = (self.sc_max_x, self.sc_max_y, self.sc_max_z)
-            at_random(self.at_seed, self.count, self.row, self.tr_min, self.tr_max, sc_min,
-                sc_max, self.rot_min, self.rot_max, self.at_is_tr, self.at_is_sc, self.at_is_rot,
-                self.sc_all, self.tr_offset, self.tr_second, self.sc_offset, self.sc_second,
-                self.rot_offset, self.rot_second, self.at_pivot, self.alter, self.ralign)
-        else: # simple mode
-            vec = xyz_axis()
-            tr = self.tr_rand * vec
-            sc = self.sc_rand * vec
-            rot = self.rot_rand * vec
-            at_random(self.at_seed, self.count, self.row, -tr, tr, sc, 100*vec, -rot, rot,
-                self.at_is_tr, self.at_is_sc, self.at_is_rot, False, self.tr_offset,
-                self.tr_second, self.sc_offset, self.sc_second, self.rot_offset,
-                self.rot_second, self.at_pivot, self.alter, self.ralign)
-
-
-    def update_rtr(self, context):
-        """rtr in simple mode update adv mode"""
-        self.tr_max = self.tr_rand * Vector((1.0, 1.0, 1.0))
-        self.tr_min = self.tr_rand * Vector((-1.0, -1.0, -1.0))
-
-
-    def update_rsc(self, context):
-        """rsc in simple mode update adv mode"""
-        self.sc_max_x, self.sc_max_y, self.sc_max_z = (100.0, 100.0, 100.0)
-        rand = self.sc_rand
-        self.sc_min_x = rand
-        self.sc_min_y = rand
-        self.sc_min_z = rand
-
-
-    def update_rrot(self, context):
-        """rrot in simple mode update adv mode"""
-        self.rot_max = self.rot_rand * Vector((1.0, 1.0, 1.0))
-        self.rot_min = self.rot_rand * Vector((-1.0, -1.0, -1.0))
-
-
-    def up_ui_sc_min_x(self, val):
-        """Update the value of the property sc_min_x in UI"""
-        self.is_prog_change = True
-        self.sc_min_x = val
-
-
-    def up_ui_sc_min_y(self, val):
-        """Update the value of the property sc_min_y in UI"""
-        self.is_prog_change = True
-        self.sc_min_y = val
-
-
-    def up_ui_sc_min_z(self, val):
-        """Update the value of the property sc_min_z in UI"""
-        self.is_prog_change = True
-        self.sc_min_z = val
-
-
-    def up_ui_sc_max_x(self, val):
-        """Update the value of the property sc_max_x in UI"""
-        self.is_prog_change = True
-        self.sc_max_x = val
-
-
-    def up_ui_sc_max_y(self, val):
-        """Update the value of the property sc_max_y in UI"""
-        self.is_prog_change = True
-        self.sc_max_y = val
-
-
-    def up_ui_sc_max_z(self, val):
-        """Update the value of the property sc_max_z in UI"""
-        self.is_prog_change = True
-        self.sc_max_z = val
-
-    # -------------- update min and max -----------------------------
-    # if user enter a max value < min, change min and vice versa
-    def up_tr_min(self, context):
-        """Update tr_max if tr_min is higher"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            for i in range(3):
-                if self.tr_min[i] > self.tr_max[i]:
-                    self.is_prog_change = True
-                    self.tr_max[i] = self.tr_min[i]
-
-
-    def up_tr_max(self, context):
-        """Update tr_min if tr_max is lower"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            for i in range(3):
-                if self.tr_min[i] > self.tr_max[i]:
-                    self.is_prog_change = True
-                    self.tr_min[i] = self.tr_max[i]
-
-
-    def up_sc_min_x(self, context):
-        """Update sc_max_x if sc_min_x is higher"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_x > self.sc_max_x
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_max_x(self.sc_min_x)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_min_y(self.sc_min_x)
-                self.up_ui_sc_min_z(self.sc_min_x)
-                self.up_ui_sc_max_y(self.sc_min_x)
-                self.up_ui_sc_max_z(self.sc_min_x)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_min_y(self.sc_min_x)
-                self.up_ui_sc_min_z(self.sc_min_x)
-                self.up_ui_sc_max_y(self.sc_max_x)
-                self.up_ui_sc_max_z(self.sc_max_x)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_max_x(self.sc_min_x)
-
-    def up_sc_min_y(self, context):
-        """Update sc_max_y if sc_min_y is higher"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_y > self.sc_max_y
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_max_y(self.sc_min_y)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_min_x(self.sc_min_y)
-                self.up_ui_sc_min_z(self.sc_min_y)
-                self.up_ui_sc_max_x(self.sc_min_y)
-                self.up_ui_sc_max_y(self.sc_min_y)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_min_x(self.sc_min_y)
-                self.up_ui_sc_min_z(self.sc_min_y)
-                self.up_ui_sc_max_x(self.sc_max_y)
-                self.up_ui_sc_max_z(self.sc_max_y)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_max_y(self.sc_min_y)
-
-    def up_sc_min_z(self, context):
-        """Update sc_max_z if sc_min_z is higher"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_z > self.sc_max_z
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_max_z(self.sc_min_z)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_min_x(self.sc_min_z)
-                self.up_ui_sc_min_y(self.sc_min_z)
-                self.up_ui_sc_max_x(self.sc_min_z)
-                self.up_ui_sc_max_y(self.sc_min_z)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_min_x(self.sc_min_z)
-                self.up_ui_sc_min_y(self.sc_min_z)
-                self.up_ui_sc_max_x(self.sc_max_z)
-                self.up_ui_sc_max_y(self.sc_max_z)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_max_y(self.sc_min_z)
-
-    def up_sc_max_x(self, context):
-        """Update sc_min_x if sc_max_x is lower"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_x > self.sc_max_x
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_min_x(self.sc_max_x)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_max_y(self.sc_max_x)
-                self.up_ui_sc_max_z(self.sc_max_x)
-                self.up_ui_sc_min_y(self.sc_max_x)
-                self.up_ui_sc_min_z(self.sc_max_x)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_max_y(self.sc_max_x)
-                self.up_ui_sc_max_z(self.sc_max_x)
-                self.up_ui_sc_min_y(self.sc_min_x)
-                self.up_ui_sc_min_z(self.sc_min_x)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_min_x(self.sc_max_x)
-
-    def up_sc_max_y(self, context):
-        """Update sc_min_y if sc_max_y is lower"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_y > self.sc_max_y
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_min_y(self.sc_max_y)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_max_x(self.sc_max_y)
-                self.up_ui_sc_max_z(self.sc_max_y)
-                self.up_ui_sc_min_x(self.sc_max_y)
-                self.up_ui_sc_min_z(self.sc_max_y)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_max_x(self.sc_max_y)
-                self.up_ui_sc_max_z(self.sc_max_y)
-                self.up_ui_sc_min_x(self.sc_min_y)
-                self.up_ui_sc_min_z(self.sc_min_y)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_min_y(self.sc_max_y)
-
-    def up_sc_max_z(self, context):
-        """Update sc_min_z if sc_max_z is lower"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            test = self.sc_min_z > self.sc_max_z
-            if test and self.sc_all:
-                # case : min > max and uniform = True
-                self.up_ui_sc_min_z(self.sc_max_z)
-                # with uniform : min_x = min_y = min_z same for max_
-                self.up_ui_sc_max_x(self.sc_max_z)
-                self.up_ui_sc_max_y(self.sc_max_z)
-                self.up_ui_sc_min_x(self.sc_max_z)
-                self.up_ui_sc_min_y(self.sc_max_z)
-            elif self.sc_all:
-                # case : min < max and uniform = True
-                self.up_ui_sc_max_x(self.sc_max_z)
-                self.up_ui_sc_max_y(self.sc_max_z)
-                self.up_ui_sc_min_x(self.sc_min_z)
-                self.up_ui_sc_min_y(self.sc_min_z)
-            elif test:
-                # case : min > max and uniform = False
-                self.up_ui_sc_min_z(self.sc_max_z)
-
-    def up_rot_min(self, context):
-        """Update rot_max if rot_min is higher"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            for i in range(3):
-                if self.rot_min[i] > self.rot_max[i]:
-                    self.is_prog_change = True
-                    self.rot_max[i] = self.rot_min[i]
-
-    def up_rot_max(self, context):
-        """Update rot_min if rot_max is lower"""
-        if self.is_prog_change:
-            self.is_prog_change = False
-        else:
-            for i in range(3):
-                if self.rot_min[i] > self.rot_max[i]:
-                    self.is_prog_change = True
-                    self.rot_min[i] = self.rot_max[i]
-
-    # ----------------------- reset all properties ------------------
-    def up_ui_reset(self):
-        """Reset all UI properties"""
-        self.up_ui_updateCount(2)
-        self.up_ui_updateRow(1)
-        self.up_ui_is_copy()
-        self.up_ui_tr_offset(Vector((2.0, 0.0, 0.0)))
-        self.up_ui_tr_global(Vector((2.0, 0.0, 0.0)))
-        self.up_ui_sc_offset((100, 100, 100))
-        self.up_ui_sc_global((100, 100, 100))
-        self.up_ui_rot_offset(Vector((0.0, 0.0, 0.0)))
-        self.up_ui_rot_global(Vector((0.0, 0.0, 0.0)))
-        self.up_ui_updateAlter(0)
-        self.total = "2"
-        self.erow = "2"
-
-
-    count: bpy.props.IntProperty(
-        name='Count',
-        description="Number of elements, original count as one",
-        default=2,
-        soft_min=2,
-        update=updateCount
-    )
-
-    row: bpy.props.IntProperty(
-        name="Row",
-        description="Number of row(s)",
-        default=1,
-        soft_min=1,
-        soft_max=100,
-        update=update_row
-    )
-
-    """Allow a variation in the row :
-    if row gets n elements, row +1 will get (n + variation) elements
-    only if n + variation > 0
-    """
-    alter: bpy.props.IntProperty(
-        name=" Row variation",
-        description="""Variation in the number of elements in a row. (between -5 and 5).
-            \n Be careful with it""",
-        default=0,
-        soft_min=-5,
-        soft_max=5,
-        update=update_alter
-    )
-
-    total: bpy.props.StringProperty(
-        name="Total",
-        description="Total of elements in array",
-        default="2"
-    )
-
-    erow: bpy.props.StringProperty(
-        description="Number of elements in the current row.",
-        default="2"
-    )
-
-    # if alter <> 0, how align the rows
-    align: bpy.props.EnumProperty(
-        name='Align',
-        description="Align of rows when variation is not zero",
-        items=[
-            ('LEFT', 'Left', "Align to the left", 'ALIGN_LEFT', 0),
-            ('CENTER', 'Center', "Align to the center", 'ALIGN_CENTER', 1),
-            ('RIGHT', 'Right', "Align to the right", 'ALIGN_RIGHT', 2)
-        ],
-        default='LEFT',
-        update=update_align
-    )
-
-    # Vector alignment depends on align
-    ralign: bpy.props.FloatVectorProperty(
-        subtype='TRANSLATION',
-        unit='LENGTH',
-        default=(0.0, 0.0, 0.0)
-    )
-
-    # booleans use to know if user or prog change the value to avoid continuous loop
-    is_prog_change: bpy.props.BoolProperty(default=False)  # True if prog change value
-
-    # which one between offset and global user calls last, True is offset, False global
-    is_tr_off_last: bpy.props.BoolProperty(default=True)
-
-    # True if addon is initialised
-    already_start: bpy.props.BoolProperty(default=False)
-
-    # if the user need a single copy or a duplicate (link object)
-    is_copy: bpy.props.BoolProperty(
-        name="Copy only",
-        description="Duplicate or copy, default is duplicate",
-        default=False,
-        update=update_is_copy
-    )
-
-    # translation vector offset
-    tr_offset: bpy.props.FloatVectorProperty(
-        name='Offset',
-        description="Distance between elements",
-        default=(2.0, 0.0, 0.0),
-        subtype='TRANSLATION',
-        unit='LENGTH',
-        precision=2,
-        step=50,
-        options={'ANIMATABLE'},
-        update=update_offset
-    )
-
-    # global translation distance
-    tr_global: bpy.props.FloatVectorProperty(
-        name='Global',
-        description="Distance between the original and the last element",
-        default=(2.0, 0.0, 0.0),
-        subtype='TRANSLATION',
-        unit='LENGTH',
-        precision=2,
-        step=50,
-        options={'ANIMATABLE'},
-        update=update_global
-    )
-
-    tr_second: bpy.props.FloatVectorProperty(
-        name="Translation",
-        description="Additional offset distance for rows",
-        default=(0.0, 0.0, 0.0),
-        subtype='TRANSLATION',
-        unit='LENGTH',
-        precision=2,
-        step=50,
-        update=update_second
-    )
-
-    at_pivot: bpy.props.PointerProperty(
-        name='Pivot',
-        description="Object you want as pivot point. If none, pivot point is the object's origine",
-        type=bpy.types.Object
-    )
-
-    # scaling vector offset
-    sc_offset: bpy.props.FloatVectorProperty(
-        name='Offset',
-        description="Incremental scale of the next elements",
-        default=(100.0, 100.0, 100.0),
-        subtype='XYZ',
-        precision=1,
-        step=100,
-        options={'ANIMATABLE'},
-        update=update_offset
-    )
-
-    # global scaling
-    sc_global: bpy.props.FloatVectorProperty(
-        name='Global',
-        description="Scale of the last element",
-        default=(100.0, 100.0, 100.0),
-        subtype='XYZ',
-        precision=1,
-        step=100,
-        options={'ANIMATABLE'},
-        update=update_global
-    )
-
-    sc_second: bpy.props.FloatVectorProperty(
-        name='Scale',
-        description="Additionnal scale for rows",
-        default=(100.0, 100.0, 100.0),
-        subtype='XYZ',
-        precision=1,
-        step=100,
-        options={'ANIMATABLE'},
-        update=update_second
-    )
-    # rotation vector offset
-    rot_offset: bpy.props.FloatVectorProperty(
-        name='Offset',
-        description="Angle between each element",
-        default=(0.0, 0.0, 0.0),
-        subtype='XYZ',
-        unit='ROTATION',
-        step=500,  # = 5
-        options={'ANIMATABLE'},
-        update=update_offset
-    )
-
-    # global rotation
-    rot_global: bpy.props.FloatVectorProperty(
-        name='Global',
-        description="Maximum angle from the reference to the last element",
-        default=(0.0, 0.0, 0.0),
-        subtype='XYZ',
-        unit='ROTATION',
-        step=500,  # = 5
-        options={'ANIMATABLE'},
-        update=update_global
-    )
-
-    rot_second: bpy.props.FloatVectorProperty(
-        name='Rotation',
-        description="Additionnal rotation for rows",
-        default=(0.0, 0.0, 0.0),
-        subtype='XYZ',
-        unit='ROTATION',
-        step=500,
-        options={'ANIMATABLE'},
-        update=update_second
-    )
-
-    # ----------------------- random part ---------------------------
-    at_seed: bpy.props.IntProperty(
-        name='Seed',
-        description="Seed value for random",
-        soft_min=0,
-        default=0,
-        update=update_seed
-    )
-
-    at_mode: bpy.props.EnumProperty(
-        name="Mode",
-        description="Choose between simple mode or advanced",
-        items=(('SIM', 'Simple', "Simple mode"),
-            ('ADV', 'Advanced', "Advanced mode")),
-        default='SIM'
-    )
-
-    at_is_tr: bpy.props.BoolProperty(
-        name="Add translation",
-        description="Add translation in random?",
-        default=False
-    )
-
-    at_is_sc: bpy.props.BoolProperty(
-        name="Add scale",
-        description="Add scale in random?",
-        default=False
-    )
-
-    at_is_rot: bpy.props.BoolProperty(
-        name="Add rotation",
-        description="Add rotation in random?",
-        default=False
-    )
-
-    tr_min: bpy.props.FloatVectorProperty(
-        name="min",
-        description="Minimum random value for translation",
-        unit='LENGTH',
-        default=(0.0, 0.0, 0.0),
-        update=up_tr_min
-    )
-
-    tr_max: bpy.props.FloatVectorProperty(
-        name="max",
-        description="Maximum random value for translation",
-        unit='LENGTH',
-        default=(0.0, 0.0, 0.0),
-        update=up_tr_max
-    )
-
-    tr_rand: bpy.props.FloatProperty(
-        name="Translation",
-        description="Random values for all axis",
-        unit='LENGTH',
-        default=0.0,
-        update=update_rtr
-    )
-
-    sc_all: bpy.props.BoolProperty(
-        name="uniform scale",
-        description="Uniform or non uniform scale, default is non uniform.",
-        default=False
-    )
-
-    sc_min_x: bpy.props.IntProperty(
-        name="min",
-        description="Minimum random value for x scale",
-        default=100,
-        update=up_sc_min_x
-    )
-
-    sc_min_y: bpy.props.IntProperty(
-        name="min",
-        description="Minimum random value for y scale",
-        default=100,
-        update=up_sc_min_y
-    )
-
-    sc_min_z: bpy.props.IntProperty(
-        name="min",
-        description="Minimum random value for z scale",
-        default=100,
-        update=up_sc_min_z
-    )
-
-    sc_max_x: bpy.props.IntProperty(
-        name="max",
-        description="Maximum random value for x scale",
-        default=100,
-        update=up_sc_max_x
-    )
-
-    sc_max_y: bpy.props.IntProperty(
-        name="max",
-        description="Maximum random value for y scale",
-        default=100,
-        update=up_sc_max_y
-    )
-
-    sc_max_z: bpy.props.IntProperty(
-        name="max",
-        description="Maximum random value for z scale",
-        default=100,
-        update=up_sc_max_z
-    )
-
-    sc_rand: bpy.props.IntProperty(
-        name="Scale",
-        description="Random scale value for all axis",
-        default=100,
-        update=update_rsc
-    )
-
-    rot_min: bpy.props.FloatVectorProperty(
-        name="min",
-        description="Minimum random value for rotation",
-        unit='ROTATION',
-        default=(0.0, 0.0, 0.0),
-        update=up_rot_min
-    )
-
-    rot_max: bpy.props.FloatVectorProperty(
-        name="max",
-        description="Maximum random value for rotation",
-        unit='ROTATION',
-        default=(0.0, 0.0, 0.0),
-        update=up_rot_max
-    )
-
-    rot_rand: bpy.props.FloatProperty(
-        name="Rotation",
-        description="Random rotation for all axis",
-        unit='ROTATION',
-        default=0.0,
-        update=update_rrot
-    )