Project

General

Profile

Download (20.4 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistySkewb.java @ 79b60250

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.helpers.ObjectFaceShape;
31
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
32
import org.distorted.objectlib.main.ObjectType;
33
import org.distorted.objectlib.helpers.ObjectShape;
34
import org.distorted.objectlib.scrambling.ScrambleState;
35
import org.distorted.objectlib.main.ShapeHexahedron;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
public class TwistySkewb extends ShapeHexahedron
40
{
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
43
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
44
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
45
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
47
         };
48

    
49
  private ScrambleState[] mStates;
50
  private int[] mBasicAngle;
51
  private float[][] mCuts;
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  public TwistySkewb(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
56
    {
57
    super(numL, meshState, iconMode, 2*numL[0]-2, quat, move, scale, stream);
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  public ScrambleState[] getScrambleStates()
63
    {
64
    if( mStates==null )
65
      {
66
      int[] numLayers = getNumLayers();
67
      int numL = numLayers[0];
68

    
69
      int[] tmp = {0,-1,0, 0,1,0, numL-1,-1,0, numL-1,1,0 };
70

    
71
      mStates = new ScrambleState[]
72
        {
73
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
74
        };
75
      }
76

    
77
    return mStates;
78
    }
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

    
82
  private int getNumCorners()
83
    {
84
    return 8;
85
    }
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private int getNumEdges(int numLayers)
90
    {
91
    return (numLayers-2)*12;
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  private int getNumCentersPerFace(int numLayers)
97
    {
98
    return ((numLayers-2)*(numLayers-2) + (numLayers-1)*(numLayers-1));
99
    }
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

    
103
  public float[][] getCuts(int[] numLayers)
104
    {
105
    if( mCuts==null )
106
      {
107
      float[] c = numLayers[0]==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/6,+SQ3/6});
108
      mCuts = new float[][] {c,c,c,c};
109
      }
110

    
111
    return mCuts;
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

    
116
  public boolean[][] getLayerRotatable(int[] numLayers)
117
    {
118
    boolean[] tmp = numLayers[0]==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
119
    return new boolean[][] { tmp,tmp,tmp,tmp };
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  public int getTouchControlType()
125
    {
126
    return TC_HEXAHEDRON;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  public int getTouchControlSplit()
132
    {
133
    return TYPE_SPLIT_CORNER;
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  public int[][][] getEnabled()
139
    {
140
    return new int[][][]
141
      {
142
          {{0,1},{3,1},{2,3},{0,2}},
143
          {{2,3},{3,1},{0,1},{0,2}},
144
          {{1,2},{0,1},{0,3},{2,3}},
145
          {{1,2},{2,3},{0,3},{0,1}},
146
          {{0,3},{0,2},{1,2},{1,3}},
147
          {{1,2},{0,2},{0,3},{1,3}},
148
      };
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  public float[] getDist3D(int[] numLayers)
154
    {
155
    return TouchControlHexahedron.D3D;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  public Static3D[] getFaceAxis()
161
    {
162
    return TouchControlHexahedron.FACE_AXIS;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  public float[][] getCubitPositions(int[] numLayers)
168
    {
169
    int numL = numLayers[0];
170
    final float DIST_CORNER = numL-1;
171
    final float DIST_EDGE   = numL-1;
172
    final float DIST_CENTER = numL-1;
173

    
174
    final int numCorners = getNumCorners();
175
    final int numEdges   = getNumEdges(numL);
176
    final int numCenters = 6*getNumCentersPerFace(numL);
177

    
178
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
179

    
180
    /// CORNERS //////////////////////////////////////////////
181

    
182
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
183
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
184
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
185
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
186
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
187
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
188
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
189
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
190

    
191
    /// CENTERS //////////////////////////////////////////////
192

    
193
    int index=8;
194

    
195
    final float X= -1000.0f;
196
    final float Y= -1001.0f;
197

    
198
    final float[][]  centerTable =
199
        {
200
            {+DIST_CENTER,X,Y},
201
            {-DIST_CENTER,X,Y},
202
            {X,+DIST_CENTER,Y},
203
            {X,-DIST_CENTER,Y},
204
            {X,Y,+DIST_CENTER},
205
            {X,Y,-DIST_CENTER}
206
        };
207

    
208
    float x,y, cen0, cen1, cen2;
209

    
210
    for( float[] centers : centerTable )
211
      {
212
      x = 2-numL;
213

    
214
      for(int i=0; i<numL-1; i++, x+=2)
215
        {
216
        y = 2-numL;
217

    
218
        for(int j=0; j<numL-1; j++, y+=2, index++)
219
          {
220
               if( centers[0]==Y ) cen0 = y;
221
          else if( centers[0]==X ) cen0 = x;
222
          else                     cen0 = centers[0];
223

    
224
               if( centers[1]==Y ) cen1 = y;
225
          else if( centers[1]==X ) cen1 = x;
226
          else                     cen1 = centers[1];
227

    
228
               if( centers[2]==Y ) cen2 = y;
229
          else if( centers[2]==X ) cen2 = x;
230
          else                     cen2 = centers[2];
231

    
232
          CENTERS[index] = new float[] {cen0,cen1,cen2};
233
          }
234
        }
235

    
236
      x = 3-numL;
237

    
238
      for(int i=0; i<numL-2; i++, x+=2)
239
        {
240
        y = 3-numL;
241

    
242
        for(int j=0; j<numL-2; j++, y+=2, index++)
243
          {
244
               if( centers[0]==Y ) cen0 = y;
245
          else if( centers[0]==X ) cen0 = x;
246
          else                     cen0 = centers[0];
247

    
248
               if( centers[1]==Y ) cen1 = y;
249
          else if( centers[1]==X ) cen1 = x;
250
          else                     cen1 = centers[1];
251

    
252
               if( centers[2]==Y ) cen2 = y;
253
          else if( centers[2]==X ) cen2 = x;
254
          else                     cen2 = centers[2];
255

    
256
          CENTERS[index] = new float[] {cen0,cen1,cen2};
257
          }
258
        }
259
      }
260

    
261
    /// EDGES ///////////////////////////////////////////////
262

    
263
    final float[][]  edgeTable =
264
        {
265
            {0,+DIST_EDGE,+DIST_EDGE},
266
            {+DIST_EDGE,0,+DIST_EDGE},
267
            {0,-DIST_EDGE,+DIST_EDGE},
268
            {-DIST_EDGE,0,+DIST_EDGE},
269
            {+DIST_EDGE,+DIST_EDGE,0},
270
            {+DIST_EDGE,-DIST_EDGE,0},
271
            {-DIST_EDGE,-DIST_EDGE,0},
272
            {-DIST_EDGE,+DIST_EDGE,0},
273
            {0,+DIST_EDGE,-DIST_EDGE},
274
            {+DIST_EDGE,0,-DIST_EDGE},
275
            {0,-DIST_EDGE,-DIST_EDGE},
276
            {-DIST_EDGE,0,-DIST_EDGE}
277
        };
278

    
279
    for (float[] edges : edgeTable)
280
      {
281
      float c = 3-numL;
282

    
283
      for (int j=0; j<numL-2; j++, c+=2, index++)
284
        {
285
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
286
                                       edges[1]==0 ? c : edges[1] ,
287
                                       edges[2]==0 ? c : edges[2] };
288
        }
289
      }
290

    
291
    return CENTERS;
292
    }
293

    
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

    
296
  public Static4D getCubitQuats(int cubit, int[] numLayers)
297
    {
298
    int numL = numLayers[0];
299
    int numCorners = getNumCorners();
300
    int numCentersPerFace = getNumCentersPerFace(numL);
301
    int numCenters = 6*numCentersPerFace;
302

    
303
    if( cubit<numCorners )
304
      {
305
      switch(cubit)
306
        {
307
        case  0: return mObjectQuats[0];                   //  unit quat
308
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
309
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
310
        case  3: return mObjectQuats[9];                   // 180 along X
311
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
312
        case  5: return mObjectQuats[11];                  // 180 along Y
313
        case  6: return mObjectQuats[10];                   // 180 along Z
314
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
315
        }
316
      }
317
    else if( cubit<numCorners+numCenters )
318
      {
319
      int center = (cubit-numCorners)/numCentersPerFace;
320

    
321
      switch(center)
322
        {
323
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
324
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
325
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
326
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
327
        case 4: return mObjectQuats[0];                   //  unit quaternion
328
        case 5: return mObjectQuats[9];                   // 180 along X
329
        }
330
      }
331
    else
332
      {
333
      int edge = (cubit-numCorners-numCenters)/(numL-2);
334

    
335
      switch(edge)
336
        {
337
        case  0: return mObjectQuats[ 0];
338
        case  1: return mObjectQuats[ 2];
339
        case  2: return mObjectQuats[10];
340
        case  3: return mObjectQuats[ 8];
341
        case  4: return mObjectQuats[ 1];
342
        case  5: return mObjectQuats[ 4];
343
        case  6: return mObjectQuats[ 6];
344
        case  7: return mObjectQuats[ 7];
345
        case  8: return mObjectQuats[11];
346
        case  9: return mObjectQuats[ 5];
347
        case 10: return mObjectQuats[ 9];
348
        case 11: return mObjectQuats[ 3];
349
        }
350
      }
351

    
352
    return null;
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356

    
357
  public ObjectShape getObjectShape(int variant)
358
    {
359
    if( variant==0 )
360
      {
361
      float[][] vertices= { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
362
      int[][] indices   = { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
363
      return new ObjectShape(vertices, indices);
364
      }
365
    else if( variant==1 )
366
      {
367
      float[][] vertices= { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
368
      int[][] indices   = { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
369
      return new ObjectShape(vertices, indices);
370
      }
371
    else
372
      {
373
      float[][] vertices= { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
374
      int[][] indices   = { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
375
      return new ObjectShape(vertices, indices);
376
      }
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  public ObjectFaceShape getObjectFaceShape(int variant)
382
    {
383
    int numL = getNumLayers()[0];
384

    
385
    if( variant==0 )
386
      {
387
      int N = numL==2 ? 7:5;
388
      int E1= numL==2 ? 3:2;
389
      int E2= numL==2 ? 5:3;
390
      float height = isInIconMode() ? 0.001f : 0.02f;
391
      float[][] bands     = { {height,35,0.16f,0.7f,N,E1,E1}, {0.001f, 35,1.00f,0.0f,3,1,E2} };
392
      int[] bandIndices   = { 0,0,0,1,1,1 };
393
      float[][] corners   = { {0.05f,0.25f}, {0.05f,0.20f} };
394
      int[] cornerIndices = { 1,1,1,0,0 };
395
      float[][] centers   = { {-0.5f, -0.5f, -0.5f} };
396
      int[] centerIndices = { 0,0,0,-1,0 };
397
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
398
      }
399
    else if( variant==1 )
400
      {
401
      int N = numL==2 ? 7:6;
402
      int E = numL==2 ? 3:1;
403
      float height = isInIconMode() ? 0.001f : 0.04f;
404
      float[][] bands     = { {height,35,SQ2/8,0.9f,N,E,E}, {0.001f,35,1,0.0f,3,0,0} };
405
      int[] bandIndices   = { 0,1,1,1,1 };
406
      float[][] corners   = { {0.06f,0.15f} };
407
      int[] cornerIndices = { 0,0,0,0,0 };
408
      float[][] centers   = { {0,0,-0.4f} };
409
      int[] centerIndices = { 0,0,0,0,-1 };
410
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
411
      }
412
    else
413
      {
414
      int N = numL==2 ? 7:5;
415
      int E = numL==2 ? 5:2;
416
      float h1 = isInIconMode() ? 0.001f : 0.035f;
417
      float h2 = isInIconMode() ? 0.001f : 0.020f;
418
      float[][] bands     = { {h1,30,0.16f,0.8f,N,2,E}, {h2,45,0.16f,0.2f,3,1,2} };
419
      int[] bandIndices   = { 0,0,1,1 };
420
      float[][] corners   = { {0.07f,0.20f}, {0.02f,0.30f} };
421
      int[] cornerIndices = { 0,0,1,1 };
422
      float[][] centers   = { {0.0f, -0.5f, -0.5f} };
423
      int[] centerIndices = { 0,0,0,0 };
424
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
425
      }
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  public int getNumCubitVariants(int[] numLayers)
431
    {
432
    return numLayers[0]==2 ? 2:3;
433
    }
434

    
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

    
437
  public int getCubitVariant(int cubit, int[] numLayers)
438
    {
439
    return cubit<8 ? 0 : (cubit<8+6*getNumCentersPerFace(numLayers[0]) ? 1:2);
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public float getStickerRadius()
445
    {
446
    return 0.08f;
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450

    
451
  public float getStickerStroke()
452
    {
453
    float stroke = 0.08f;
454

    
455
    if( isInIconMode() )
456
      {
457
      int[] numLayers = getNumLayers();
458
      stroke *= (numLayers[0]==2 ? 2.0f : 2.7f);
459
      }
460

    
461
    return stroke;
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public float[][] getStickerAngles()
467
    {
468
    return null;
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472
// PUBLIC API
473

    
474
  public Static3D[] getRotationAxis()
475
    {
476
    return ROT_AXIS;
477
    }
478

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480

    
481
  public int[] getBasicAngles()
482
    {
483
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
484
    return mBasicAngle;
485
    }
486

    
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488

    
489
  public String getShortName()
490
    {
491
    switch(getNumLayers()[0])
492
      {
493
      case 2: return ObjectType.SKEW_2.name();
494
      case 3: return ObjectType.SKEW_3.name();
495
      }
496

    
497
    return ObjectType.SKEW_2.name();
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public long getSignature()
503
    {
504
    switch(getNumLayers()[0])
505
      {
506
      case 2: return ObjectType.SKEW_2.ordinal();
507
      case 3: return ObjectType.SKEW_3.ordinal();
508
      }
509

    
510
    return ObjectType.SKEW_2.ordinal();
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

    
515
  public String getObjectName()
516
    {
517
    switch(getNumLayers()[0])
518
      {
519
      case 2: return "Skewb";
520
      case 3: return "Master Skewb";
521
      }
522
    return "Skewb";
523
    }
524

    
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526

    
527
  public String getInventor()
528
    {
529
    switch(getNumLayers()[0])
530
      {
531
      case 2: return "Tony Durham";
532
      case 3: return "Katsuhiko Okamoto";
533
      }
534
    return "Tony Durham";
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int getYearOfInvention()
540
    {
541
    switch(getNumLayers()[0])
542
      {
543
      case 2: return 1982;
544
      case 3: return 2003;
545
      }
546
    return 1982;
547
    }
548

    
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550

    
551
  public int getComplexity()
552
    {
553
    switch(getNumLayers()[0])
554
      {
555
      case 2: return 1;
556
      case 3: return 3;
557
      }
558
    return 5;
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562

    
563
  public String[][] getTutorials()
564
    {
565
    int[] numLayers = getNumLayers();
566

    
567
    switch(numLayers[0])
568
      {
569
      case 2: return new String[][] {
570
                          {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
571
                          {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
572
                          {"ru","EICw3aqn6Bc","Как собрать Скьюб?","Алексей Ярыгин"},
573
                          {"fr","lR-GuIroh4k","Comment réussir le skewb","Rachma Nikov"},
574
                          {"de","7RX6D5pznOk","Skewb lösen","Pezcraft"},
575
                          {"pl","ofRu1fByNpk","Jak ułożyć: Skewb","DżoDżo"},
576
                          {"br","mNycauwshWs","Como resolver o Skewb","Pedro Filho"},
577
                          {"kr","5R3sU-_bMAI","SKEWB 초보 공식","iamzoone"},
578
                          {"vn","Db5mXuqgQP8","Tutorial N.5 - Skewb","Duy Thích Rubik"},
579
                     //   {"tw","8srf9xhsS9k","Skewb斜轉方塊解法","1hrBLD"},
580
                         };
581
      case 3: return new String[][] {
582
                          {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
583
                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
584
                          {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
585
                          {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
586
                          {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
587
                          {"ru","UnsvseFBXmo","часть 3: Как собрать мастер Скьюб","Иван Циков"},
588
                          {"fr","tYMoY4EOHVA","Résolution du Master Skewb","Asthalis"},
589
                          {"de","LSErzqGNElI","Master Skewb lösen","JamesKnopf"},
590
                          {"pl","Y7l3AYFvDJI","Master Skewb TUTORIAL PL","MrUk"},
591
                          {"kr","ycR-WmXJCG0","마스터 스큐브 3번째 해법","듀나메스 큐브 해법연구소"},
592
                          {"vn","uG8H0ZQTZgw","Tutorial N.35 - Master Skewb","Duy Thích Rubik"},
593
                         };
594
      }
595
    return null;
596
    }
597
}
(27-27/35)