commit fa8068182b485947f25c634c87ecda13fa24750e
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Jan 11 15:55:43 2021 +0100

    Rename 'Minx' to 'Kilominx' - there would be a separate 'Kilominx' and 'Megaminx' series.

diff --git a/src/main/java/org/distorted/objects/MovementKilominx.java b/src/main/java/org/distorted/objects/MovementKilominx.java
new file mode 100644
index 00000000..28e5c633
--- /dev/null
+++ b/src/main/java/org/distorted/objects/MovementKilominx.java
@@ -0,0 +1,303 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.objects;
+
+import org.distorted.library.type.Static3D;
+import static org.distorted.objects.TwistyKilominx.C1;
+import static org.distorted.objects.TwistyKilominx.C2;
+import static org.distorted.objects.TwistyKilominx.LEN;
+import static org.distorted.objects.FactoryCubit.SIN54;
+import static org.distorted.objects.FactoryCubit.COS54;
+import static org.distorted.objects.TwistyObject.SQ5;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class MovementKilominx extends Movement
+{
+  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5)/3;
+  static final float DIST2D = (0.5f*SIN54/COS54)/3;
+
+  static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D( C2/LEN, C1/LEN, 0      ),
+           new Static3D( C2/LEN,-C1/LEN, 0      ),
+           new Static3D(-C2/LEN, C1/LEN, 0      ),
+           new Static3D(-C2/LEN,-C1/LEN, 0      ),
+           new Static3D( 0     , C2/LEN, C1/LEN ),
+           new Static3D( 0     , C2/LEN,-C1/LEN ),
+           new Static3D( 0     ,-C2/LEN, C1/LEN ),
+           new Static3D( 0     ,-C2/LEN,-C1/LEN ),
+           new Static3D( C1/LEN, 0     , C2/LEN ),
+           new Static3D( C1/LEN, 0     ,-C2/LEN ),
+           new Static3D(-C1/LEN, 0     , C2/LEN ),
+           new Static3D(-C1/LEN, 0     ,-C2/LEN )
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MovementKilominx()
+    {
+    super(TwistyKilominx.ROT_AXIS, FACE_AXIS, DIST3D, DIST2D);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int computeRowFromOffset(int face, int size, float offset)
+    {
+    return offset<DIST2D ? 0:2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float returnRotationFactor(int size, int row)
+    {
+    return 1.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// return angle (in radians) that the line connecting the center C of the pentagonal face and the
+// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
+
+  private float returnAngle(int face)
+    {
+    switch(face)
+      {
+      case  0:
+      case  2:
+      case  6:
+      case  7: return 0.0f;
+      case  1:
+      case  3:
+      case  4:
+      case  5: return (float)(36*Math.PI/180);
+      case  9:
+      case 10: return (float)(54*Math.PI/180);
+      case  8:
+      case 11: return (float)(18*Math.PI/180);
+      }
+
+    return 0.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
+// from the center of the coordinate system to P.
+// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
+// P' and going in the direction of V.
+// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
+// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
+// directly upwards, is 'point' on the left or the right of it?
+
+  private boolean isOnTheLeft(float[] point, float distance, float angle)
+    {
+    float sin = (float)Math.sin(angle);
+    float cos = (float)Math.cos(angle);
+
+    float vx = point[0] + sin*distance;
+    float vy = point[1] - cos*distance;
+
+    return vx*sin < vy*cos;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
+// 'point' is inside the pentagon - or 0 otherwise.
+// The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
+// This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
+// pentagon.
+// Distance from the center to a vertex of the pentagon = 1/(6*COS54)
+
+  private int returnPartOfThePentagon(float[] point, int face)
+    {
+    float angle = returnAngle(face);
+    float A = (float)(Math.PI/5);
+
+    for(int i=0; i<5; i++)
+      {
+      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
+      }
+
+    if( isOnTheLeft(point, 0, 2.5f*A-angle) )
+      {
+      if( isOnTheLeft(point, 0, 3.5f*A-angle) )
+        {
+        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
+        }
+      else return 1;
+      }
+    else
+      {
+      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
+        {
+        return 3;
+        }
+      else
+        {
+        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean isInsideFace(int face, float[] p)
+    {
+    return returnPartOfThePentagon(p,face) > 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
+    {
+    int part = returnPartOfThePentagon(touchPoint,face);
+
+    if( part>0 )
+      {
+      enabled[0] = 2;
+
+      switch(face)
+        {
+        case  0:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=3; break;
+                    case 2: enabled[1]=3; enabled[2]=5; break;
+                    case 3: enabled[1]=5; enabled[2]=1; break;
+                    case 4: enabled[1]=1; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  1:  switch(part)
+                    {
+                    case 1: enabled[1]=0; enabled[2]=5; break;
+                    case 2: enabled[1]=5; enabled[2]=2; break;
+                    case 3: enabled[1]=2; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=0; break;
+                    }
+                  break;
+
+        case  2:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=2; break;
+                    case 2: enabled[1]=2; enabled[2]=5; break;
+                    case 3: enabled[1]=5; enabled[2]=0; break;
+                    case 4: enabled[1]=0; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=3; break;
+                    }
+                  break;
+
+        case  3:  switch(part)
+                    {
+                    case 1: enabled[1]=1; enabled[2]=5; break;
+                    case 2: enabled[1]=5; enabled[2]=3; break;
+                    case 3: enabled[1]=3; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=4; break;
+                    case 5: enabled[1]=4; enabled[2]=1; break;
+                    }
+                  break;
+
+        case  4:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=0; break;
+                    case 2: enabled[1]=0; enabled[2]=4; break;
+                    case 3: enabled[1]=4; enabled[2]=5; break;
+                    case 4: enabled[1]=5; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=3; break;
+                    }
+                  break;
+
+        case  5:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=1; break;
+                    case 2: enabled[1]=1; enabled[2]=4; break;
+                    case 3: enabled[1]=4; enabled[2]=5; break;
+                    case 4: enabled[1]=5; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  6:  switch(part)
+                    {
+                    case 1: enabled[1]=5; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=1; break;
+                    case 3: enabled[1]=1; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=5; break;
+                    }
+                  break;
+
+        case  7:  switch(part)
+                    {
+                    case 1: enabled[1]=5; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=0; break;
+                    case 3: enabled[1]=0; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=5; break;
+                    }
+                  break;
+
+        case  8: switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=0; break;
+                    case 2: enabled[1]=0; enabled[2]=1; break;
+                    case 3: enabled[1]=1; enabled[2]=3; break;
+                    case 4: enabled[1]=3; enabled[2]=5; break;
+                    case 5: enabled[1]=5; enabled[2]=2; break;
+                    }
+                  break;
+
+        case  9:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=2; break;
+                    case 3: enabled[1]=2; enabled[2]=1; break;
+                    case 4: enabled[1]=1; enabled[2]=0; break;
+                    case 5: enabled[1]=0; enabled[2]=3; break;
+                    }
+                  break;
+
+        case 10:  switch(part)
+                    {
+                    case 1: enabled[1]=2; enabled[2]=4; break;
+                    case 2: enabled[1]=4; enabled[2]=3; break;
+                    case 3: enabled[1]=3; enabled[2]=0; break;
+                    case 4: enabled[1]=0; enabled[2]=1; break;
+                    case 5: enabled[1]=1; enabled[2]=2; break;
+                    }
+                  break;
+
+        case 11:  switch(part)
+                    {
+                    case 1: enabled[1]=3; enabled[2]=1; break;
+                    case 2: enabled[1]=1; enabled[2]=0; break;
+                    case 3: enabled[1]=0; enabled[2]=2; break;
+                    case 4: enabled[1]=2; enabled[2]=5; break;
+                    case 5: enabled[1]=5; enabled[2]=3; break;
+                    }
+                  break;
+        }
+      }
+    else
+      {
+      enabled[0] = 0;
+      }
+    }
+}
diff --git a/src/main/java/org/distorted/objects/MovementMinx.java b/src/main/java/org/distorted/objects/MovementMinx.java
deleted file mode 100644
index 50226153..00000000
--- a/src/main/java/org/distorted/objects/MovementMinx.java
+++ /dev/null
@@ -1,303 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import org.distorted.library.type.Static3D;
-import static org.distorted.objects.TwistyMinx.C1;
-import static org.distorted.objects.TwistyMinx.C2;
-import static org.distorted.objects.TwistyMinx.LEN;
-import static org.distorted.objects.FactoryCubit.SIN54;
-import static org.distorted.objects.FactoryCubit.COS54;
-import static org.distorted.objects.TwistyObject.SQ5;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementMinx extends Movement
-{
-  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5)/3;
-  static final float DIST2D = (0.5f*SIN54/COS54)/3;
-
-  static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D( C2/LEN, C1/LEN, 0      ),
-           new Static3D( C2/LEN,-C1/LEN, 0      ),
-           new Static3D(-C2/LEN, C1/LEN, 0      ),
-           new Static3D(-C2/LEN,-C1/LEN, 0      ),
-           new Static3D( 0     , C2/LEN, C1/LEN ),
-           new Static3D( 0     , C2/LEN,-C1/LEN ),
-           new Static3D( 0     ,-C2/LEN, C1/LEN ),
-           new Static3D( 0     ,-C2/LEN,-C1/LEN ),
-           new Static3D( C1/LEN, 0     , C2/LEN ),
-           new Static3D( C1/LEN, 0     ,-C2/LEN ),
-           new Static3D(-C1/LEN, 0     , C2/LEN ),
-           new Static3D(-C1/LEN, 0     ,-C2/LEN )
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementMinx()
-    {
-    super(TwistyMinx.ROT_AXIS, FACE_AXIS, DIST3D, DIST2D);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int computeRowFromOffset(int face, int size, float offset)
-    {
-    return offset<DIST2D ? 0:2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float returnRotationFactor(int size, int row)
-    {
-    return 1.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return angle (in radians) that the line connecting the center C of the pentagonal face and the
-// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
-
-  private float returnAngle(int face)
-    {
-    switch(face)
-      {
-      case  0:
-      case  2:
-      case  6:
-      case  7: return 0.0f;
-      case  1:
-      case  3:
-      case  4:
-      case  5: return (float)(36*Math.PI/180);
-      case  9:
-      case 10: return (float)(54*Math.PI/180);
-      case  8:
-      case 11: return (float)(18*Math.PI/180);
-      }
-
-    return 0.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
-// from the center of the coordinate system to P.
-// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
-// P' and going in the direction of V.
-// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
-// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
-// directly upwards, is 'point' on the left or the right of it?
-
-  private boolean isOnTheLeft(float[] point, float distance, float angle)
-    {
-    float sin = (float)Math.sin(angle);
-    float cos = (float)Math.cos(angle);
-
-    float vx = point[0] + sin*distance;
-    float vy = point[1] - cos*distance;
-
-    return vx*sin < vy*cos;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
-// 'point' is inside the pentagon - or 0 otherwise.
-// The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
-// This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
-// pentagon.
-// Distance from the center to a vertex of the pentagon = 1/(6*COS54)
-
-  private int returnPartOfThePentagon(float[] point, int face)
-    {
-    float angle = returnAngle(face);
-    float A = (float)(Math.PI/5);
-
-    for(int i=0; i<5; i++)
-      {
-      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
-      }
-
-    if( isOnTheLeft(point, 0, 2.5f*A-angle) )
-      {
-      if( isOnTheLeft(point, 0, 3.5f*A-angle) )
-        {
-        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
-        }
-      else return 1;
-      }
-    else
-      {
-      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
-        {
-        return 3;
-        }
-      else
-        {
-        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean isInsideFace(int face, float[] p)
-    {
-    return returnPartOfThePentagon(p,face) > 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int part = returnPartOfThePentagon(touchPoint,face);
-
-    if( part>0 )
-      {
-      enabled[0] = 2;
-
-      switch(face)
-        {
-        case  0:  switch(part)
-                    {
-                    case 1: enabled[1]=2; enabled[2]=3; break;
-                    case 2: enabled[1]=3; enabled[2]=5; break;
-                    case 3: enabled[1]=5; enabled[2]=1; break;
-                    case 4: enabled[1]=1; enabled[2]=4; break;
-                    case 5: enabled[1]=4; enabled[2]=2; break;
-                    }
-                  break;
-
-        case  1:  switch(part)
-                    {
-                    case 1: enabled[1]=0; enabled[2]=5; break;
-                    case 2: enabled[1]=5; enabled[2]=2; break;
-                    case 3: enabled[1]=2; enabled[2]=3; break;
-                    case 4: enabled[1]=3; enabled[2]=4; break;
-                    case 5: enabled[1]=4; enabled[2]=0; break;
-                    }
-                  break;
-
-        case  2:  switch(part)
-                    {
-                    case 1: enabled[1]=3; enabled[2]=2; break;
-                    case 2: enabled[1]=2; enabled[2]=5; break;
-                    case 3: enabled[1]=5; enabled[2]=0; break;
-                    case 4: enabled[1]=0; enabled[2]=4; break;
-                    case 5: enabled[1]=4; enabled[2]=3; break;
-                    }
-                  break;
-
-        case  3:  switch(part)
-                    {
-                    case 1: enabled[1]=1; enabled[2]=5; break;
-                    case 2: enabled[1]=5; enabled[2]=3; break;
-                    case 3: enabled[1]=3; enabled[2]=2; break;
-                    case 4: enabled[1]=2; enabled[2]=4; break;
-                    case 5: enabled[1]=4; enabled[2]=1; break;
-                    }
-                  break;
-
-        case  4:  switch(part)
-                    {
-                    case 1: enabled[1]=3; enabled[2]=0; break;
-                    case 2: enabled[1]=0; enabled[2]=4; break;
-                    case 3: enabled[1]=4; enabled[2]=5; break;
-                    case 4: enabled[1]=5; enabled[2]=1; break;
-                    case 5: enabled[1]=1; enabled[2]=3; break;
-                    }
-                  break;
-
-        case  5:  switch(part)
-                    {
-                    case 1: enabled[1]=2; enabled[2]=1; break;
-                    case 2: enabled[1]=1; enabled[2]=4; break;
-                    case 3: enabled[1]=4; enabled[2]=5; break;
-                    case 4: enabled[1]=5; enabled[2]=0; break;
-                    case 5: enabled[1]=0; enabled[2]=2; break;
-                    }
-                  break;
-
-        case  6:  switch(part)
-                    {
-                    case 1: enabled[1]=5; enabled[2]=4; break;
-                    case 2: enabled[1]=4; enabled[2]=1; break;
-                    case 3: enabled[1]=1; enabled[2]=2; break;
-                    case 4: enabled[1]=2; enabled[2]=0; break;
-                    case 5: enabled[1]=0; enabled[2]=5; break;
-                    }
-                  break;
-
-        case  7:  switch(part)
-                    {
-                    case 1: enabled[1]=5; enabled[2]=4; break;
-                    case 2: enabled[1]=4; enabled[2]=0; break;
-                    case 3: enabled[1]=0; enabled[2]=3; break;
-                    case 4: enabled[1]=3; enabled[2]=1; break;
-                    case 5: enabled[1]=1; enabled[2]=5; break;
-                    }
-                  break;
-
-        case  8: switch(part)
-                    {
-                    case 1: enabled[1]=2; enabled[2]=0; break;
-                    case 2: enabled[1]=0; enabled[2]=1; break;
-                    case 3: enabled[1]=1; enabled[2]=3; break;
-                    case 4: enabled[1]=3; enabled[2]=5; break;
-                    case 5: enabled[1]=5; enabled[2]=2; break;
-                    }
-                  break;
-
-        case  9:  switch(part)
-                    {
-                    case 1: enabled[1]=3; enabled[2]=4; break;
-                    case 2: enabled[1]=4; enabled[2]=2; break;
-                    case 3: enabled[1]=2; enabled[2]=1; break;
-                    case 4: enabled[1]=1; enabled[2]=0; break;
-                    case 5: enabled[1]=0; enabled[2]=3; break;
-                    }
-                  break;
-
-        case 10:  switch(part)
-                    {
-                    case 1: enabled[1]=2; enabled[2]=4; break;
-                    case 2: enabled[1]=4; enabled[2]=3; break;
-                    case 3: enabled[1]=3; enabled[2]=0; break;
-                    case 4: enabled[1]=0; enabled[2]=1; break;
-                    case 5: enabled[1]=1; enabled[2]=2; break;
-                    }
-                  break;
-
-        case 11:  switch(part)
-                    {
-                    case 1: enabled[1]=3; enabled[2]=1; break;
-                    case 2: enabled[1]=1; enabled[2]=0; break;
-                    case 3: enabled[1]=0; enabled[2]=2; break;
-                    case 4: enabled[1]=2; enabled[2]=5; break;
-                    case 5: enabled[1]=5; enabled[2]=3; break;
-                    }
-                  break;
-        }
-      }
-    else
-      {
-      enabled[0] = 0;
-      }
-    }
-}
diff --git a/src/main/java/org/distorted/objects/ObjectList.java b/src/main/java/org/distorted/objects/ObjectList.java
index fffc2264..fac6fa53 100644
--- a/src/main/java/org/distorted/objects/ObjectList.java
+++ b/src/main/java/org/distorted/objects/ObjectList.java
@@ -132,10 +132,10 @@ public enum ObjectList
 
   KILO (
          new int[][] {
-                       {3 , 18, R.raw.minx3, R.drawable.ui_small_minx3, R.drawable.ui_medium_minx3, R.drawable.ui_big_minx3, R.drawable.ui_huge_minx3} ,
+                       {3 , 18, R.raw.kilo3, R.drawable.ui_small_kilo3, R.drawable.ui_medium_kilo3, R.drawable.ui_big_kilo3, R.drawable.ui_huge_kilo3} ,
                      },
-         TwistyMinx.class,
-         new MovementMinx(),
+         TwistyKilominx.class,
+         new MovementKilominx(),
          4
        ),
   ;
@@ -520,7 +520,7 @@ public enum ObjectList
       case  7: return new TwistySkewb     (size, quat, texture, mesh, effects, moves, res, scrWidth);
       case  8: return new TwistyIvy       (size, quat, texture, mesh, effects, moves, res, scrWidth);
       case  9: return new TwistyRex       (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 10: return new TwistyMinx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
+      case 10: return new TwistyKilominx  (size, quat, texture, mesh, effects, moves, res, scrWidth);
       }
 
     return null;
diff --git a/src/main/java/org/distorted/objects/TwistyKilominx.java b/src/main/java/org/distorted/objects/TwistyKilominx.java
new file mode 100644
index 00000000..07849f63
--- /dev/null
+++ b/src/main/java/org/distorted/objects/TwistyKilominx.java
@@ -0,0 +1,443 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.objects;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+import org.distorted.library.effect.MatrixEffectQuaternion;
+import org.distorted.library.main.DistortedEffects;
+import org.distorted.library.main.DistortedTexture;
+import org.distorted.library.mesh.MeshBase;
+import org.distorted.library.mesh.MeshSquare;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+import org.distorted.main.R;
+
+import java.util.Random;
+
+import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class TwistyKilominx extends TwistyObject
+{
+  private static final int FACES_PER_CUBIT =6;
+
+  static final float C0 = (SQ5-1)/4;                       // cos(72 deg)
+  static final float C1 = (SQ5+1)/4;                       // cos(36 deg)
+  static final float C2 = (SQ5+3)/4;
+  static final float LEN= (float)(Math.sqrt(1.25f+0.5f*SQ5));
+
+  // the six rotation axis of a Kilominx. Must be normalized.
+  static final Static3D[] ROT_AXIS = new Static3D[]
+         {
+           new Static3D( C2/LEN, C1/LEN, 0      ),
+           new Static3D(-C2/LEN, C1/LEN, 0      ),
+           new Static3D( 0     , C2/LEN, C1/LEN ),
+           new Static3D( 0     ,-C2/LEN, C1/LEN ),
+           new Static3D( C1/LEN, 0     , C2/LEN ),
+           new Static3D( C1/LEN, 0     ,-C2/LEN )
+         };
+
+  private static final int MINX_LGREEN = 0xff53aa00;
+  private static final int MINX_PINK   = 0xfffd7ab7;
+  private static final int MINX_SANDY  = 0xffefd48b;
+  private static final int MINX_LBLUE  = 0xff00a2d7;
+  private static final int MINX_ORANGE = 0xffff6200;
+  private static final int MINX_VIOLET = 0xff7d59a4;
+  private static final int MINX_DGREEN = 0xff007a47;
+  private static final int MINX_DRED   = 0xffbd0000;
+  private static final int MINX_DBLUE  = 0xff1a29b2;
+  private static final int MINX_DYELLOW= 0xffffc400;
+  private static final int MINX_WHITE  = 0xffffffff;
+  private static final int MINX_GREY   = 0xff727c7b;
+
+  private static final int[] FACE_COLORS = new int[]
+         {
+           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
+           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
+           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
+         };
+
+  // All 60 legal rotation quats of a Kilominx
+  private static final Static4D[] QUATS = new Static4D[]
+         {
+           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
+           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
+           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
+           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
+
+           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
+           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
+           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
+           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
+           new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
+           new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
+           new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
+           new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
+
+           new Static4D(  0.5f,    C1,    C0,  0.0f ),
+           new Static4D(  0.5f,    C1,   -C0,  0.0f ),
+           new Static4D(  0.5f,   -C1,    C0,  0.0f ),
+           new Static4D(  0.5f,   -C1,   -C0,  0.0f ),
+           new Static4D(    C0,  0.5f,    C1,  0.0f ),
+           new Static4D(    C0,  0.5f,   -C1,  0.0f ),
+           new Static4D(   -C0,  0.5f,    C1,  0.0f ),
+           new Static4D(   -C0,  0.5f,   -C1,  0.0f ),
+           new Static4D(    C1,    C0,  0.5f,  0.0f ),
+           new Static4D(    C1,   -C0,  0.5f,  0.0f ),
+           new Static4D(   -C1,    C0,  0.5f,  0.0f ),
+           new Static4D(   -C1,   -C0,  0.5f,  0.0f ),
+
+           new Static4D(  0.0f,    C0,    C1,  0.5f ),
+           new Static4D(  0.0f,    C0,   -C1,  0.5f ),
+           new Static4D(  0.0f,   -C0,    C1,  0.5f ),
+           new Static4D(  0.0f,   -C0,   -C1,  0.5f ),
+           new Static4D(    C0,    C1,  0.0f,  0.5f ),
+           new Static4D(    C0,   -C1,  0.0f,  0.5f ),
+           new Static4D(   -C0,    C1,  0.0f,  0.5f ),
+           new Static4D(   -C0,   -C1,  0.0f,  0.5f ),
+           new Static4D(    C1,  0.0f,    C0,  0.5f ),
+           new Static4D(    C1,  0.0f,   -C0,  0.5f ),
+           new Static4D(   -C1,  0.0f,    C0,  0.5f ),
+           new Static4D(   -C1,  0.0f,   -C0,  0.5f ),
+
+           new Static4D(  0.0f,    C1,  0.5f,    C0 ),
+           new Static4D(  0.0f,    C1, -0.5f,    C0 ),
+           new Static4D(  0.0f,   -C1,  0.5f,    C0 ),
+           new Static4D(  0.0f,   -C1, -0.5f,    C0 ),
+           new Static4D(  0.5f,  0.0f,    C1,    C0 ),
+           new Static4D(  0.5f,  0.0f,   -C1,    C0 ),
+           new Static4D( -0.5f,  0.0f,    C1,    C0 ),
+           new Static4D( -0.5f,  0.0f,   -C1,    C0 ),
+           new Static4D(    C1,  0.5f,  0.0f,    C0 ),
+           new Static4D(    C1, -0.5f,  0.0f,    C0 ),
+           new Static4D(   -C1,  0.5f,  0.0f,    C0 ),
+           new Static4D(   -C1, -0.5f,  0.0f,    C0 ),
+
+           new Static4D(  0.0f,  0.5f,    C0,    C1 ),
+           new Static4D(  0.0f,  0.5f,   -C0,    C1 ),
+           new Static4D(  0.0f, -0.5f,    C0,    C1 ),
+           new Static4D(  0.0f, -0.5f,   -C0,    C1 ),
+           new Static4D(  0.5f,    C0,  0.0f,    C1 ),
+           new Static4D(  0.5f,   -C0,  0.0f,    C1 ),
+           new Static4D( -0.5f,    C0,  0.0f,    C1 ),
+           new Static4D( -0.5f,   -C0,  0.0f,    C1 ),
+           new Static4D(    C0,  0.0f,  0.5f,    C1 ),
+           new Static4D(    C0,  0.0f, -0.5f,    C1 ),
+           new Static4D(   -C0,  0.0f,  0.5f,    C1 ),
+           new Static4D(   -C0,  0.0f, -0.5f,    C1 ),
+         };
+
+  private static final int[][] mFaceMap =
+         {
+           {  0, 1, 8, 12,12,12 },
+           {  6, 5,10, 12,12,12 },
+           {  1, 0,11, 12,12,12 },
+           {  5, 6, 3, 12,12,12 },
+           {  0, 9, 4, 12,12,12 },
+           {  5, 4, 9, 12,12,12 },
+           {  7, 1, 2, 12,12,12 },
+           {  2, 6, 7, 12,12,12 },
+           { 10, 9, 8, 12,12,12 },
+           {  4, 3,11, 12,12,12 },
+           {  7,10, 8, 12,12,12 },
+           {  3, 2,11, 12,12,12 },
+           {  0, 8, 9, 12,12,12 },
+           {  9,10, 5, 12,12,12 },
+           {  0, 4,11, 12,12,12 },
+           {  4, 5, 3, 12,12,12 },
+           {  1, 7, 8, 12,12,12 },
+           {  7, 6,10, 12,12,12 },
+           {  2, 1,11, 12,12,12 },
+           {  6, 2, 3, 12,12,12 },
+         };
+
+  private static MeshBase mMesh;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  TwistyKilominx(int size, Static4D quat, DistortedTexture texture,
+                 MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
+    {
+    super(size, size, 30, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  float getScreenRatio()
+    {
+    return 0.9f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  Static4D[] getQuats()
+    {
+    return QUATS;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getNumFaces()
+    {
+    return FACE_COLORS.length;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean shouldResetTextureMaps()
+    {
+    return false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getNumStickerTypes()
+    {
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  float[] getCuts(int numLayers)
+    {
+    return new float[] { -0.5f , 0.5f };
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getNumCubitFaces()
+    {
+    return FACES_PER_CUBIT;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  Static3D[] getCubitPositions(int numLayers)
+    {
+    final Static3D[] CENTERS = new Static3D[20];
+
+    CENTERS[ 0] = new Static3D( 0.0f, 0.5f,   C2);
+    CENTERS[ 1] = new Static3D( 0.0f, 0.5f,  -C2);
+    CENTERS[ 2] = new Static3D( 0.0f,-0.5f,   C2);
+    CENTERS[ 3] = new Static3D( 0.0f,-0.5f,  -C2);
+    CENTERS[ 4] = new Static3D(   C2, 0.0f, 0.5f);
+    CENTERS[ 5] = new Static3D(   C2, 0.0f,-0.5f);
+    CENTERS[ 6] = new Static3D(  -C2, 0.0f, 0.5f);
+    CENTERS[ 7] = new Static3D(  -C2, 0.0f,-0.5f);
+    CENTERS[ 8] = new Static3D( 0.5f,   C2, 0.0f);
+    CENTERS[ 9] = new Static3D( 0.5f,  -C2, 0.0f);
+    CENTERS[10] = new Static3D(-0.5f,   C2, 0.0f);
+    CENTERS[11] = new Static3D(-0.5f,  -C2, 0.0f);
+    CENTERS[12] = new Static3D(   C1,   C1,   C1);
+    CENTERS[13] = new Static3D(   C1,   C1,  -C1);
+    CENTERS[14] = new Static3D(   C1,  -C1,   C1);
+    CENTERS[15] = new Static3D(   C1,  -C1,  -C1);
+    CENTERS[16] = new Static3D(  -C1,   C1,   C1);
+    CENTERS[17] = new Static3D(  -C1,   C1,  -C1);
+    CENTERS[18] = new Static3D(  -C1,  -C1,   C1);
+    CENTERS[19] = new Static3D(  -C1,  -C1,  -C1);
+
+    return CENTERS;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getQuat(int cubit)
+    {
+    switch(cubit)
+      {
+      case  0: return 0;
+      case  1: return 2;
+      case  2: return 3;
+      case  3: return 1;
+      case  4: return 40;
+      case  5: return 31;
+      case  6: return 41;
+      case  7: return 30;
+      case  8: return 39;
+      case  9: return 35;
+      case 10: return 36;
+      case 11: return 34;
+      case 12: return 56;
+      case 13: return 32;
+      case 14: return 43;
+      case 15: return 21;
+      case 16: return 48;
+      case 17: return 28;
+      case 18: return 42;
+      case 19: return 23;
+      }
+
+    return 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createCubitMesh(int cubit)
+    {
+    if( mMesh==null ) mMesh = FactoryCubit.getInstance().createMinxCornerMesh();
+    MeshBase mesh = mMesh.copy(true);
+
+    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
+    mesh.apply(quat,0xffffffff,0);
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getFaceColor(int cubit, int cubitface, int numLayers)
+    {
+    return mFaceMap[cubit][cubitface];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+    {
+    float S = 0.07f;
+    float R = 0.09f;
+
+    float A = 0.86f;
+    float X1= (SQ5+1)/8;
+    float Y1= (float)(Math.sqrt(2+0.4f*SQ5)/4);
+    float Y2= Y1 - (float)(Math.sqrt(10-2*SQ5)/8);
+
+    float[] vertices = { -X1, Y2, 0, -A*Y1, X1, Y2, 0, Y1 };
+
+    FactorySticker factory = FactorySticker.getInstance();
+    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
+
+    float MID = TEXTURE_HEIGHT*0.5f;
+    float WID = TEXTURE_HEIGHT*0.1f;
+    float HEI = TEXTURE_HEIGHT*(0.47f+Y1);
+    canvas.drawLine(left+MID-WID,top+HEI,left+MID+WID,top+HEI,paint);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  float returnMultiplier()
+    {
+    return 2.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  float[] getRowChances()
+    {
+    return new float[] { 0.5f, 0.5f, 1.0f };
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+
+  public Static3D[] getRotationAxis()
+    {
+    return ROT_AXIS;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getBasicAngle()
+    {
+    return 5;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
+    {
+    int numAxis = ROTATION_AXIS.length;
+
+    if( oldRotAxis == START_AXIS )
+      {
+      return rnd.nextInt(numAxis);
+      }
+    else
+      {
+      int newVector = rnd.nextInt(numAxis-1);
+      return (newVector>=oldRotAxis ? newVector+1 : newVector);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
+    {
+    float rowFloat = rnd.nextFloat();
+
+    for(int row=0; row<mRowChances.length; row++)
+      {
+      if( rowFloat<=mRowChances[row] ) return row;
+      }
+
+    return 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// The Kilominx is solved if and only if:
+//
+// all cubits are rotated with the same quat.
+
+  public boolean isSolved()
+    {
+    int q = CUBITS[0].mQuatIndex;
+
+    for(int i=0; i<NUM_CUBITS; i++)
+      {
+      if( CUBITS[i].mQuatIndex != q ) return false;
+      }
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// only needed for solvers - there are no Kilominx solvers ATM)
+
+  public String retObjectString()
+    {
+    return "";
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getObjectName(int numLayers)
+    {
+    return R.string.minx2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getInventor(int numLayers)
+    {
+    return R.string.minx2_inventor;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getComplexity(int numLayers)
+    {
+    return 3;
+    }
+}
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
deleted file mode 100644
index 48912965..00000000
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ /dev/null
@@ -1,443 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-
-import org.distorted.library.effect.MatrixEffectQuaternion;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-
-import java.util.Random;
-
-import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyMinx extends TwistyObject
-{
-  private static final int FACES_PER_CUBIT =6;
-
-  static final float C0 = (SQ5-1)/4;                       // cos(72 deg)
-  static final float C1 = (SQ5+1)/4;                       // cos(36 deg)
-  static final float C2 = (SQ5+3)/4;
-  static final float LEN= (float)(Math.sqrt(1.25f+0.5f*SQ5));
-
-  // the six rotation axis of a Kilominx. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D( C2/LEN, C1/LEN, 0      ),
-           new Static3D(-C2/LEN, C1/LEN, 0      ),
-           new Static3D( 0     , C2/LEN, C1/LEN ),
-           new Static3D( 0     ,-C2/LEN, C1/LEN ),
-           new Static3D( C1/LEN, 0     , C2/LEN ),
-           new Static3D( C1/LEN, 0     ,-C2/LEN )
-         };
-
-  private static final int MINX_LGREEN = 0xff53aa00;
-  private static final int MINX_PINK   = 0xfffd7ab7;
-  private static final int MINX_SANDY  = 0xffefd48b;
-  private static final int MINX_LBLUE  = 0xff00a2d7;
-  private static final int MINX_ORANGE = 0xffff6200;
-  private static final int MINX_VIOLET = 0xff7d59a4;
-  private static final int MINX_DGREEN = 0xff007a47;
-  private static final int MINX_DRED   = 0xffbd0000;
-  private static final int MINX_DBLUE  = 0xff1a29b2;
-  private static final int MINX_DYELLOW= 0xffffc400;
-  private static final int MINX_WHITE  = 0xffffffff;
-  private static final int MINX_GREY   = 0xff727c7b;
-
-  private static final int[] FACE_COLORS = new int[]
-         {
-           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
-           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
-           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
-         };
-
-  // All 60 legal rotation quats of a Kilominx
-  private static final Static4D[] QUATS = new Static4D[]
-         {
-           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-           new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
-           new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
-           new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
-           new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
-
-           new Static4D(  0.5f,    C1,    C0,  0.0f ),
-           new Static4D(  0.5f,    C1,   -C0,  0.0f ),
-           new Static4D(  0.5f,   -C1,    C0,  0.0f ),
-           new Static4D(  0.5f,   -C1,   -C0,  0.0f ),
-           new Static4D(    C0,  0.5f,    C1,  0.0f ),
-           new Static4D(    C0,  0.5f,   -C1,  0.0f ),
-           new Static4D(   -C0,  0.5f,    C1,  0.0f ),
-           new Static4D(   -C0,  0.5f,   -C1,  0.0f ),
-           new Static4D(    C1,    C0,  0.5f,  0.0f ),
-           new Static4D(    C1,   -C0,  0.5f,  0.0f ),
-           new Static4D(   -C1,    C0,  0.5f,  0.0f ),
-           new Static4D(   -C1,   -C0,  0.5f,  0.0f ),
-
-           new Static4D(  0.0f,    C0,    C1,  0.5f ),
-           new Static4D(  0.0f,    C0,   -C1,  0.5f ),
-           new Static4D(  0.0f,   -C0,    C1,  0.5f ),
-           new Static4D(  0.0f,   -C0,   -C1,  0.5f ),
-           new Static4D(    C0,    C1,  0.0f,  0.5f ),
-           new Static4D(    C0,   -C1,  0.0f,  0.5f ),
-           new Static4D(   -C0,    C1,  0.0f,  0.5f ),
-           new Static4D(   -C0,   -C1,  0.0f,  0.5f ),
-           new Static4D(    C1,  0.0f,    C0,  0.5f ),
-           new Static4D(    C1,  0.0f,   -C0,  0.5f ),
-           new Static4D(   -C1,  0.0f,    C0,  0.5f ),
-           new Static4D(   -C1,  0.0f,   -C0,  0.5f ),
-
-           new Static4D(  0.0f,    C1,  0.5f,    C0 ),
-           new Static4D(  0.0f,    C1, -0.5f,    C0 ),
-           new Static4D(  0.0f,   -C1,  0.5f,    C0 ),
-           new Static4D(  0.0f,   -C1, -0.5f,    C0 ),
-           new Static4D(  0.5f,  0.0f,    C1,    C0 ),
-           new Static4D(  0.5f,  0.0f,   -C1,    C0 ),
-           new Static4D( -0.5f,  0.0f,    C1,    C0 ),
-           new Static4D( -0.5f,  0.0f,   -C1,    C0 ),
-           new Static4D(    C1,  0.5f,  0.0f,    C0 ),
-           new Static4D(    C1, -0.5f,  0.0f,    C0 ),
-           new Static4D(   -C1,  0.5f,  0.0f,    C0 ),
-           new Static4D(   -C1, -0.5f,  0.0f,    C0 ),
-
-           new Static4D(  0.0f,  0.5f,    C0,    C1 ),
-           new Static4D(  0.0f,  0.5f,   -C0,    C1 ),
-           new Static4D(  0.0f, -0.5f,    C0,    C1 ),
-           new Static4D(  0.0f, -0.5f,   -C0,    C1 ),
-           new Static4D(  0.5f,    C0,  0.0f,    C1 ),
-           new Static4D(  0.5f,   -C0,  0.0f,    C1 ),
-           new Static4D( -0.5f,    C0,  0.0f,    C1 ),
-           new Static4D( -0.5f,   -C0,  0.0f,    C1 ),
-           new Static4D(    C0,  0.0f,  0.5f,    C1 ),
-           new Static4D(    C0,  0.0f, -0.5f,    C1 ),
-           new Static4D(   -C0,  0.0f,  0.5f,    C1 ),
-           new Static4D(   -C0,  0.0f, -0.5f,    C1 ),
-         };
-
-  private static final int[][] mFaceMap =
-         {
-           {  0, 1, 8, 12,12,12 },
-           {  6, 5,10, 12,12,12 },
-           {  1, 0,11, 12,12,12 },
-           {  5, 6, 3, 12,12,12 },
-           {  0, 9, 4, 12,12,12 },
-           {  5, 4, 9, 12,12,12 },
-           {  7, 1, 2, 12,12,12 },
-           {  2, 6, 7, 12,12,12 },
-           { 10, 9, 8, 12,12,12 },
-           {  4, 3,11, 12,12,12 },
-           {  7,10, 8, 12,12,12 },
-           {  3, 2,11, 12,12,12 },
-           {  0, 8, 9, 12,12,12 },
-           {  9,10, 5, 12,12,12 },
-           {  0, 4,11, 12,12,12 },
-           {  4, 5, 3, 12,12,12 },
-           {  1, 7, 8, 12,12,12 },
-           {  7, 6,10, 12,12,12 },
-           {  2, 1,11, 12,12,12 },
-           {  6, 2, 3, 12,12,12 },
-         };
-
-  private static MeshBase mMesh;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyMinx(int size, Static4D quat, DistortedTexture texture,
-             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, 30, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float getScreenRatio()
-    {
-    return 0.9f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Static4D[] getQuats()
-    {
-    return QUATS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaces()
-    {
-    return FACE_COLORS.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean shouldResetTextureMaps()
-    {
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumStickerTypes()
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[] getCuts(int numLayers)
-    {
-    return new float[] { -0.5f , 0.5f };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumCubitFaces()
-    {
-    return FACES_PER_CUBIT;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Static3D[] getCubitPositions(int numLayers)
-    {
-    final Static3D[] CENTERS = new Static3D[20];
-
-    CENTERS[ 0] = new Static3D( 0.0f, 0.5f,   C2);
-    CENTERS[ 1] = new Static3D( 0.0f, 0.5f,  -C2);
-    CENTERS[ 2] = new Static3D( 0.0f,-0.5f,   C2);
-    CENTERS[ 3] = new Static3D( 0.0f,-0.5f,  -C2);
-    CENTERS[ 4] = new Static3D(   C2, 0.0f, 0.5f);
-    CENTERS[ 5] = new Static3D(   C2, 0.0f,-0.5f);
-    CENTERS[ 6] = new Static3D(  -C2, 0.0f, 0.5f);
-    CENTERS[ 7] = new Static3D(  -C2, 0.0f,-0.5f);
-    CENTERS[ 8] = new Static3D( 0.5f,   C2, 0.0f);
-    CENTERS[ 9] = new Static3D( 0.5f,  -C2, 0.0f);
-    CENTERS[10] = new Static3D(-0.5f,   C2, 0.0f);
-    CENTERS[11] = new Static3D(-0.5f,  -C2, 0.0f);
-    CENTERS[12] = new Static3D(   C1,   C1,   C1);
-    CENTERS[13] = new Static3D(   C1,   C1,  -C1);
-    CENTERS[14] = new Static3D(   C1,  -C1,   C1);
-    CENTERS[15] = new Static3D(   C1,  -C1,  -C1);
-    CENTERS[16] = new Static3D(  -C1,   C1,   C1);
-    CENTERS[17] = new Static3D(  -C1,   C1,  -C1);
-    CENTERS[18] = new Static3D(  -C1,  -C1,   C1);
-    CENTERS[19] = new Static3D(  -C1,  -C1,  -C1);
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getQuat(int cubit)
-    {
-    switch(cubit)
-      {
-      case  0: return 0;
-      case  1: return 2;
-      case  2: return 3;
-      case  3: return 1;
-      case  4: return 40;
-      case  5: return 31;
-      case  6: return 41;
-      case  7: return 30;
-      case  8: return 39;
-      case  9: return 35;
-      case 10: return 36;
-      case 11: return 34;
-      case 12: return 56;
-      case 13: return 32;
-      case 14: return 43;
-      case 15: return 21;
-      case 16: return 48;
-      case 17: return 28;
-      case 18: return 42;
-      case 19: return 23;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MeshBase createCubitMesh(int cubit)
-    {
-    if( mMesh==null ) mMesh = FactoryCubit.getInstance().createMinxCornerMesh();
-    MeshBase mesh = mMesh.copy(true);
-
-    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
-    mesh.apply(quat,0xffffffff,0);
-
-    return mesh;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
-    {
-    float S = 0.07f;
-    float R = 0.09f;
-
-    float A = 0.86f;
-    float X1= (SQ5+1)/8;
-    float Y1= (float)(Math.sqrt(2+0.4f*SQ5)/4);
-    float Y2= Y1 - (float)(Math.sqrt(10-2*SQ5)/8);
-
-    float[] vertices = { -X1, Y2, 0, -A*Y1, X1, Y2, 0, Y1 };
-
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
-
-    float MID = TEXTURE_HEIGHT*0.5f;
-    float WID = TEXTURE_HEIGHT*0.1f;
-    float HEI = TEXTURE_HEIGHT*(0.47f+Y1);
-    canvas.drawLine(left+MID-WID,top+HEI,left+MID+WID,top+HEI,paint);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnMultiplier()
-    {
-    return 2.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[] getRowChances()
-    {
-    return new float[] { 0.5f, 0.5f, 1.0f };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getBasicAngle()
-    {
-    return 5;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
-    {
-    int numAxis = ROTATION_AXIS.length;
-
-    if( oldRotAxis == START_AXIS )
-      {
-      return rnd.nextInt(numAxis);
-      }
-    else
-      {
-      int newVector = rnd.nextInt(numAxis-1);
-      return (newVector>=oldRotAxis ? newVector+1 : newVector);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
-    {
-    float rowFloat = rnd.nextFloat();
-
-    for(int row=0; row<mRowChances.length; row++)
-      {
-      if( rowFloat<=mRowChances[row] ) return row;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// The Kilominx is solved if and only if:
-//
-// all cubits are rotated with the same quat.
-
-  public boolean isSolved()
-    {
-    int q = CUBITS[0].mQuatIndex;
-
-    for(int i=0; i<NUM_CUBITS; i++)
-      {
-      if( CUBITS[i].mQuatIndex != q ) return false;
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// only needed for solvers - there are no Kilominx solvers ATM)
-
-  public String retObjectString()
-    {
-    return "";
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.minx2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.minx2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 3;
-    }
-}
diff --git a/src/main/java/org/distorted/tutorial/TutorialList.java b/src/main/java/org/distorted/tutorial/TutorialList.java
index 37b7ae29..e80d6d71 100644
--- a/src/main/java/org/distorted/tutorial/TutorialList.java
+++ b/src/main/java/org/distorted/tutorial/TutorialList.java
@@ -86,7 +86,7 @@ public enum TutorialList
   PYRA4 ( ObjectList.PYRA, 4,
           new String[][] {
                           {"gb","tGQDqDcSa6U","How to Solve the Master Pyraminx","Z3"},
-                          {"es","74PIPm9-uPg","Resolver MASTER PYRAMINX 4x4","Cuby"},
+                          {"es","74PIPm9-uPg","Resolver Master Pyraminx 4x4","Cuby"},
                           {"ru","-F_xJAwkobU","Как собрать Мастер Пираминкс"," Алексей Ярыгин"},
                           {"fr","F3gzBs7uvmw","Tuto: résoudre le Master Pyraminx","Spaghetti Cubing"},
                           {"pl","EamwvhmHC7Q","4x4 (Master) Pyraminx PL","MrUk"},
@@ -114,7 +114,7 @@ public enum TutorialList
   DINO3 ( ObjectList.DINO, 3,
           new String[][] {
                           {"gb","puTJZqFBQwo","Dino Skewb Cube Tutorial","Bearded Cubing"},
-                          {"es","6o1Yo5iCxvI","Resolver CUBO DINO","Cuby"},
+                          {"es","6o1Yo5iCxvI","Resolver Cubo Dino","Cuby"},
                           {"ru","tWDrCtIv1_U","Как собрать Дино Куб","Алексей Ярыгин"},
                           {"fr","hNkpte7Mesc","Comment résoudre le Dino Cube","Valentino Cube"},
                           {"pl","o05DYu8UMio","Dino cube TUTORIAL PL","MrUk"},
@@ -124,7 +124,7 @@ public enum TutorialList
   REDI3 ( ObjectList.REDI, 3,
           new String[][] {
                           {"gb","Qn7TJED6O-4","How to Solve the MoYu Redi Cube","Z3"},
-                          {"es","g0M38Aotgac","Resolver REDI CUBE","Cuby"},
+                          {"es","g0M38Aotgac","Resolver Redi Cube","Cuby"},
                           {"ru","ip2wYwc0DMI","Как собрать Реди Куб?","Кубмаркет"},
                           {"fr","zw7UZcqqsgA","Comment résoudre le Redi Cube","ValentinoCube"},
                           {"pl","vxo3lXMsWQI","Jak ułożyć redi cube?","DJ rubiks"},
@@ -134,7 +134,7 @@ public enum TutorialList
   HELI3 ( ObjectList.HELI, 3,
           new String[][] {
                           {"gb","-suwJpd_PO8","Helicopter Cube Tutorial","Bearded Cubing"},
-                          {"es","DWG9n_YyGPA","Resolver HELICOPTER CUBE","Cuby"},
+                          {"es","DWG9n_YyGPA","Resolver Helicopter Cube","Cuby"},
                           {"ru","V4lJ3pg7Hio","Как собрать Куб Вертолет","Алексей Ярыгин"},
                           {"fr","Zk8zWBWD2Ow","Comment résoudre le Helicopter Cube","Julien"},
                           {"pl","zoBZame4gFo","Helicopter cube TUTORIAL PL","MrUk"},
@@ -155,7 +155,7 @@ public enum TutorialList
   SKEW3 ( ObjectList.SKEW, 3,
           new String[][] {
                           {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
-                          {"es","8TP6p63KQCA","MASTER SKEWB EN ESPAÑOL","jorlozCubes"},
+                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
                           {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
                           {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
                           {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
@@ -167,7 +167,7 @@ public enum TutorialList
   IVY2 ( ObjectList.IVY, 2,
           new String[][] {
                           {"gb","QMzeJobSu1M","How to Solve the Ivy Cube","Z3"},
-                          {"es","2-Gf2cmEJDs","Resolver IVY CUBE","Cuby"},
+                          {"es","2-Gf2cmEJDs","Resolver Ivy Cube","Cuby"},
                           {"ru","pbkfOCnnfsA","Как собрать Иви куб","Алексей Ярыгин"},
                           {"fr","mn7YTnYu3Uc","Comment résoudre le Ivy Cube","ValentinoCube"},
                           {"pl","8s_0VxNvFA8","Jak ułożyć ivy cube","DubiCube"},
@@ -177,7 +177,7 @@ public enum TutorialList
   REX3 ( ObjectList.REX, 3,
           new String[][] {
                           {"gb","noAQfWqlMbk","Rex Cube Tutorial","CrazyBadCuber"},
-                          {"es","Q90x9rjLJzw","Resolver CUBO REX","Cuby"},
+                          {"es","Q90x9rjLJzw","Resolver Cubo Rex","Cuby"},
                           {"ru","Dr9CLM6A3fU","Как собрать Рекс Куб","Алексей Ярыгин"},
                           {"fr","SvK1kf6c43c","Résolution du Rex Cube","Asthalis"},
                           {"pl","ffbFRnHglWY","Rex cube TUTORIAL PL","MrUk"},
@@ -187,7 +187,7 @@ public enum TutorialList
   KILO3( ObjectList.KILO, 3,
           new String[][] {
                           {"gb","grgGgUSxiQg","How to Solve the Kilominx","Z3"},
-                          {"es","g6WMYjkCLok","Resolver MEGAMINX 2x2","Cuby"},
+                          {"es","g6WMYjkCLok","Resolver Kilominx","Cuby"},
                           {"ru","gjaknjuZXPs","Киломинкс как собрать"," CUBES WORLD"},
                           {"fr","F7z6LztN-7A","Résoudre le Kilominx"," Twins Cuber"},
                           {"pl","tdWh8f8qpq4","Kilominx cube TUTORIAL PL","MrUK"},
diff --git a/src/main/res/drawable-nodpi/ui_big_kilo3.png b/src/main/res/drawable-nodpi/ui_big_kilo3.png
new file mode 100644
index 00000000..7e5779fd
Binary files /dev/null and b/src/main/res/drawable-nodpi/ui_big_kilo3.png differ
diff --git a/src/main/res/drawable-nodpi/ui_big_minx3.png b/src/main/res/drawable-nodpi/ui_big_minx3.png
deleted file mode 100644
index 7e5779fd..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_minx3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_kilo3.png b/src/main/res/drawable-nodpi/ui_huge_kilo3.png
new file mode 100644
index 00000000..7babb464
Binary files /dev/null and b/src/main/res/drawable-nodpi/ui_huge_kilo3.png differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_minx3.png b/src/main/res/drawable-nodpi/ui_huge_minx3.png
deleted file mode 100644
index 7babb464..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_minx3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_kilo3.png b/src/main/res/drawable-nodpi/ui_medium_kilo3.png
new file mode 100644
index 00000000..99ea4b3d
Binary files /dev/null and b/src/main/res/drawable-nodpi/ui_medium_kilo3.png differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_minx3.png b/src/main/res/drawable-nodpi/ui_medium_minx3.png
deleted file mode 100644
index 99ea4b3d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_minx3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_kilo3.png b/src/main/res/drawable-nodpi/ui_small_kilo3.png
new file mode 100644
index 00000000..5895fcb8
Binary files /dev/null and b/src/main/res/drawable-nodpi/ui_small_kilo3.png differ
diff --git a/src/main/res/drawable-nodpi/ui_small_minx3.png b/src/main/res/drawable-nodpi/ui_small_minx3.png
deleted file mode 100644
index 5895fcb8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_minx3.png and /dev/null differ
diff --git a/src/main/res/raw/kilo3.dmesh b/src/main/res/raw/kilo3.dmesh
new file mode 100644
index 00000000..1a729c34
Binary files /dev/null and b/src/main/res/raw/kilo3.dmesh differ
diff --git a/src/main/res/raw/minx3.dmesh b/src/main/res/raw/minx3.dmesh
deleted file mode 100644
index 1a729c34..00000000
Binary files a/src/main/res/raw/minx3.dmesh and /dev/null differ
