Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIcosamate.java @ eeabbae3

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.objects;
11

    
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_ICOSAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14
import static org.distorted.objectlib.touchcontrol.TouchControlIcosahedron.*;
15

    
16
import org.distorted.library.type.Static3D;
17
import org.distorted.library.type.Static4D;
18
import org.distorted.objectlib.helpers.FactoryCubit;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectShape;
21
import org.distorted.objectlib.helpers.ObjectSignature;
22
import org.distorted.objectlib.helpers.ObjectVertexEffects;
23
import org.distorted.objectlib.main.InitAssets;
24
import org.distorted.objectlib.main.InitData;
25
import org.distorted.objectlib.main.ObjectSignatures;
26
import org.distorted.objectlib.main.ObjectType;
27
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
28
import org.distorted.objectlib.shape.ShapeIcosahedron;
29
import org.distorted.objectlib.touchcontrol.TouchControlIcosahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class TwistyIcosamate extends ShapeIcosahedron
34
{
35
  static final Static3D[] ROT_AXIS = new Static3D[]
36
         {
37
           new Static3D(                   0,                   1,                   0),
38
           new Static3D(                   0, VEC[1][1]/VEC[0][1], VEC[1][2]/VEC[0][1]),
39
           new Static3D( VEC[2][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[2][2]/VEC[0][1]),
40
           new Static3D( VEC[3][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[3][2]/VEC[0][1]),
41
           new Static3D(-VEC[3][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[3][2]/VEC[0][1]),
42
           new Static3D(-VEC[2][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[2][2]/VEC[0][1])
43
         };
44

    
45
  private int[][] mEdges;
46
  private int[][] mBasicAngle;
47
  private float[][] mCuts;
48
  private float[][] mPosition;
49
  private int[] mQuatIndex;
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

    
53
  public TwistyIcosamate(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
54
    {
55
    super(meshState, iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
56
    }
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
  @Override
61
  public int getInternalColor()
62
    {
63
    return 0xff222222;
64
    }
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  public int[][] getScrambleEdges()
69
    {
70
    if( mEdges==null )
71
      {
72
      int[][] basicAngle = getBasicAngles();
73
      mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(basicAngle);
74
      }
75

    
76
    return mEdges;
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
  public float[][] getCuts(int[] numLayers)
82
    {
83
    if( mCuts==null )
84
      {
85
      int nL = numLayers[0];
86
      float[] cut = new float[nL-1];
87
      for(int i=0; i<nL-1; i++) cut[i] = VEC[1][1]*(2*i+2-nL);
88
      mCuts = new float[][] { cut,cut,cut,cut,cut,cut };
89
      }
90

    
91
    return mCuts;
92
    }
93

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

    
96
  public boolean[][] getLayerRotatable(int[] numLayers)
97
    {
98
    int nL = numLayers[0];
99
    boolean[] tmp = new boolean[nL];
100
    for(int i=0; i<nL; i++) tmp[i] = true;
101
    return new boolean[][] { tmp,tmp,tmp,tmp,tmp,tmp };
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  public int getTouchControlType()
107
    {
108
    return TC_ICOSAHEDRON;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  public int getTouchControlSplit()
114
    {
115
    return TYPE_NOT_SPLIT;
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  public int[][][] getEnabled()
121
    {
122
    return new int[][][]
123
      {
124
          {{3,4,5}}, {{1,4,5}}, {{1,2,5}}, {{1,2,3}}, {{2,3,4}},
125
          {{0,2,5}}, {{0,1,3}}, {{0,2,4}}, {{0,3,5}}, {{0,1,4}},
126
          {{0,2,5}}, {{0,1,3}}, {{0,2,4}}, {{0,3,5}}, {{0,1,4}},
127
          {{3,4,5}}, {{1,4,5}}, {{1,2,5}}, {{1,2,3}}, {{2,3,4}},
128
      };
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public float[] getDist3D(int[] numLayers)
134
    {
135
    return TouchControlIcosahedron.D3D;
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  public Static3D[] getFaceAxis()
141
    {
142
    return TouchControlIcosahedron.FACE_AXIS;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  private float[] computeOff(int index, int N)
148
    {
149
    if( N==2 )
150
      {
151
      return new float[] {0,0,0};
152
      }
153
    else
154
      {
155
      switch(index)
156
        {
157
        case 0 : return new float[] {0,SQ3/9,0};
158
        case 1 : return new float[] {-1.0f/6,-SQ3/18,0};
159
        default: return new float[] { 1.0f/6,-SQ3/18,0};
160
        }
161
      }
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165
// Rodrigues
166

    
167
  private void rotateVect(float vx, float vy, float vz, float sin, float cos, float[] vec)
168
    {
169
    float cx = vy*vec[2] - vz*vec[1];
170
    float cy = vz*vec[0] - vx*vec[2];
171
    float cz = vx*vec[1] - vy*vec[0];
172

    
173
    float scalar = vx*vec[0] + vy*vec[1] + vz*vec[2];
174

    
175
    vec[0] = vec[0]*cos + cx*sin + vx*scalar*(1-cos);
176
    vec[1] = vec[1]*cos + cy*sin + vy*scalar*(1-cos);
177
    vec[2] = vec[2]*cos + cz*sin + vz*scalar*(1-cos);
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  private void rotateFacePosition(float x, float y, float z, float[] off)
183
    {
184
    float cosB = (float)Math.sqrt(x*x+z*z);
185
    float sinB = y;
186
    float sinA = x/cosB;
187
    float cosA = z/cosB;
188

    
189
    float vec1X = 0;
190
    float vec1Y = 1;
191
    float vec1Z = 0;
192

    
193
    float vec2X = -z/cosB;
194
    float vec2Y = 0;
195
    float vec2Z = x/cosB;
196

    
197
    rotateVect(vec1X,vec1Y,vec1Z,sinA,cosA,off);
198
    rotateVect(vec2X,vec2Y,vec2Z,sinB,cosB,off);
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  private float[] createFacePosition(float vx, float vy, float vz, float scale, boolean inverted, float[] off)
204
    {
205
    float[] tmp = new float[3];
206
    tmp[0] = off[0];
207
    tmp[1] = off[1];
208
    tmp[2] = off[2];
209

    
210
    rotateFacePosition(vx,vy,vz,tmp);
211

    
212
    if( inverted )
213
      {
214
      tmp[0] = -tmp[0];
215
      tmp[1] = -tmp[1];
216
      tmp[2] = -tmp[2];
217
      }
218

    
219
    float[] ret = new float[3];
220

    
221
    ret[0] = scale*(vx+tmp[0]);
222
    ret[1] = scale*(vy+tmp[1]);
223
    ret[2] = scale*(vz+tmp[2]);
224

    
225
    return ret;
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
  private float[] createEdgePosition(int edge, int index, int N)
231
    {
232
    int[] edgeIndices = EDGE_INDICES[edge];
233
    int i0 = edgeIndices[0];
234
    int i1 = edgeIndices[1];
235

    
236
    float x = (VEC[i0][0]+VEC[i1][0])/2;
237
    float y = (VEC[i0][1]+VEC[i1][1])/2;
238
    float z = (VEC[i0][2]+VEC[i1][2])/2;
239

    
240
    return new float[] { x,y,z };
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  public float[][] getCubitPositions(int[] numLayers)
246
    {
247
    if( mPosition==null )
248
      {
249
      int N = numLayers[0];
250

    
251
      int numV = 12;
252
      int perF = N*(N-1)/2;
253
      int numF = 20*perF;
254
      int perE = N-2;
255
      int numE = 30*perE;
256

    
257
      mPosition = new float[numV+numF+numE][];
258

    
259
      for(int v=0; v<12; v++)
260
        mPosition[v] = new float[] { VEC[v][0]*N, VEC[v][1]*N, VEC[v][2]*N };
261

    
262
      float[][] off = new float[perF][];
263
      for(int i=0; i<perF; i++) off[i] = computeOff(i,N);
264

    
265
      for(int f=0; f<20; f++)
266
        {
267
        Static3D vect = TouchControlIcosahedron.FACE_AXIS[f];
268
        float x = vect.get0();
269
        float y = vect.get1();
270
        float z = vect.get2();
271
        boolean inverted = f>=10;
272

    
273
        for(int i=0; i<perF; i++)
274
          mPosition[12+f*perF+i] = createFacePosition(x,y,z,DIST3D*N,inverted,off[i]);
275
        }
276

    
277
      for(int e=0; e<30; e++)
278
        for(int i=0; i<perE; i++)
279
          mPosition[12+20*perF+e*perE+i] = createEdgePosition(e,i,N);
280
      }
281

    
282
    return mPosition;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  public Static4D getCubitQuats(int cubit, int[] numLayers)
288
    {
289
    if( mQuatIndex==null )
290
      {
291
      switch( numLayers[0] )
292
        {
293
        case 2: mQuatIndex = new int[]
294
                  {
295
                  0,12,5,9,13,8,14,18,7,6,10,55,
296

    
297
                  0,4,3,2,1,
298
                  6,11,32,14,26,
299
                  41,27,7,5,10,
300
                  35,18,45,33,15
301
                  };
302
                break;
303
        case 3: mQuatIndex = new int[]
304
                  {
305
                  0,12,5,9,13,8,14,18,7,6,10,55,
306

    
307
                  0,52,28,4,44,9,3,31,24,2,13,51,1,8,42,
308
                  21,30,6,16,11,49,54,32,39,48,14,23,37,43,26,
309
                  41,50,46,27,40,34,7,25,17,29,5,12,10,20,53,
310
                  56,38,35,58,22,18,57,47,45,55,36,33,59,19,15,
311

    
312
                  0,4,3,2,1,
313
                  5,20,31,13,8,
314
                  6,16,49,10,39,41,23,27,17,7,
315
                  14,22,30,11,19,
316
                  35,18,45,33,15
317
                  };
318
                break;
319
        }
320
      }
321

    
322
    return mObjectQuats[mQuatIndex[cubit]];
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  private float[][] getVertices(int variant)
328
    {
329
    float N = getNumLayers()[0];
330

    
331
    if( variant==0 )
332
      {
333
      float[] pos = mPosition[0];
334
      float[][] ret = new float[7][];
335
      for(int i=0; i<6; i++) ret[i] = new float[] { VEC[i][0]-pos[0], VEC[i][1]+(N-1)*VEC[0][1]-pos[1], VEC[i][2]-pos[2] };
336
      ret[6] = new float[] { -pos[0], -pos[1], -pos[2] };
337
      return ret;
338
      }
339
    else if( variant==1 )
340
      {
341
      float CX = mPosition[12][0];
342
      float CY = mPosition[12][1];
343
      float CZ = mPosition[12][2];
344

    
345
      float v1x = VEC[0][0]*(N-1)+VEC[2][0]; float v1y = VEC[0][1]*(N-1)+          VEC[2][1]; float v1z = VEC[0][2]*(N-1)+VEC[2][2];
346
      float v2x = VEC[2][0];                 float v2y = VEC[0][1]*(N-2)+VEC[1][1]+VEC[2][1]; float v2z = VEC[1][2]+VEC[2][2];
347
      float v3x = VEC[0][0]*(N-1)+VEC[1][0]; float v3y = VEC[0][1]*(N-1)+VEC[1][1]          ; float v3z = VEC[0][2]*(N-1)+VEC[1][2];
348

    
349
      return new float[][] { { v1x-CX, v1y-CY, v1z-CZ },
350
                             { v2x-CX, v2y-CY, v2z-CZ },
351
                             { v3x-CX, v3y-CY, v3z-CZ },
352
                             {    -CX,    -CY,    -CZ }
353
                           };
354
      }
355
    else
356
      {
357
      float[] pos = mPosition[72];
358

    
359
      float v1x = N*(VEC[0][0] + VEC[0][0] + VEC[1][0])/3; float v1y = N*(VEC[0][1] + VEC[0][1] + VEC[1][1])/3; float v1z = N*(VEC[0][2] + VEC[0][2] + VEC[1][2])/3;
360
      float v2x = N*(VEC[0][0] + VEC[1][0] + VEC[1][0])/3; float v2y = N*(VEC[0][1] + VEC[1][1] + VEC[1][1])/3; float v2z = N*(VEC[0][2] + VEC[1][2] + VEC[1][2])/3;
361
      float v3x = N*(VEC[0][0] + VEC[1][0] + VEC[2][0])/3; float v3y = N*(VEC[0][1] + VEC[1][1] + VEC[2][1])/3; float v3z = N*(VEC[0][2] + VEC[1][2] + VEC[2][2])/3;
362
      float v4x =-N*(VEC[0][0] + VEC[1][0] + VEC[2][0])/3; float v4y = N*(VEC[0][1] + VEC[1][1] + VEC[2][1])/3; float v4z = N*(VEC[0][2] + VEC[1][2] + VEC[2][2])/3;
363

    
364
      return new float[][] { { v1x-pos[0], v1y-pos[1], v1z-pos[2] },
365
                             { v2x-pos[0], v2y-pos[1], v2z-pos[2] },
366
                             { v3x-pos[0], v3y-pos[1], v3z-pos[2] },
367
                             { v4x-pos[0], v4y-pos[1], v4z-pos[2] },
368
                             {    -pos[0],    -pos[1],    -pos[2] }
369
                           };
370
      }
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  public ObjectShape getObjectShape(int variant)
376
    {
377
    if( variant==0 )
378
      {
379
      int[][] indices =
380
          {
381
              {1,2,0},{2,3,0},{3,4,0},{4,5,0},{5,1,0}, {6,2,1},{6,3,2},{6,4,3},{6,5,4},{6,1,5}
382
          };
383

    
384
      return new ObjectShape(getVertices(variant), indices);
385
      }
386
    else if( variant==1 )
387
      {
388
      int[][] indices =
389
          {
390
              {0,2,1},{0,1,3},{2,0,3},{1,2,3}
391
          };
392

    
393
      return new ObjectShape(getVertices(variant), indices);
394
      }
395
    else
396
      {
397
      int[][] indices =
398
          {
399
              {0,1,2},{0,3,1},{4,2,1},{4,0,2},{4,3,0},{4,1,3}
400
          };
401

    
402
      return new ObjectShape(getVertices(variant), indices);
403
      }
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public ObjectFaceShape getObjectFaceShape(int variant)
409
    {
410
    if( variant==0 )
411
      {
412
      float h1 = isInIconMode() ? 0.001f : 0.04f;
413
      float h2 = 0.001f;
414
      float[][] bands = { {h1,27,0.2f,0.4f,5,0,0}, {h2,27,0.2f,0.4f,3,0,0} };
415
      int[] indices   = { 0,0,0,0,0, 1,1,1,1,1,1 };
416
      return new ObjectFaceShape(bands,indices,null);
417
      }
418
    else if( variant==1 )
419
      {
420
      float h1 = isInIconMode() ? 0.001f : 0.04f;
421
      float h2 = 0.001f;
422
      float[][] bands = { {h1,25,0.2f,0.4f,5,0,0}, {h2,25,0.2f,0.4f,3,0,0} };
423
      int[] indices   = { 0,1,1,1 };
424
      return new ObjectFaceShape(bands,indices,null);
425
      }
426
    else
427
      {
428
      float h1 = isInIconMode() ? 0.001f : 0.04f;
429
      float h2 = 0.001f;
430
      float[][] bands = { {h1,25,0.2f,0.4f,5,0,0}, {h2,25,0.2f,0.4f,3,0,0} };
431
      int[] indices   = { 0,0,1,1,1,1 };
432
      return new ObjectFaceShape(bands,indices,null);
433
      }
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public ObjectVertexEffects getVertexEffects(int variant)
439
    {
440
    if( variant==0 )
441
      {
442
      float[] pos = mPosition[0];
443
      float[][] corners  = { {0.04f,0.12f},{0.04f,0.10f} };
444
      int[] cornerIndices= { 0,1,1,1,1,1,-1 };
445
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
446
      int[] centerIndices= { 0,0,0,0,0,0,-1 };
447
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
448
      }
449
    else if( variant==1 )
450
      {
451
      float[] pos = mPosition[12];
452
      float[][] corners = { {0.04f,0.15f} };
453
      int[] indices     = { 0,0,0,-1 };
454
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
455
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
456
      }
457
    else
458
      {
459
      float[] pos = mPosition[72];
460
      float[][] corners = { {0.04f,0.15f} };
461
      int[] indices     = { 0,0,0,0,-1 };
462
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
463
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
464
      }
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  public int getNumCubitVariants(int[] numLayers)
470
    {
471
    return getNumLayers()[0]==2 ? 2 : 3;
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public int getCubitVariant(int cubit, int[] numLayers)
477
    {
478
    int N = getNumLayers()[0];
479
    return cubit<12 ? 0 : (cubit<10*N*(N-1)+12 ? 1 : 2);
480
    }
481

    
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

    
484
  public float getStickerRadius()
485
    {
486
    return 0.09f;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  public float getStickerStroke()
492
    {
493
    return isInIconMode() ? 0.14f : 0.09f;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public float[][] getStickerAngles()
499
    {
500
    return null;
501
    }
502

    
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
// PUBLIC API
505

    
506
  public Static3D[] getRotationAxis()
507
    {
508
    return ROT_AXIS;
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  public int[][] getBasicAngles()
514
    {
515
    if( mBasicAngle==null )
516
      {
517
      int num = getNumLayers()[0];
518
      int[] tmp = new int[num];
519
      for(int i=0; i<num; i++) tmp[i] = 5;
520
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp,tmp,tmp };
521
      }
522

    
523
    return mBasicAngle;
524
    }
525

    
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527

    
528
  public String getShortName()
529
    {
530
    switch(getNumLayers()[0])
531
      {
532
      case 2: return ObjectType.ICOS_2.name();
533
      case 3: return ObjectType.ICOS_3.name();
534
      }
535

    
536
    return null;
537
    }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

    
541
  public ObjectSignature getSignature()
542
    {
543
    switch(getNumLayers()[0])
544
      {
545
      case 2: return new ObjectSignature(ObjectSignatures.ICOS_2);
546
      case 3: return new ObjectSignature(ObjectSignatures.ICOS_3);
547
      }
548

    
549
    return null;
550
    }
551

    
552
///////////////////////////////////////////////////////////////////////////////////////////////////
553

    
554
  public String getObjectName()
555
    {
556
    switch(getNumLayers()[0])
557
      {
558
      case 2: return "Icosamate";
559
      case 3: return "Master Icosamate";
560
      }
561
    return null;
562
    }
563

    
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565

    
566
  public String getInventor()
567
    {
568
    switch(getNumLayers()[0])
569
      {
570
      case 2: return "Jason Smith";
571
      case 3: return "Keisuke Maruyama";
572
      }
573
    return null;
574
    }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577

    
578
  public int getYearOfInvention()
579
    {
580
    switch(getNumLayers()[0])
581
      {
582
      case 2: return 2010;
583
      case 3: return 2018;
584
      }
585
    return 0;
586
    }
587

    
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589

    
590
  public int getComplexity()
591
    {
592
    return getNumLayers()[0]==2 ? 3 : 4;
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public String[][] getTutorials()
598
    {
599
    int[] numLayers = getNumLayers();
600

    
601
    switch(numLayers[0])
602
      {
603
      case 2: return new String[][] {
604
                            {"gb","e7Es4Zx6Sl4","Icosamate introduction & algorithms","Superantoniovivaldi"},
605
                            {"gb","ZhkklbYfs98","Icosamate solve","Superantoniovivaldi"},
606
                            {"pl","eJTLTeoicWI","Icosamate TUTORIAL PL","MrUK"},
607
                            {"vn","RVjjxj9rPeg","BẠN PHẠM BẢO GIẢI ICOSAMATE","VĂN CÔNG TÙNG"},
608
                          };
609
      case 3: return new String[][] {
610
                            {"gb","77aBjBdfA2Q","Master Icosamate Algorithms","Superantoniovivaldi"},
611
                            {"gb","j6AIwlIofFU","Master Icosamate Tutorial","Superantoniovivaldi"},
612
                            {"gb","5Z1B5r6-CxM","Astrominx Tutorial","Jabberwock Technologies"},
613
                            {"pl","","Icosamate TUTORIAL PL","MrUK"},
614
                            {"vn","C4YO0B4rgTc","Tutorial N.237- Master Icosamate 1/3","Duy Thích Rubik"},
615
                            {"vn","90m_0AoyOHU","Tutorial N.237- Master Icosamate 2/3","Duy Thích Rubik"},
616
                            {"vn","LOd5qBwoP_k","Tutorial N.237- Master Icosamate 3/3","Duy Thích Rubik"},
617
                          };
618
      }
619

    
620
    return null;
621
    }
622
}
(17-17/42)