Project

General

Profile

Download (16.4 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ cc3d81dd

1 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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.objects;
21
22
import android.content.res.Resources;
23
24 f10a88a8 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
25 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
26 6cf89a3e Leszek Koltunski
import org.distorted.helpers.ScrambleState;
27 4c0a6d97 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
33 38589947 Leszek Koltunski
import java.util.Random;
34
35 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37 538ee7a6 Leszek Koltunski
abstract class TwistyBandagedAbstract extends TwistyObject
38 4c0a6d97 Leszek Koltunski
{
39
  // the three rotation axis of a 3x3 Cube. Must be normalized.
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(1,0,0),
43
           new Static3D(0,1,0),
44
           new Static3D(0,0,1)
45
         };
46
47
  private static final int[] FACE_COLORS = new int[]
48
         {
49
           COLOR_YELLOW, COLOR_WHITE,
50
           COLOR_BLUE  , COLOR_GREEN,
51
           COLOR_RED   , COLOR_ORANGE
52
         };
53
54 538ee7a6 Leszek Koltunski
  private static final int[][] mDimensions = new int[][]
55
        {
56
         {1,1,1},  // has to be X>=Z>=Y so that all
57
         {2,1,1},  // the faces are horizontal
58
         {3,1,1},
59
         {2,1,2},
60
         {2,2,2}
61 4c0a6d97 Leszek Koltunski
        };
62
63 97eb0852 Leszek Koltunski
  private static final int NUM_STICKERS = 4;
64 9c06394a Leszek Koltunski
65 97eb0852 Leszek Koltunski
  private int[] mBasicAngle;
66 38589947 Leszek Koltunski
  private int mCurrState;
67
  private int mIndexExcluded;
68 e1dc3366 Leszek Koltunski
  private int[][] mScrambleTable;
69
  private int[] mNumOccurences;
70 97eb0852 Leszek Koltunski
  private Static4D[] mQuats;
71
  private ObjectSticker[] mStickers;
72
  private Static4D[] mInitQuats;
73
  private int[][] mAxisMap;
74
  private int[][] mFaceMap;
75 f2d0d23e Leszek Koltunski
  ScrambleState[] mStates;
76
  float[][] POSITIONS;
77
  int[] QUAT_INDICES;
78 38589947 Leszek Koltunski
79 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
80
81 538ee7a6 Leszek Koltunski
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
82
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
83 4c0a6d97 Leszek Koltunski
    {
84
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
85
    }
86
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88
89 68ce0d53 Leszek Koltunski
  abstract float[][] getPositions();
90
  abstract int[] getQuatIndices();
91
92 97eb0852 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
93
94
  private void initializeQuats()
95
    {
96
    mQuats = new Static4D[]
97
         {
98
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
99
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
100
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
101
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
102
103
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
104
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
105
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
106
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
107
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
108
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
109
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
110
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
111
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
112
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
113
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
114
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
115
116
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
117
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
118
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
119
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
120
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
121
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
122
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
123
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
124
         };
125
    }
126
127 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
128
129
  int[] getSolvedQuats(int cubit, int numLayers)
130
    {
131 97eb0852 Leszek Koltunski
    if( mQuats==null ) initializeQuats();
132 a480ee80 Leszek Koltunski
    int status = retCubitSolvedStatus(cubit,numLayers);
133 97eb0852 Leszek Koltunski
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],mQuats);
134 a480ee80 Leszek Koltunski
    }
135
136 68ce0d53 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
137
138 f10a88a8 Leszek Koltunski
  int getNumCubits()
139
    {
140
    return getPositions().length;
141
    }
142
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
145
  private float[] getCubitPosition(int cubit)
146 68ce0d53 Leszek Koltunski
    {
147
    float[][] pos = getPositions();
148
149 f10a88a8 Leszek Koltunski
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
150
    }
151 68ce0d53 Leszek Koltunski
152 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154
  private int getQuatIndex(int cubit)
155
    {
156
    int[] indices = getQuatIndices();
157
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
158 68ce0d53 Leszek Koltunski
    }
159
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161
162 f10a88a8 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
163 68ce0d53 Leszek Koltunski
    {
164 f10a88a8 Leszek Koltunski
    int variant = getCubitVariant(cubit,numLayers);
165 68ce0d53 Leszek Koltunski
166 f10a88a8 Leszek Koltunski
    final int[][] vert_indices =
167
      {
168
        {2,3,1,0},
169
        {7,6,4,5},
170
        {4,0,1,5},
171
        {7,3,2,6},
172
        {6,2,0,4},
173
        {3,7,5,1},
174
      };
175
176
    float defHeight = 0.048f;
177
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
178
    float[][] corners = new float[][] { {0.04f,0.15f} };
179
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
180
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
181
182
    int X = mDimensions[variant][0];
183
    int Y = mDimensions[variant][1];
184
    int Z = mDimensions[variant][2];
185
186
    int maxXY = Math.max(X,Y);
187
    int maxXZ = Math.max(X,Z);
188
    int maxYZ = Math.max(Y,Z);
189
190
    double[][] vertices =
191
      {
192
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
193
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
194
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
195
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
196
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
197
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
198
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
199
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
200
      };
201
202
    float[][] bands= new float[][]
203
      {
204
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
205
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
206
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
207
      };
208
209
    float[][] centers = new float[][]
210
      {
211
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
212
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
213
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
214
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
215
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
216
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
217
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
218
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
219
      };
220
221
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
222 68ce0d53 Leszek Koltunski
    }
223 4c0a6d97 Leszek Koltunski
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
227 4c0a6d97 Leszek Koltunski
    {
228 97eb0852 Leszek Koltunski
    if( mInitQuats ==null )
229
      {
230
      mInitQuats = new Static4D[]
231
        {
232
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
233
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
234
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
235
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
236
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
237
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
238
        };
239
      }
240
241
    return mInitQuats[getQuatIndex(cubit)];
242 3e605536 Leszek Koltunski
    }
243 f10a88a8 Leszek Koltunski
244 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246
  int getNumCubitVariants(int numLayers)
247
    {
248
    return mDimensions.length;
249
    }
250
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252
253
  int getCubitVariant(int cubit, int numLayers)
254
    {
255
    float[][] pos = getPositions();
256 f10a88a8 Leszek Koltunski
257 3e605536 Leszek Koltunski
    if( cubit>=0 && cubit<pos.length )
258 f10a88a8 Leszek Koltunski
      {
259 3e605536 Leszek Koltunski
      int numPoints = pos[cubit].length/3;
260
      return numPoints==8 ? 4 : numPoints-1;
261 4c0a6d97 Leszek Koltunski
      }
262
263 3e605536 Leszek Koltunski
    return 1;
264 4c0a6d97 Leszek Koltunski
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268 9c06394a Leszek Koltunski
  int getColor(int face)
269
    {
270
    return FACE_COLORS[face];
271
    }
272
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275
  ObjectSticker retSticker(int face)
276 4c0a6d97 Leszek Koltunski
    {
277 97eb0852 Leszek Koltunski
    if( mStickers==null )
278
      {
279
      mStickers = new ObjectSticker[NUM_STICKERS];
280
281
      int[][] stickerDimensions = new int[][]
282
        {
283
         {1,1},  // dimensions of the faces of
284
         {2,1},  // the cuboids defined in mDimensions
285
         {3,1},
286
         {2,2}
287
        };
288
289
      for(int s=0; s<NUM_STICKERS; s++)
290
        {
291
        float X = stickerDimensions[s][0];
292
        float Y = stickerDimensions[s][1];
293
        float MAX = Math.max(X,Y);
294
        X /= (2*MAX);
295
        Y /= (2*MAX);
296
297
        float R = 0.10f / MAX;
298
        float S = 0.08f / MAX;
299
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
300
        float[] radii = new float[] {R,R,R,R};
301
        mStickers[s] = new ObjectSticker(coords,null,radii,S);
302
        }
303
      }
304
305 9c06394a Leszek Koltunski
    return mStickers[face/NUM_FACES];
306 4c0a6d97 Leszek Koltunski
    }
307
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309
310 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
311 4c0a6d97 Leszek Koltunski
    {
312
    int numCubits = getNumCubits();
313 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
314 4c0a6d97 Leszek Koltunski
315
    for(int cubit=0; cubit<numCubits; cubit++)
316
      {
317 e6cf7283 Leszek Koltunski
      tmp[cubit] = getCubitPosition(cubit);
318 4c0a6d97 Leszek Koltunski
      }
319
320
    return tmp;
321
    }
322
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324
325
  Static4D[] getQuats()
326
    {
327 97eb0852 Leszek Koltunski
    if( mQuats==null ) initializeQuats();
328
    return mQuats;
329 4c0a6d97 Leszek Koltunski
    }
330
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332
333
  boolean shouldResetTextureMaps()
334
    {
335
    return false;
336
    }
337
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
340
  int getNumFaces()
341
    {
342
    return FACE_COLORS.length;
343
    }
344
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346
347 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
348 4c0a6d97 Leszek Koltunski
    {
349 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
350 4c0a6d97 Leszek Koltunski
351
    for(int i=0; i<numLayers-1; i++)
352
      {
353 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
354
      cuts[0][i] = cut;
355
      cuts[1][i] = cut;
356
      cuts[2][i] = cut;
357 4c0a6d97 Leszek Koltunski
      }
358
359
    return cuts;
360
    }
361
362 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  int getSolvedFunctionIndex()
365
    {
366
    return 0;
367
    }
368
369 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
370
371
  int getNumStickerTypes(int numLayers)
372
    {
373 538ee7a6 Leszek Koltunski
    return NUM_STICKERS;
374 4c0a6d97 Leszek Koltunski
    }
375
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
378
  int getNumCubitFaces()
379
    {
380
    return FACE_COLORS.length;
381
    }
382
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384
385
  float getScreenRatio()
386
    {
387
    return 0.5f;
388
    }
389
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
392 538ee7a6 Leszek Koltunski
  private int retStickerIndex(int horzSize, int vertSize)
393 4c0a6d97 Leszek Koltunski
    {
394 538ee7a6 Leszek Koltunski
    switch(horzSize)
395 4c0a6d97 Leszek Koltunski
      {
396 538ee7a6 Leszek Koltunski
      case 1: return 0;
397
      case 2: return vertSize==1 ? 1:3;
398
      case 3: return 2;
399 4c0a6d97 Leszek Koltunski
      }
400
401 538ee7a6 Leszek Koltunski
    return 0;
402
    }
403 4c0a6d97 Leszek Koltunski
404 538ee7a6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
405
406
  private int getStickerIndex(int cubitface, int[] dim)
407
    {
408 4c0a6d97 Leszek Koltunski
    switch(cubitface)
409
      {
410 538ee7a6 Leszek Koltunski
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
411
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
412
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
413 4c0a6d97 Leszek Koltunski
      }
414
415 538ee7a6 Leszek Koltunski
    return 0;
416
    }
417
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419
420
  int getFaceColor(int cubit, int cubitface, int numLayers)
421
    {
422 97eb0852 Leszek Koltunski
    if( mFaceMap==null )
423
      {
424
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
425
      mFaceMap = new int[][]
426
          {
427
              {0,0,5,2,4,2},
428
              {1,1,4,3,5,3},
429
              {2,4,2,1,1,4},
430
              {3,5,3,0,0,5},
431
              {4,3,0,4,3,0},
432
              {5,2,1,5,2,1}
433
          };
434
      }
435
436
    if( mAxisMap==null )
437
      {
438
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
439
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
440
      }
441
442 f10a88a8 Leszek Koltunski
    int variant      = getCubitVariant(cubit,numLayers);
443 538ee7a6 Leszek Koltunski
    int[] dim        = mDimensions[variant];
444
    float[] pos      = getCubitPosition(cubit);
445
    int stickerIndex = getStickerIndex(cubitface,dim);
446
    int quatIndex    = getQuatIndex(cubit);
447
    int face         = mFaceMap[cubitface][quatIndex];
448
    int multiplier   = (face%2)==0 ? 1:-1;
449
    int posIndex     = face/2;
450
    int dimIndex     = mAxisMap[posIndex][quatIndex];
451 92ec91b9 Leszek Koltunski
452
    float position = 0.0f;
453
    int len = pos.length/3;
454
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
455
    position /= len;
456
457
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
458 538ee7a6 Leszek Koltunski
459 97eb0852 Leszek Koltunski
    return reaches ? stickerIndex*NUM_FACES + face : NUM_TEXTURES;
460 4c0a6d97 Leszek Koltunski
    }
461
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463
464
  float returnMultiplier()
465
    {
466
    return getNumLayers();
467
    }
468
469 e1dc3366 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
470
471
  private void initializeScrambling()
472
    {
473
    int numLayers = getNumLayers();
474
475
    if( mScrambleTable ==null )
476
      {
477
      mScrambleTable = new int[NUM_AXIS][numLayers];
478
      }
479
    if( mNumOccurences ==null )
480
      {
481
      int max=0;
482
483
      for (ScrambleState mState : mStates)
484
        {
485
        int tmp = mState.getTotal(-1);
486
        if (max < tmp) max = tmp;
487
        }
488
489
      mNumOccurences = new int[max];
490
      }
491
492
    for(int i=0; i<NUM_AXIS; i++)
493
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
494
    }
495
496 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
497
// PUBLIC API
498
499 38589947 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
500
    {
501
    if( curr==0 )
502
      {
503
      mCurrState     = 0;
504
      mIndexExcluded =-1;
505 e1dc3366 Leszek Koltunski
      initializeScrambling();
506 38589947 Leszek Koltunski
      }
507
508 e1dc3366 Leszek Koltunski
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
509 38589947 Leszek Koltunski
510
    scramble[curr][0] = info[0];
511
    scramble[curr][1] = info[1];
512
    scramble[curr][2] = info[2];
513
514
    mCurrState     = info[3];
515
    mIndexExcluded = info[0];
516
    }
517
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519
520 4c0a6d97 Leszek Koltunski
  public Static3D[] getRotationAxis()
521
    {
522
    return ROT_AXIS;
523
    }
524
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526
527 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
528 4c0a6d97 Leszek Koltunski
    {
529 97eb0852 Leszek Koltunski
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
530
    return mBasicAngle;
531 4c0a6d97 Leszek Koltunski
    }
532
}