package com.lin1943.rubikcubesolver

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.video.Recorder
import androidx.camera.video.Recording
import androidx.camera.video.VideoCapture
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.lin1943.rubikcubesolver.databinding.ActivityMainBinding
import java.io.File
import java.nio.ByteBuffer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


private var nl1=9
private var nl2=12
private var no1=3
private var no2=3
private var io1=0
private var io2=0
private var ntg=0
private var nto=0
private var nxa=0
private var nxb=0
private var ioa=0
private var iob=0
private var iok=0
private var nt0=0
private var n1=0
private var n2=0
private var n3=0
private var n4=0
private var nt=0
private var iu=0
private var id=0
private var xs  = IntArray(41)  // 0
private var nm1 = IntArray(16)
private var nm2 = IntArray(24)
private var nms = IntArray(40)
private var nmo = IntArray(41)
private var nmx = IntArray(20)
private var nmt = IntArray(205) // nmt[5][41]
private var q1 = IntArray(2520)
private var q2 = IntArray(2520)
private var x0 = IntArray(277390) //  95040 (6:3702717:1138856)
private var p0 = IntArray(277390)
private var m0 = IntArray(277390)
private var x1 = IntArray(544908) // 295326 (8:3696619:1519971)
private var p1 = IntArray(544908)
private var m1 = IntArray(544908)
private var mq1 = 2520
private var mp0 = 277389 //  95039 (6:3702717:1138856)  5:6:7
private var mp1 = 544907 // 295325 (8:3696619:1519971)  7:8:9
private var cc = IntArray(216) // cc[6][6][6]
private var xc = IntArray(216) // xc[6][6][6]
private var ce = IntArray(36)  // ce[6][6]
private var xe = IntArray(36)  // xe[6][6]
private var s  = intArrayOf(0,
    3,1,2, 3,2,4, 3,4,5, 3,5,1, // 8-corners (3 & 6 go first)
    6,2,1, 6,4,2, 6,5,4, 6,1,5, // (3 face # in ccw sequence)
    3,1, 3,2, 3,4, 3,5,         // 12-edges (3,6,1,4 go first)
    6,1, 6,2, 6,4, 6,5,
    1,2, 4,2, 4,5, 1,5,
    1, 2, 3, 4, 5, 6)           // 6-centers
private var faceC = arrayOf(0,
    3,1,2, 3,2,4, 3,4,5, 3,5,1,
    6,2,1, 6,4,2, 6,5,4, 6,1,5,
    3,1, 3,2, 3,4, 3,5,
    6,1, 6,2, 6,4, 6,5,
    1,2, 4,2, 4,5, 1,5,
    1, 2, 3, 4, 5, 6)
private val ki = intArrayOf(
    0,0,0, 4,5,6, 13,14,15, 7,8,9, 10,11,12, 1,2,3, // after rot face1
    1,2,3, 0,0,0, 13,14,15, 7,8,9, 10,11,12, 4,5,6,
    1,2,3, 4,5,6,  0, 0, 0, 7,8,9, 10,11,12,13,14,15,
    1,2,3, 4,5,6, 13,14,15, 0,0,0, 10,11,12, 7,8,9,
    1,2,3, 4,5,6, 13,14,15, 7,8,9,  0, 0, 0,10,11,12,
    1,2,3, 4,5,6, 13,14,15, 7,8,9, 10,11,12, 0,0,0)
private var rt = intArrayOf( // square No of 6-rotations about 6-faces for RotateA
    1, 2, 3,25,26,11,12,10,48,47,22,23,24,33,34,14,15,13,42,41,  // face 1
    4, 5, 6,27,28, 2, 3, 1,41,42,13,14,15,35,36,17,18,16,43,44,  // face 2
    6, 4, 5,30,29, 9, 7, 8,32,31,12,10,11,26,25, 3, 1, 2,28,27,  // face 3
    7, 8, 9,29,30, 5, 6, 4,44,43,16,17,18,37,38,20,21,19,46,45,  // face 4
    10,11,12,31,32, 8, 9, 7,45,46,19,20,21,39,40,23,24,22,47,48,  // face 5
    15,13,14,34,33,24,22,23,40,39,21,19,20,38,37,18,16,17,36,35,  // face 6
    27,28,51, 1, 1,32,31,53, 1, 1,39,40,54, 1, 1,36,35,50, 1, 1,  // face 7 X
    29,30,51, 1, 1,26,25,49, 1, 1,33,34,54, 1, 1,38,37,52, 1, 1,  // face 8 Y
    43,44,52, 1, 1,46,45,53, 1, 1,47,48,49, 1, 1,42,41,50, 1, 1); // face 9 Z
private var f12r = intArrayOf(
    1,2,3,4,5,6,7,8,9, 2,4,3,5,1,6,8,7,9, 4,5,3,1,2,6,7,8,9, 5,1,3,2,4,6,8,7,9,
    2,1,6,5,4,3,8,7,9, 4,2,6,1,5,3,7,8,9, 1,5,6,4,2,3,7,8,9, 5,4,6,2,1,3,8,7,9);
private var f  = intArrayOf(0, 1,2,4,5, 1,2,4,5);
private var g  = intArrayOf(26,25, 28,27, 30,29, 32,31, 26,25);      // L3_edges:side(1):top(2)
private var z  = intArrayOf(41,42, 44,43, 45,46, 48,47);             // L2_edge {L R}
private var u  = intArrayOf(1,2,3, 4,5,6, 7,8,9, 10,11,12, 1,2,3);   // L3_corner {t s s} in cc
private var d  = intArrayOf(13,14,15, 16,17,18, 19,20,21, 22,23,24); // L1_corner {b s s} in cc
private var c  = intArrayOf(2,3,1, 5,6,4, 8,9,7, 11,12,10, 2,3,1);   // L3_corners:(s1 s2 t3) in ccw T3c4
private var cu = intArrayOf(10,1,4,7,10,1);
private var cs = intArrayOf(11,2,5,8,11,2);
private var cr = intArrayOf(12,3,6,9,12,3);
private var gu = intArrayOf(0, 25,27,29,31,25);
private var gs = intArrayOf(0, 26,28,30,32,26);
private var e  = intArrayOf(
    25,27,29,31,48,41,44,45,42,43,46,47,
    26,28,30,32,34,36,38,40,33,35,37,39);     // L1e0
private var ip = intArrayOf(0,1,2,3,0,1,2,3); // X OK for face1, NG for face4, Z not used
private var iq = intArrayOf(0,2,4,0,5,1,0);   // X OK for face1, NG for face4, Z not used
private var id54 = intArrayOf(
    12,26,2, 47,49,41, 23,34,15,   //  7 29  4 |  6 30  8   9 32 11
    3,28, 5, 42,50,44, 14,36,18,   // 31 51 27 | 43 52 45  46 53 48
    7,29, 4, 31,51,27, 10,25, 1,   // 10 25  1 | 17 38 21  20 40 24
    6,30, 8, 43,52,45, 17,38,21,   // 12 26  2   3 28  5 | 19 39 22
    9,32,11, 46,53,48, 20,40,24,   // 47 49 41  42 50 44 | 37 54 33
    19,39,22, 37,54,33, 16,35,13)  // 23 34 15  14 36 18 | 16 35 13
private var id9 = IntArray(9)
private var ti  = IntArray(55)
private var tj  = IntArray(55)
private var p   = IntArray(55)
private var t   = IntArray(8101) // t[150][54]
private var x   = IntArray(600)  // x[30][20]
private var rd  = IntArray(125);
private var rdd = IntArray(1000); // rdd[8][125]
private var rds = IntArray(200);  // rds[8][25]
private var rdi = IntArray(25);
private var nii = IntArray(8);
private var ni  = 0
private var nj  = 0
private var kmin = 0
private var jtrace = 0
private var jtrmin = 0
private var nseed = -1 // nseed < 32768
private var nr    = 49 // nr  < 100
private var kkk   = 0  // kkk > 0 for debug
private var kkkk=0;
private var LLV=0; // 0:1:2:3:4:5:6
private var SLL=0; // 0:1:2:3:0:0:0
private var OLL=0; // 0:1:1:1:1:4:4
private var PLL=0; // 0:1:1:1:4:1:4
private var MTH=7;
private var faceCix = 0
private var alg3U = 1 // 1:3;  -1:U
private var cicc  = 0 // 1:camera_Input; 2:color_calibration
private var ffok  = 0 // 1~6:input_data is ok for ffok-face
private var ccok  = 0 // 1:color_calibration is ok
private var ddok  = 0 // 1:calibration_data is ok
private var id33  = 0
private var disC  = 1 // 2:disable C-Button // sixyuv.txt          // dpratio.txt
private var ratio = doubleArrayOf(1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5) // px2dp*ratio[0:3],offbt*ratio[4:7]
private var rtD   = 90  // (0,90,180,270)
private var dpW   = 360 // 360 592  423 705
private var dpH   = 568 // 568 336  681 399
private var imW   = intArrayOf(640,320,320,1920)  // 120*16 moto x4  2.56x4.56 in
private var imH   = intArrayOf(480,240,240,1080)  // 120*9  moto x4  65  x 116 mm
private var stP   = intArrayOf(  1,  2,  2)
private var stR   = intArrayOf(640,640,640)
private var px2dp = doubleArrayOf(1.13,0.56,0.56) // 640/568 320/568 320/568
private var pix33 = IntArray(162) // pix33[6][3][3][3]
private var facff = IntArray(9)   // facff[3][3]
private var pixcc = IntArray(18)  // pixcc[6][3]
private var pixdd = IntArray(18)  // pixdd[6][3]
private var pixss = IntArray(27)  // pixss[3][3][3]
private var dsize = intArrayOf(307200,153599,153599,90,0,113,360,568,640,480,-240,189,451,68)
private var pixhh = intArrayOf(46,108,195,57,108,26,60,93,91,51,80,184,47,199,61,56,144,91)
private var image0 = ByteArray(307200) // debug
private var image1 = ByteArray(153599)
private var image2 = ByteArray(153599)
private var imgsiz = intArrayOf(307200,153599,153599,307200,153599,153599,307200,153599,153599)
private var answer = " "
private var info = 0
private var idf  = 0

typealias LumaListener = (luma: Double) -> Unit


class MainActivity : AppCompatActivity() {
    private lateinit var viewBinding: ActivityMainBinding

    private var imageCapture: ImageCapture? = null

    private var videoCapture: VideoCapture<Recorder>? = null
    private var recording: Recording? = null
    /* NG: Unresolved reference: Configuration
    override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
    }
    */
    private var argbC = arrayOf(Color.argb(255,255,192,203), Color.RED,Color.GREEN,Color.YELLOW,Color.argb(255,255,165,0),Color.BLUE,Color.WHITE,Color.argb(0,0,0,0))
    //      val argbC = arrayOf(0xFFFFC0CB,0x7FFF0000,0x7F00FF00,0x7FFFFF00,0xFFFFA500,0x7F0000FF,0x7FFFFFFF,0x00000000)
    private var textC = arrayOf("P","R","G","Y","O","B","W","S")

    private lateinit var cameraExecutor: ExecutorService

    private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

        private fun ByteBuffer.toByteArray(): ByteArray {
            rewind()    // Rewind the buffer to zero
            val data = ByteArray(remaining())
            get(data)   // Copy the buffer into a byte array
            return data // Return the byte array
        }

        override fun analyze(image: ImageProxy) {

            // pix33 = IntArray(162) // pix33[6][3][3][3] // 1.13 *  60 = 68; 1.08 *  60 =  65
            // pixcc = IntArray(18)  // pixcc[6][3]       // 1.13 * 400 =451; 1.08 * 340 = 368
            // pixdd = IntArray(18)  // pixdd[6][3]       // 1.08 *  592=640;480   =   112+368
            // pixss = IntArray(27)  // pixss[3][3][3]    // 1.13 *  568=640       =   189+451
            // dsize = intArrayOf(307200,153599,153599, 90, 0,113,360,568,640,480,-240, 189,189,68)
            // dsize = intArrayOf(307200,153599,153599,  0,58,108,592,336,640,480, 320,  58, 58,65)
            // dsize = intArrayOf(307200,153599,153599,180,58,108,592,336,640,480,-320,-422, 58,65)
            // dsize = intArrayOf(307200,153599,153599, 90, 0, 94,423,681,640,480,-240, 264,264,56)
            // dsize = intArrayOf(307200,153599,153599,  0,58, 91,705,399,640,480, 320,  58, 58,54)
            // dsize = intArrayOf(307200,153599,153599,180,58, 91,705,399,640,480,-320,-422, 58,54)
            // px2dp = DoubleArray(3)
            // imW   = IntArray(3)
            // imH   = IntArray(3)
            // stP   = IntArray(3)
            // stR   = IntArray(3)
            // dpW dpH // 592x336 360x568  705x399 423x681
            var offbt = intArrayOf(0,0,0)
            rtD = image.imageInfo.rotationDegrees     // 90  (0,90,180,270)
            stP[0] = image.planes[0].getPixelStride() // 1    ( 1,  2,  2 )
            stR[0] = image.planes[0].getRowStride()   // 640  (640,640,640)
            imW[0] = image.width                      // 640
            imH[0] = image.height                     // 480
            stP[1] = image.planes[1].getPixelStride() // 2
            stR[1] = image.planes[1].getRowStride()   // 640
            stP[2] = stP[1]; stR[2] = stR[1]
            var stp0 = (stR[0]/stP[0])/(stR[1]/stP[1])// 2
            imW[1] = imW[0]/stp0; imW[2] = imW[1]     // 320
            imH[1] = imH[0]/stp0; imH[2] = imH[1]     // 240
            var px2dp0 = 0.0; var py2dp0 = 0.0; offbt[0] = 0
            if(rtD==0 || rtD==180) {                        //  normal   small
                px2dp0 = imW[0].toDouble() / dpW.toDouble() // 640/592  640/705 // 108   91
                py2dp0 = imH[0].toDouble() / dpH.toDouble() // 480/336  480/399 // 143  120
                if(px2dp0<py2dp0) offbt[0] = (imH[0].toDouble() - px2dp0*dpH.toDouble()).toInt()
            } else {
                px2dp0 = imH[0].toDouble() / dpW.toDouble() // 480/360  480/423 // 133  113
                py2dp0 = imW[0].toDouble() / dpH.toDouble() // 640/568  640/681 // 113   94
                if(px2dp0<py2dp0) offbt[0] = (imW[0].toDouble() - px2dp0*dpH.toDouble()).toInt()
            }
            px2dp[0] = Math.min(px2dp0,py2dp0)
            px2dp[0] = px2dp[0]*ratio[rtD/90] // ratio[] in dpratio.txt may be edited by user
            px2dp[1] = px2dp[0]*(imH[1].toDouble()/imH[0].toDouble()); px2dp[2] = px2dp[1]
            offbt[1] = offbt[0]*imH[1]/imH[0]; offbt[2] = offbt[1]

            dsize[3] = rtD                                           //   0  90    0  90
            dsize[4] = (offbt[0].toDouble()*ratio[rtD/90+4]).toInt() //  58   0   58   0
            dsize[5] = (100.0 * px2dp[0] + 0.5).toInt()              // 108 113   91  94
            dsize[6] = dpW; dsize[7] = dpH; dsize[8] = imW[0]; dsize[9] = imH[0]
            // dsize[10] = px0; dsize[11] = py0; dsize[12] = px400; dsize[13] = px60
            /*
            println("Format ${image.getFormat()}") // 35
            var mat=FloatArray(9)
            image.imageInfo.sensorToBufferTransformMatrix.getValues(mat)
            for(k in 0..mat.size-1) print("${mat[k]}\n") // 1 0 0  0 1 0  0 0 1 // no use
            var sx=1f; var sy=1f; var px=0f; var py=0f;
            image.imageInfo.sensorToBufferTransformMatrix.postScale(sx,sy,px,py); println("$sx $sy $px $py") // no change
            image.imageInfo.sensorToBufferTransformMatrix.postScale(sx,sy,px,py); println("$sx $sy $px $py") // no use
            println("${image.imageInfo.rotationDegrees} ${image.width} ${image.height}")     // 90 640 480
            println("${image.planes[0].getPixelStride()} ${image.planes[0].getRowStride()}") //  1 640 : 1 640
            println("${image.planes[1].getPixelStride()} ${image.planes[1].getRowStride()}") //  1 320 : 2 640
            println("${image.planes[2].getPixelStride()} ${image.planes[2].getRowStride()}") //  1 320 : 2 640
            */
            if(cicc==0 || faceCix==0) {val luma=0.0; image.close(); return} // listener(luma)
            if(cicc==2 && faceCix!=3) {val luma=0.0; image.close(); return} // listener(luma)
            var answerL = "Analyze"
            var f27 = 27 * (faceCix - 1)
            for (k in 0..26) pixss[k] = 0
            for (kk in 0..2) {
                var buffer = image.planes[kk].buffer
                var data = buffer.toByteArray()
                dsize[kk] = data.size     // 307200 153599
                // var pixels = data.map { it.toInt() and 0xFF }
                if(disC>=4) {
                    var ndata = Math.min(data.size,imgsiz[kk]); imgsiz[kk+3]=ndata; imgsiz[kk+6]=data.size
                    if (kk == 0) for (k in 0 until ndata) image0[k] = data[k] // image0.txt
                    if (kk == 1) for (k in 0 until ndata) image1[k] = data[k] // image1.txt
                    if (kk == 2) for (k in 0 until ndata) image2[k] = data[k] // image2.txt
                    image0[2*kk]=(4096*stP[kk]+stR[kk]).shr(7).toByte()
                    image0[2*kk+1]=stR[kk].and(0x7F).toByte()
                    image0[6]=imW[0].shr(7).toByte(); image0[7]=imW[0].and(0x7F).toByte()
                    image0[8]=imH[0].shr(7).toByte(); image0[9]=imH[0].and(0x7F).toByte()
                    image0[3*kk+10]=ndata.shr(14).toByte()
                    image0[3*kk+11]=ndata.shr(7).and(0x7F).toByte()
                    image0[3*kk+12]=ndata.and(0x7F).toByte()
                    image0[19]=dsize[5].shr(7).and(0x7F).toByte()
                    image0[20]=dsize[5].and(0x7F).toByte()
                }
                var ij:   Int
                var px00: Int
                var pxj0: Int
                var pxij: Int
                var pxdx: Int
                var pxdy: Int
                var stx   = 1
                var sty   = 1
                var px0   = 0
                var py0   = 0
                var px60  =  (60.0*px2dp[kk]+0.5).toInt()               //  60 * 1.13 =  68
                var px400 = (400.0*px2dp[kk]*ratio[rtD/90]+0.5).toInt() // 400 * 1.13 = 451
                //  px340 = (340.0*px2dp[kk]*ratio[rtD/90]+0.5).toInt() // 340 * 1.08 = 368
                px400 = px400 + ((offbt[kk].toDouble())*ratio[rtD/90+4]).toInt()
                if(rtD==0 || rtD==180) px400 = imH[kk]-px400
                else                   px400 = imW[kk]-px400
                if(dpW>dpH) px400 = ((offbt[kk].toDouble())*(1.0-ratio[rtD/90+4])).toInt()
                if(rtD==  0) {stx = stP[kk]; sty = stR[kk]; px0 = imW[kk]/2; py0 = px400}
                if(rtD== 90) {stx =-stR[kk]; sty = stP[kk]; px0 =-imH[kk]/2; py0 = px400}
                if(rtD==180) {stx =-stP[kk]; sty =-stR[kk]; px0 =-imW[kk]/2; py0 = px400-imH[kk]}
                if(rtD==270) {stx = stR[kk]; sty =-stP[kk]; px0 = imH[kk]/2; py0 = px400-imW[kk]}
                if(kk==0) {dsize[10] = px0; dsize[11] = py0; dsize[12] = px400; dsize[13] = px60}
                pxdx = px60 * stx
                pxdy = px60 * sty
                px00 = (py0+px60/2-4)*sty + (px0-px60-4)*stx
                // answerL = answerL + "\nkk $kk : ${dsize[kk]} ${px2dp[kk]} : ${imW[kk]} ${imH[kk]} $stx $sty : $pxdx $pxdy $px00"
                for (jj in 0..2) {
                    for (ii in 0..2) {
                        ij = 9 * jj + 3 * ii
                        for (j in 0..7) {
                            pxj0 = px00 + pxdy * jj + pxdx * ii + sty * j
                            for (i in kk..kk+7) {
                                pxij = pxj0 + stx * i
                                if(pxij<0 || pxij>=dsize[kk]) continue
                                pixss[ij+kk] = pixss[ij+kk] + data[pxij].toInt().and(0xFF)
                            }
                        }
                    }
                }
            }
            for (ij3 in 0..26 step 3) {
                pix33[f27 + ij3]     = pixss[ij3]     / 64
                pix33[f27 + ij3 + 1] = pixss[ij3 + 1] / 64
                pix33[f27 + ij3 + 2] = pixss[ij3 + 2] / 64
                // answerL = answerL + "\n${pix33[f27 + ij3]} ${pix33[f27 + ij3 + 1]} ${pix33[f27 + ij3 + 2]}"
            }
            // println(answerL)
            // fac33get(pixdd,faceC) // pix33,faceCix,cicc,disC // faceC[6][3][3] = 1:6
            var kc = intArrayOf(5, 1, 4, 3, 7, 6)    // O- G1 G-
            if (cicc==2 && faceCix==3 && disC%4<2) { // O3 Y4 R5
                // answerL = answerL + "\npixcc "    // W6 B7 R-
                for (kp in 0..5) {
                    for (k in 0..2) {
                        pixdd[3 * kp + k] = pix33[f27 + 3 * kc[kp] + k]
                        // answerL = answerL + "${pixdd[3 * kp + k]} "
                    }
                }
                // println(answerL)
                // ccok = 1 // will be set by setcicc(ci)
            }
            var kf = faceCix - 1
            // answerL = answerL + "\nfac33 : "
            for (kr in 0..2) {
                for (kc in 0..2) {
                    var kcrf = kc + kr * 3 + kf * 9;
                    var ipmin = 32767;
                    var kpmin = kf;
                    for (kp in 0..5) {
                        var idif = 0;
                        for (k in 0..2) idif =
                            idif + Math.abs(pix33[3 * kcrf + k] - pixdd[3 * kp + k]);
                        if (idif <= ipmin) {
                            ipmin = idif;
                            kpmin = kp+1;
                        }
                    }
                    faceC[id54[kcrf]] = kpmin; // faceC[] = 1:6
                    // answerL = answerL + "$kpmin "
                }
            }  // -2 -4 -5 -6 -1 // RBLDF
            id33 = 0; for (k in 0..8) id33 = id33.shl(3) + faceC[9 * kf + k + 1]
            // answerL = answerL + ": $id33 : $faceCix"
            if(faceCix==faceC[49+kf]) {
                for(k in 0..8) {facff[k]=faceC[id54[9 * kf + k]];} // print("${facff[k]} ")}
                ffok=faceCix
            }
            if(cicc==2 && faceCix==3 && disC%4<2 && faceC[7]==4 && faceC[4]==2 && faceC[1]==1) {
                for(k in 0..17) pixcc[k]=pixdd[k]
                ddok=faceCix
            }
            // println(answerL)

            // viewBinding.solutionL.apply{this.setBackgroundColor(argbC[3]); text=answerL} // NG
            val luma = id33.toDouble()
            // val luma = pixels.average()

            listener(luma)

            image.close()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        // Request camera permissions
        if (allPermissionsGranted()) {
            // startCamera()
        } else {
            ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
            )
        }

        // Set up the listeners for take photo and video capture buttons
        // viewBinding.imageCaptureButton.setOnClickListener { takePhoto() }
        // viewBinding.videoCaptureButton.setOnClickListener { captureVideo() }
        viewBinding.face01Button.setOnClickListener { setFace01Color() }
        viewBinding.face02Button.setOnClickListener { setFace02Color() }
        viewBinding.face03Button.setOnClickListener { setFace03Color() }
        viewBinding.face04Button.setOnClickListener { setFace04Color() }
        viewBinding.face05Button.setOnClickListener { setFace05Color() }
        viewBinding.face06Button.setOnClickListener { setFace06Color() }
        viewBinding.face07Button.setOnClickListener { setFace07Color() }
        viewBinding.face08Button.setOnClickListener { setFace08Color() }
        viewBinding.face09Button.setOnClickListener { setFace09Color() }
        viewBinding.face10Button.setOnClickListener { setFace10Color() }
        viewBinding.face11Button.setOnClickListener { setFace11Color() }
        viewBinding.face12Button.setOnClickListener { setFace12Color() }
        viewBinding.face13Button.setOnClickListener { setFace13Color() }
        viewBinding.face14Button.setOnClickListener { setFace14Color() }
        viewBinding.face15Button.setOnClickListener { setFace15Color() }
        viewBinding.face16Button.setOnClickListener { setFace16Color() }
        viewBinding.face17Button.setOnClickListener { setFace17Color() }
        viewBinding.face18Button.setOnClickListener { setFace18Color() }
        viewBinding.face19Button.setOnClickListener { setFace19Color() }
        viewBinding.face20Button.setOnClickListener { setFace20Color() }
        viewBinding.face21Button.setOnClickListener { setFace21Color() }
        viewBinding.face22Button.setOnClickListener { setFace22Color() }
        viewBinding.face23Button.setOnClickListener { setFace23Color() }
        viewBinding.face24Button.setOnClickListener { setFace24Color() }
        viewBinding.face25Button.setOnClickListener { setFace25Color() }
        viewBinding.face26Button.setOnClickListener { setFace26Color() }
        viewBinding.face27Button.setOnClickListener { setFace27Color() }
        viewBinding.face28Button.setOnClickListener { setFace28Color() }
        viewBinding.face29Button.setOnClickListener { setFace29Color() }
        viewBinding.face30Button.setOnClickListener { setFace30Color() }
        viewBinding.face31Button.setOnClickListener { setFace31Color() }
        viewBinding.face32Button.setOnClickListener { setFace32Color() }
        viewBinding.face33Button.setOnClickListener { setFace33Color() }
        viewBinding.face34Button.setOnClickListener { setFace34Color() }
        viewBinding.face35Button.setOnClickListener { setFace35Color() }
        viewBinding.face36Button.setOnClickListener { setFace36Color() }
        viewBinding.face37Button.setOnClickListener { setFace37Color() }
        viewBinding.face38Button.setOnClickListener { setFace38Color() }
        viewBinding.face39Button.setOnClickListener { setFace39Color() }
        viewBinding.face40Button.setOnClickListener { setFace40Color() }
        viewBinding.face41Button.setOnClickListener { setFace41Color() }
        viewBinding.face42Button.setOnClickListener { setFace42Color() }
        viewBinding.face43Button.setOnClickListener { setFace43Color() }
        viewBinding.face44Button.setOnClickListener { setFace44Color() }
        viewBinding.face45Button.setOnClickListener { setFace45Color() }
        viewBinding.face46Button.setOnClickListener { setFace46Color() }
        viewBinding.face47Button.setOnClickListener { setFace47Color() }
        viewBinding.face48Button.setOnClickListener { setFace48Color() }
        viewBinding.face49Button.setOnClickListener { setFace49Color() }
        viewBinding.face50Button.setOnClickListener { setFace50Color() }
        viewBinding.face51Button.setOnClickListener { setFace51Color() }
        viewBinding.face52Button.setOnClickListener { setFace52Color() }
        viewBinding.face53Button.setOnClickListener { setFace53Color() }
        viewBinding.face54Button.setOnClickListener { setFace54Color() }
        viewBinding.face55Button.setOnClickListener { setFace55Color() }
        viewBinding.face56Button.setOnClickListener { solvecube() }
        viewBinding.face57Button.setOnClickListener { randomROT() }
        viewBinding.face58Button.setOnClickListener { changeMTH() }
        viewBinding.face59Button.setOnClickListener { traceROT(1) }
        viewBinding.face60Button.setOnClickListener { traceROT(-1) }
        viewBinding.face61Button.setOnClickListener { setciccX(1) }
        viewBinding.face62Button.setOnClickListener { setciccX(2) }
        viewBinding.face63Button.setOnClickListener { setalg3U() }
        viewBinding.solutionL.setOnClickListener { dispInfo() }

        cameraExecutor = Executors.newSingleThreadExecutor()

        if (savedInstanceState != null) { // For a previously destroyed instance.
            display48(t,-1)
        } else { // For a new instance.
            for (j in 1..54) {ti[j] = s[j]; tj[j] = s[j]; faceC[j] = s[j]}
            SetCXce(s) // set xc[6*6*6],xe[6*6],cc[6*6*6],ce[6*6]
            jtrace = 0; jtrmin = 0; nseed = -1
            AsyncTask.execute { setTable(2) }
        }
        cicc = 0; alg3U = 1; faceCix = 0; ddok = 0; ffok = 0; answer = " "; info = 0
        var kk = 0
        val externalStorageVolumes: Array<out File> =
            ContextCompat.getExternalFilesDirs(applicationContext, null)
        val fileratio = File(externalStorageVolumes[0], "dpratio.txt")
        if (!fileratio.exists()) {
            var ratbb = byteArrayOf(49.toByte(),46.toByte(),48.toByte(),
                20.toByte(),49.toByte(),46.toByte(),48.toByte(),
                20.toByte(),49.toByte(),46.toByte(),48.toByte(),
                20.toByte(),49.toByte(),46.toByte(),48.toByte(),
                20.toByte(),48.toByte(),46.toByte(),53.toByte(),
                20.toByte(),48.toByte(),46.toByte(),53.toByte(),
                20.toByte(),48.toByte(),46.toByte(),53.toByte(),
                20.toByte(),48.toByte(),46.toByte(),53.toByte())
            fileratio.writeBytes(ratbb) // 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5
        } else {
            var ratbb = fileratio.readBytes()
            var ratp = 0; var ratd = 1; var ratx = 1; kk = 0
            for(k in 0 until ratbb.size) {
                var ratk = ratbb[k].toInt() - 48
                if(ratk == -2) {ratx = 10; continue}
                if(ratk<0 || ratk>9) {
                    if (ratp == 0 && ratx == 1) continue // OK: 1  1.25  0.800  0.0  0.  .0
                    ratio[kk] = ratp.toDouble()/ratd.toDouble() // NG: 0  00
                    ratp = 0; ratd = 1; ratx = 1
                    if(kk >= 7) break
                    kk = kk + 1
                } else {
                    ratp = ratp * 10 + ratk
                    ratd = ratd * ratx
                }
            }
            if(ratp>0 || ratx>1) ratio[kk] = ratp.toDouble()/ratd.toDouble()
        }
        val filepixcc = File(externalStorageVolumes[0], "sixyuv.txt")
        if (!filepixcc.exists()) {
            disC = 1
            pixhh = intArrayOf(
                46,108,195,57,108,26,60, 93,91,
                51, 80,184,47,199,61,56,144,91)
            var answerL = "$disC : "
            for(k in 0..17) {answerL = answerL + "${pixhh[k]},"; pixdd[k] = pixhh[k]}
            var pixbb = answerL.toByteArray(Charsets.UTF_8)
            filepixcc.writeBytes(pixbb)
        } else {
            var pixbb = filepixcc.readBytes()
            disC = pixbb[0].toInt() - 48 // 2 disable color_calibration
            var valp = 0; kk = 0
            for (k in 1 until pixbb.size) {
                var valk = pixbb[k].toInt() - 48
                if (valk < 0 || valk > 9) {
                    if (valp == 0) continue
                    pixdd[kk] = valp
                    valp = 0
                    if (kk >= 17) break
                    kk = kk + 1
                } else {valp = valp * 10 + valk}
            }
            if (valp > 0) pixdd[kk] = valp
            // print("\n$disC : "); for (k in 0..17) print("${pixdd[k]},")
        }
        ccok = disC%4/2 // disC=2 : disable color_calibration
    }
    /*
    private fun takePhoto() {
        // Get a stable reference of the modifiable image capture use case
        val imageCapture = imageCapture ?: return

        // Create time stamped name and MediaStore entry.
        val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US)
            .format(System.currentTimeMillis())
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, name)
            put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
            if(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")
            }
        }

        // Create output options object which contains file + metadata
        val outputOptions = ImageCapture.OutputFileOptions
            .Builder(contentResolver,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                contentValues)
            .build()

        // Set up image capture listener, which is triggered after photo has
        // been taken
        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(exc: ImageCaptureException) {
                    Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
                }

                override fun
                        onImageSaved(output: ImageCapture.OutputFileResults){
                    val msg = "Photo capture succeeded: ${output.savedUri}"
                    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
                    Log.d(TAG, msg)
                }
            }
        )
    }

    // Implements VideoCapture use case, including start and stop capturing.
    private fun captureVideo() {
        val videoCapture = this.videoCapture ?: return

        viewBinding.videoCaptureButton.isEnabled = false

        val curRecording = recording
        if (curRecording != null) {
            // Stop the current recording session.
            curRecording.stop()
            recording = null
            return
        }

        // create and start a new recording session
        val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US)
            .format(System.currentTimeMillis())
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, name)
            put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4")
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/CameraX-Video")
            }
        }

        val mediaStoreOutputOptions = MediaStoreOutputOptions
            .Builder(contentResolver, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
            .setContentValues(contentValues)
            .build()
        recording = videoCapture.output
            .prepareRecording(this, mediaStoreOutputOptions)
            .apply {
                if (PermissionChecker.checkSelfPermission(this@MainActivity,
                        Manifest.permission.RECORD_AUDIO) ==
                    PermissionChecker.PERMISSION_GRANTED)
                {
                    withAudioEnabled()
                }
            }
            .start(ContextCompat.getMainExecutor(this)) { recordEvent ->
                when(recordEvent) {
                    is VideoRecordEvent.Start -> {
                        viewBinding.videoCaptureButton.apply {
                            text = getString(R.string.stop_capture)
                            isEnabled = true
                        }
                    }
                    is VideoRecordEvent.Finalize -> {
                        if (!recordEvent.hasError()) {
                            val msg = "Video capture succeeded: " +
                                    "${recordEvent.outputResults.outputUri}"
                            Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT)
                                .show()
                            Log.d(TAG, msg)
                        } else {
                            recording?.close()
                            recording = null
                            Log.e(TAG, "Video capture ends with error: " +
                                    "${recordEvent.error}")
                        }
                        viewBinding.videoCaptureButton.apply {
                            text = getString(R.string.start_capture)
                            isEnabled = true
                        }
                    }
                }
            }
    }
    */
    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
                }
            /*
            val recorder = Recorder.Builder()
                .setQualitySelector(QualitySelector.from(Quality.HIGHEST))
                .build()
            videoCapture = VideoCapture.withOutput(recorder)
            */
            // comment out ImageCapture and ImageAnalyzer use cases
            imageCapture = ImageCapture.Builder().build()

            val imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                        // if(luma != 0.0) Log.d(TAG, "Average luminosity: $luma")
                        /*
                        var k0 = (faceCix - 1) * 9
                        var answerL = "${dsize[0]} ${dsize[1]} ${dsize[2]} ${dsize[3]} ${dsize[4]} ${dsize[5]} ";
                        answerL = answerL + "$dpW $dpH $rtD : $faceCix\n"
                        for (j in 0..5) answerL = answerL + "${pixcc[3*j]} ${pixcc[3*j+1]} ${pixcc[3*j+2]}\n"
                        if(faceCix>0) for (j in 0..8) answerL = answerL + "${pix33[3*(k0+j)]} ${pix33[3*(k0+j)+1]} ${pix33[3*(k0+j)+2]} : ${fac33[k0+j]}\n"
                        // println(answerL)
                        */
                        if (faceCix > 0 && faceCix < 7) {
                            id33 = luma.toInt().and(0x7FFFFFF) // 9*3 bits
                            display48(t, -1) // faceC[]
                            // answerL = answerL + "id33 $id33"
                            // println(answerL)
                        }
                        // viewBinding.solutionL.apply {this.setBackgroundColor(argbC[3]); text = answerL} // NG
                        // println(answerL); // Log.d(TAG, answerL)
                    })
                }
            //

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture,  imageAnalyzer) // , videoCapture)

            } catch(exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }

        }, ContextCompat.getMainExecutor(this))
    }

    private fun stopCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            // Used to unbind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
            cameraProvider.unbindAll()
        }, ContextCompat.getMainExecutor(this))
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    companion object {
        private const val TAG = "RubikCubeSolver"
        private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS =
            mutableListOf (
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO
            ).apply {
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                    add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                }
            }.toTypedArray()
    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:
        IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
                finish()
            }
        }
    }

    /*
    private fun setFace01Color() {
        val iC = getNextColor(1)
        viewBinding.face01Button.apply {
            val button: Button = findViewById(R.id.face_01_button)
            this.setBackgroundColor(argbC[iC])
        }
    }
    */

    private fun setFace01Color(){var iC=getNextColor(1); viewBinding.face01Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace02Color(){var iC=getNextColor(2); viewBinding.face02Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace03Color(){var iC=getNextColor(3); viewBinding.face03Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace04Color(){var iC=getNextColor(4); viewBinding.face04Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace05Color(){var iC=getNextColor(5); viewBinding.face05Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace06Color(){var iC=getNextColor(6); viewBinding.face06Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace07Color(){var iC=getNextColor(7); viewBinding.face07Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace08Color(){var iC=getNextColor(8); viewBinding.face08Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace09Color(){var iC=getNextColor(9); viewBinding.face09Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace10Color(){var iC=getNextColor(10); viewBinding.face10Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace11Color(){var iC=getNextColor(11); viewBinding.face11Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace12Color(){var iC=getNextColor(12); viewBinding.face12Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace13Color(){var iC=getNextColor(13); viewBinding.face13Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace14Color(){var iC=getNextColor(14); viewBinding.face14Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace15Color(){var iC=getNextColor(15); viewBinding.face15Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace16Color(){var iC=getNextColor(16); viewBinding.face16Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace17Color(){var iC=getNextColor(17); viewBinding.face17Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace18Color(){var iC=getNextColor(18); viewBinding.face18Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace19Color(){var iC=getNextColor(19); viewBinding.face19Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace20Color(){var iC=getNextColor(20); viewBinding.face20Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace21Color(){var iC=getNextColor(21); viewBinding.face21Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace22Color(){var iC=getNextColor(22); viewBinding.face22Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace23Color(){var iC=getNextColor(23); viewBinding.face23Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace24Color(){var iC=getNextColor(24); viewBinding.face24Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace25Color(){var iC=getNextColor(25); viewBinding.face25Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace26Color(){var iC=getNextColor(26); viewBinding.face26Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace27Color(){var iC=getNextColor(27); viewBinding.face27Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace28Color(){var iC=getNextColor(28); viewBinding.face28Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace29Color(){var iC=getNextColor(29); viewBinding.face29Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace30Color(){var iC=getNextColor(30); viewBinding.face30Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace31Color(){var iC=getNextColor(31); viewBinding.face31Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace32Color(){var iC=getNextColor(32); viewBinding.face32Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace33Color(){var iC=getNextColor(33); viewBinding.face33Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace34Color(){var iC=getNextColor(34); viewBinding.face34Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace35Color(){var iC=getNextColor(35); viewBinding.face35Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace36Color(){var iC=getNextColor(36); viewBinding.face36Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace37Color(){var iC=getNextColor(37); viewBinding.face37Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace38Color(){var iC=getNextColor(38); viewBinding.face38Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace39Color(){var iC=getNextColor(39); viewBinding.face39Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace40Color(){var iC=getNextColor(40); viewBinding.face40Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace41Color(){var iC=getNextColor(41); viewBinding.face41Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace42Color(){var iC=getNextColor(42); viewBinding.face42Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace43Color(){var iC=getNextColor(43); viewBinding.face43Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace44Color(){var iC=getNextColor(44); viewBinding.face44Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace45Color(){var iC=getNextColor(45); viewBinding.face45Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace46Color(){var iC=getNextColor(46); viewBinding.face46Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace47Color(){var iC=getNextColor(47); viewBinding.face47Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace48Color(){var iC=getNextColor(48); viewBinding.face48Button.apply{this.setBackgroundColor(argbC[iC]); text=textC[iC]}}
    private fun setFace49Color(){if(cicc!=2) {faceCix= 1; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}
    private fun setFace50Color(){if(cicc!=2) {faceCix= 2; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}
    private fun setFace51Color(){faceCix= 3; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}
    private fun setFace52Color(){if(cicc!=2) {faceCix= 4; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}
    private fun setFace53Color(){if(cicc!=2) {faceCix= 5; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}
    private fun setFace54Color(){if(cicc!=2) {faceCix= 6; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}
    private fun setFace55Color(){if(cicc!=2) {faceCix= 0; viewBinding.face55Button.apply{this.setBackgroundColor(argbC[faceCix]); text=textC[faceCix]}}}

    private fun dispInfo():Unit {
        if(info<0) return
        info = info + 1
        if(info > 8) info = 0
        var answerL = " "
        when(info) {
            0 ->answerL="6(CCF) 48(CF) (3,M,I,C,F,B,P,S,T)-Buttons:\n" +
                    "\nCCF: C@P = C@CCF.   P: C@P = Pink." +
                    "\nCF: C@CF = C@P/Next.   M: Next Method." +
                    "\nT: Turn F@P or Random.   S: Solve." +
                    "\nF/B: Trace Forward/Backward." +
                    "\nI: camera Input.   C: Calibration." +
                    "\n8-Mth: F2L,SLL,BLL,QLL,'PLL,'OLL,'O+P, 'K2P." +
                    "\nCF = Cube Face.   CCF = Center CF." +
                    "\nC@P = Color at P.   F@P = Face at P."
            1 ->answerL="F2L = First 2 Layers.  LL = Last Layer.\n" +
                    "SLL = Simple LL. BLL/QLL = Better/Quick LL.\n" +
                    "OLL = Qrient LL.  PLL = Permute LL.\n" +
                    "O+P = OLL+PLL.  K2P = Kociemba 2 Phases.\n" +
                    "' = Modified:  'K2P = mK2P = Modified K2P.\n" +
                    "2 Trace modes depend on C@P = Pink/Else.\n" +
                    "C@CCF:(RGYOBW)=(123456)/(FRUBLD)-face\n" +
                    "-Rotate screen to replay-"
            2 ->answerL="SLL uses Basic Alg.:\n" +
                    "1a: +231-312; 1b: +213-132; 1c: -234+342\n" +
                    "2a: -3+2+3-2+3+2#3-2#3;     2b: -2a\n" +
                    "2c: +3+5-3-2+3-5-3+2;         2d: -2c\n" +
                    "2e: #3-2#3+2+3-2+3+2-3;    2f: -2e = 2aR\n" +
                    "3a: +y+2-6+2#3-2+6+2#3#2-y;     3b: -3a\n" +
                    "4a: -2+3-23232+323#2;               4b: -4a\n" +
                    "4e: #2X2-3#2X2+3;   4f: #X-3#2X2X+3#X"
            3 ->answerL="F2L is used for all human methods (1-7).\n" +
                    "For the Last Layer, method 1 uses only Alg. 1a,1b,2a,2b,3a,3b,4a,4b.\n" +
                    "Since 1b,2b,3b,4b can be completed by two 1a,2a,3a,4a, " +
                    "the required Alg. can be reduced to 1a,2a,3a,4a.\n" +
                    "But it is not recommended."
            4 ->answerL="BLL and QLL use the same Alg. as the SLL with more testings.\n\n" +
                    "Note that:\n" +
                    "SLL can complete the last layer in 5 steps or less."
            5 ->answerL="'OLL adds 3 Alg. for 2NGc:\n" +
                    "5a: +2+3-2-3-5 +3+2-3-2+5\n" +
                    "5b: #2+6-2#3 +2-6-2#3 -2\n" +
                    "5c: -5+2+3-2-3 +5+3+2-3-2\n\n" +
                    "5c = 5aR = 5a Reversed"
            6 ->answerL="'PLL adds 4 Alg. for fan, arrow & kite:\n" +
                    "6a: -x (+3-2+6#2-3+2-6)x2 +x (fan -/)\n" +
                    "6b: -x (-3+2-6#2+3-2+6)x2 +x (fan -\\)\n" +
                    "6c: -12+323 -23+21 -23+232 -12+1\n" +
                    "6d: +2-3+23-z#y +2-3+23#2-zy +23-232-y\n\n" +
                    "For details please visite:\n" +
                    "https://homepage.ntu.edu.tw/~twlin/"
            7 ->answerL="K2P uses 12-G0 + 18-G1 where:\n" +
                    "G0 = {F,R,B,L,U,D} : 18 face turns,\n" +
                    "G1 = {F2,R2,B2,L2,U,D} : 10 face turns.\n\n" +
                    "'K2P uses 12-G0 + 2-G4 + 17-G1 where:\n" +
                    "G2 = {F2,R2,B2,L2} : 4 face turns,\n" +
                    "G3 = G0-G1 = {F,F',R,R',B,B',L,L'} : 8 turns.\n" +
                    "G4 = G1-G2 = {U,D} : 6 face turns."
            8 ->answerL="dpratio.txt & sixYUV.txt can be edited.\n" +
                    "To disable color Calibration, change\n" +
                    "the first number (C) in sixYUV to 2.\n" +
                    "The first 4 numbers in dpratio are " +
                    "used to adjust P (px/dp) for screen " +
                    "rotate R in (0,90,180,270) degree.\n" +
                    "The last 4 numbers in dpratio are " +
                    "the crop ratio at bottom for each R."
        }
        viewBinding.solutionL.apply{this.setBackgroundColor(argbC[3]); text=answerL}
    }

    private fun randomROT():Unit {
        if(nseed<0) setTable(0)
        var nm: Int
        for(j in 1..54) t[j] = faceC[j]
        if(faceCix==0) {
            nm = 10 * (random() * 6.0 + 1.0).toInt() // 1:6
            nm = nm + (random() * 3.0 + 1.0).toInt() // 1:3
        } else {nm = 10*faceCix + 1}
        RotateA(t,1,nm)
        display48(t,1)
        return
    }

    private fun traceROT(stpi:Int):Unit {
        if(nseed<0) setTable(0)
        var ii=0
        var stp=stpi
        if(faceCix>0) {
            ni=nii[MTH]
            if(stp>0) {
                ii=ni; for(i in 1..ni) if(jtrace < rds[25*MTH+i]) {ii=i; break;}
                stp=rds[25*MTH+ii]-jtrace
            } else {
                ii=0; for(i in ni downTo 0) if(jtrace > rds[25*MTH+i]) {ii=i; break;}
                stp=rds[25*MTH+ii]-jtrace
            }
        }
        jtrace = jtrace + stp
        if(jtrace<0) jtrace=0
        if(jtrace>jtrmin) jtrace=jtrmin
        dispAns()
        display48(t,jtrace)
        return
    }

    private fun changeMTH():Unit {
        if(nseed<0) setTable(0)
        if(MTH<0) {MTH=6; for(j in 1..54) t[j] = tj[j]} // MTH=-1 or 7 after solve
        MTH=MTH+1
        if(MTH>7) MTH=0
        var ni=nii[MTH]
        if(ni==0) rds[25*MTH]=0
        var nt=rds[25*MTH+ni]
        for(j in 1..nt) RotateA(t,j,rdd[125*MTH+j])
        jtrmin=nt
        jtrace=0
        dispAns()
        display48(t,jtrace)
        return
    }

    private fun setciccX(ci:Int):Unit {
        /* No show no use
        if(ci<=0) {
            answerL = "Please wait ${1-ci} seconds!.\nPlease wait ${1-ci} seconds!.."
            viewBinding.solutionL.apply{this.setBackgroundColor(argbC[3-ci]); text=answerL}
            println(answerL)
            return
        }
        */
        info = -1
        dpW = getResources().getConfiguration().screenWidthDp  // 360 592  423 705
        dpH = getResources().getConfiguration().screenHeightDp // 568 336  681 399
        var answerL = " "
        if(disC%4 >=2 && ci==2) return // C-Button disabled by sixyuv.txt edited by user
        if(faceCix!=3 && ci==2) return // ignor for tap C by mistake
        if(cicc==1) {viewBinding.face61Button.apply{text="I"}
            if(ffok>0) {
                var k0 = 9 * (ffok - 1)
                for (j in 0..8) faceC[id54[k0 + j]] = facff[j]
                display48(t, -1)
            }
        }
        if(cicc==2) {viewBinding.face62Button.apply{text="C"};
            val externalStorageVolumes: Array<out File> =
                ContextCompat.getExternalFilesDirs(applicationContext, null)
            if(ddok>0 && ffok>0) {
                ccok = 1
                val filepixcc = File(externalStorageVolumes[0], "sixyuv.txt")
                if (disC%4 < 2) { // disC%4=2 : disable color_calibration
                    if(disC%4 < 1) disC = disC + 1
                    answerL = "$disC : "
                    for (k in 0..17) answerL = answerL + "${pixcc[k]},"
                    var pixbb = answerL.toByteArray(Charsets.UTF_8)
                    filepixcc.writeBytes(pixbb) // 1 : 255,...,200,
                    // println("################################## $filepixcc\n" + answerL)
                }
            }
            ///*
            if (disC >= 4) {
                val fileimg0 = File(externalStorageVolumes[0], "image0.txt")
                fileimg0.writeBytes(image0)
                val fileimg1 = File(externalStorageVolumes[0], "image1.txt")
                fileimg1.writeBytes(image1)
                val fileimg2 = File(externalStorageVolumes[0], "image2.txt")
                fileimg2.writeBytes(image2)
                val filepixcc = File(externalStorageVolumes[0], "sixyuv.txt")
                val file1 = File(this.externalCacheDir, "sixyuv.txt")
                var pixbb = filepixcc.readBytes()
                file1.writeBytes(pixbb)
            }
            //*/
        }
        /*
        var dxx = DoubleArray(10)
        dxx[0]=getResources().getDisplayMetrics().scaledDensity.toDouble() // 3.9       2.75
        dxx[1]=getResources().getDisplayMetrics().density.toDouble()       // 3.0       2.75
        dxx[2]=getResources().getDisplayMetrics().widthPixels.toDouble()   // 1080      1080
        dxx[3]=getResources().getDisplayMetrics().heightPixels.toDouble()  // 1776      2154
        dxx[4]=getResources().getDisplayMetrics().densityDpi.toDouble()    // 480       440
        dxx[5]=getResources().getDisplayMetrics().xdpi.toDouble()          // 428.625   440
        dxx[6]=getResources().getDisplayMetrics().ydpi.toDouble()          // 424.069   440
        dxx[7]=dxx[4]/dxx[5] // 428.625*px2dp[0] = 480
        for(k in 0..7) println("$k ${dxx[k]}")
        */
        var answerY = "\nC Y : $disC :"; var answerU = "\nU :"; var answerV = "\nV :"
        for (k in 0..17 step 3) {
            answerY = answerY + " ${pixdd[k]}"
            answerU = answerU + " ${pixdd[k+1]}"
            answerV = answerV + " ${pixdd[k+2]}"
        }
        answer = answerY + answerU + answerV
        answerL = "Tap I/C for camera Input/Calibratiom."
        answerL = answerL + "\nData follows can be igonored:"
        answerL = answerL + "\nImage byte : ${dsize[0]} ${dsize[1]} ${dsize[2]}"
        answerL = answerL + "\nSn-dp Im-px R : ${dsize[6]} ${dsize[7]} ${dsize[8]} ${dsize[9]} ${dsize[3]}"
        answerL = answerL + "\nCX TY BO DX P : ${dsize[10]} ${dsize[11]} ${dsize[4]} ${dsize[13]} ${dsize[5]}%"
        answerL = answerL + "\ndpratio : ${ratio[0]} ${ratio[1]} ${ratio[2]} ${ratio[3]}"
        answerL = answerL + " ${ratio[4]} ${ratio[5]} ${ratio[6]} ${ratio[7]}" + answer
        viewBinding.solutionL.apply{this.setBackgroundColor(argbC[3]); text=answerL}
        viewBinding.lineH1.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineH2.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineH3.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineH4.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineV1.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineV2.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineV3.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineV4.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineX1.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineX2.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineX3.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineX4.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineY1.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineY2.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineY3.apply { this.setBackgroundColor(argbC[7]) }
        viewBinding.lineY4.apply { this.setBackgroundColor(argbC[7]) }
        // println(answerL);
        if(cicc==ci) {stopCamera(); cicc=0; return} // {onDestroy(); cicc=0; return}
        if(ci==1) {
            if(ccok==0 && disC%4==0) {
                answerL = "Please Tap Y-CCF then Tap C \nfor color calibration."
                viewBinding.solutionL.apply{this.setBackgroundColor(argbC[3]); text=answerL}
                // println(answerL);
                return
            }
            viewBinding.face61Button.apply{text="#"}
            answerL = "Tap CCF for each face inside region.\nIf correct Tap another CCF or # or P.\nTap # and P after finish all faces."
        }
        if(ci==2) {
            viewBinding.face62Button.apply{text="#"}
            answerL = "Use a solved cube \nturn -2 -4 -5 -6 -1 (R B L D F)\nto get Y-face below for calibration\nO G G\nO Y R\nW B R\nTap Y-CCF then Tap C.\nMatch Y-face to region and Tap # at C."
            ddok = 0
        }
        if(cicc==0) startCamera() // {var faceT = faceCix; faceCix = 0; startCamera(); faceCix = faceT}
        cicc=ci; ffok=0; answer = " "
        /* for debug
        answerL = answerL + "\n${dsize[0]} ${dsize[1]} ${dsize[2]} ${dsize[3]} ${dsize[4]} ${dsize[5]}\n$dpW $dpH $rtD\n"
        for(j in 0..5) answerL = answerL + "${pixcc[3*j]} ${pixcc[3*j+1]} ${pixcc[3*j+2]}\n"
        for(j in 0..8) answerL = answerL + "${faceC[j+1]} "
        answerL = answerL + ": $id33 : $cicc $ci"
        */
        viewBinding.solutionL.apply{this.setBackgroundColor(argbC[7]); text=answerL}
        if(dpW <= dpH) {
            viewBinding.lineX1.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineX2.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineX3.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineX4.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineY1.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineY2.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineY3.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineY4.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineH1.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineH2.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineH3.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineH4.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineV1.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineV2.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineV3.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineV4.apply { this.setBackgroundColor(argbC[6]) }
        } else {
            viewBinding.lineH1.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineH2.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineH3.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineH4.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineV1.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineV2.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineV3.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineV4.apply { this.setBackgroundColor(argbC[7]) }
            viewBinding.lineX1.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineX2.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineX3.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineX4.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineY1.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineY2.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineY3.apply { this.setBackgroundColor(argbC[6]) }
            viewBinding.lineY4.apply { this.setBackgroundColor(argbC[6]) }
        }
        // println(answerL)
        return
    }

    private fun setalg3U():Unit {
        alg3U = -alg3U
        if(alg3U>0) viewBinding.face63Button.apply{text="3"}
        if(alg3U<0) viewBinding.face63Button.apply{text="U"}
        // display48(t,-1)
        return
    }

    private fun dispAns():Unit {
        // int nii[8],rds[8][25],rdd[8][125],MTH,jtrmin,jtrace;
        var mLL = arrayOf(" F2L"," SLL"," BLL"," QLL","'PLL","'OLL","'O+P","'K2P")
        var CHa = arrayOf(" ","F","R","U","B","L","D","X","Y","Z")
        var CHb = arrayOf(" ","'","2"," ")
        var CHm = arrayOf(" ","+","#","-")
        var Spc = " "
        var nm: Int
        var n : Int
        var m : Int
        var ni=nii[MTH]
        var nt=rds[25*MTH+ni]
        jtrmin=nt
        var answerL = "$jtrmin${mLL[MTH]}:"
        var answerR = "$jtrmin${mLL[MTH]}:"
        for(k in 1..ni) {
            for(i in rds[25*MTH+k-1]+1..rds[25*MTH+k]) {
                nm = rdd[125*MTH+i]; n=nm/10; m=nm%10;
                if(i==rds[25*MTH+k]) {
                    if(i==jtrace) Spc = "!" else Spc = ":"
                } else {
                    if(i==jtrace) Spc = "|" else Spc = " "
                }
                answerL = answerL + "${CHm[m]}$n" + Spc
                answerR = answerR + "${CHa[n]}${CHb[m]}" + Spc
            }}
        // println(answerL)
        if(alg3U>0) {if(jtrmin<=72) answerL=answerL+"\n"+answerR}
        if(alg3U<0) {if(jtrmin<=72) answerL=answerR+"\n"+answerL else answerL=answerR}
        if(MTH==7) {
            answerL = answerL + "\n\n"
            for (i in 0..7) {
                ni = nii[i]; nt = rds[25 * i + ni]; answerL = answerL + "$nt "
                if(i%3==0) answerL = answerL + " "
            }
        }
        viewBinding.solutionL.apply{this.setBackgroundColor(argbC[6]); text=answerL}
    }

    private fun getNextColor(ix: Int): Int {
        if(nseed<0) setTable(0)
        if (faceCix > 0) { faceC[ix] = faceCix }
        else { faceC[ix] = faceC[ix]%6 + 1 }
        return faceC[ix]
    }

    private fun setTable(idfi:Int):Unit {
        // if(nseed>=0) return
        // nseed = 99
        if(idfi<1) return
        if(idfi>1) {idf = idfi; nseed = 99}
        if(idf==0 && q1[2519] == 25181 && q2[2519] == 25181 &&
            p0[1] == 1567131842 && x0[1] == 136160 &&
            p1[1] == 24092373 && x1[1] == 213824) return
        Setq1()   // set mq1,q1[]
        if(idf==0) return
        Setp0()   // set mp0,x0[],p0[],m0[]
        if(idf==0) return
        Setp1()   // set mp1,x1[],p1[],m1[]
        idf = 0
        return
    }

    private fun solvecube(){
        var nm: Int
        var nt: Int
        var ng: Int
        //  bmpFILE = arrayOf("pp1a.bmp","pp1b.bmp","pp2a.bmp","pp2b.bmp")
        //  ti  = IntArray(55)
        //  nmt = IntArray(205) // nmt[5][41]
        var nnt = IntArray(5)
        var nng = IntArray(5)
        var fc  = IntArray(7)
        var xx  = IntArray(23) // x[20]+c3+e2+p1
        var o = intArrayOf(0,2,3,1,5,6,4, 3,1,2,6,4,5, 2,3,1,5,6,4)
        var q = intArrayOf(
            3,1,2, 14,15,13, 18,16,17, 5,6,4,
            11,12,10,24,22,23, 20,21,19, 9,7,8,
            28,27, 42,41, 36,35, 44,43,
            32,31, 48,47, 40,39, 46,45,
            25,26, 33,34, 37,38, 29,30,
            51,49,50, 54,52,53)

        no1 = 2
        no2 = 2
        // nseed = 99
        // nl1 = 9
        // nl2 = 12
        // nr = 9
        // Log.d(TAG, "Photo0 ")
        // SetCXce(s) // set xc[6*6*6],xe[6*6],cc[6*6*6],ce[6*6]
        // Setq1()    // set mq1,q1[]
        // Setp0()    // set mp0,x0[],p0[],m0[]
        // Setp1()    // set mp1,x1[],p1[],m1[],d1[]
        /*
        var nm: Int
        for(j in 1..54) t[j] = s[j]
        for(k in 1..nr) {
            nm = 10*(random()*6.0 + 1.0).toInt() // 1:6
            nm = nm+(random()*3.0 + 1.0).toInt() // 1:3
            RotateA(t,k,nm)
            display48(t,k)
            // print("$nm "); if(k%20==0 || k==nr) print("\n")
        }
        */
        // var answerL = "\nPLEASE WAIT\n"
        // viewBinding.solutionL.apply{this.setBackgroundColor(argbC[6]); text=answerL}
        // setciccX(-3); setciccX(-2); setciccX(-1) // No show no use
        setTable(1)
        MTH=-1 // for changeMTH()
        for(j in 1..54) {t[j] = faceC[j]; ti[j]=t[j]}
        ng = NGFace9(t,fc); if(ng>0) {dispERR(fc); return}
        ng = NGCubIC(t,xx); if(ng>0) {dispERC(xx); return}
        viewBinding.face56Button.apply{text = textC[6]}
        for(k in 0..2) { // setciccX(k-3) // No show no use
            nt = PhaseONE()
            if(ntg > nto) ntg = nto
            // print("\n$nto  ")                    // printf("\n%4d  ",nto);
            // for(j in 1..nto) print(" ${nmo[j]}") // printf("%3d",nmo[j]); printf("\n");
            for(j in 1..nto) nmt[41*k+j] = nmo[j]; nnt[k] = nto; nng[k] = ntg;
            if(k > 0) {nnt[k+2] = nto; nng[k+2] = ntg; for(j in 1..nto) {
                nmt[41*(k+2)+j] = 10*o[6*k+(nmo[j]/10).toInt()] + (nmo[j]%10)
            }}
            for(j in 1..54) t[j+54] = o[t[j]]
            for(j in 1..54) t[j] = t[q[j-1]+54]
        }
        /*
        for(k in 0..4) {
            print("\n${nnt[k]}  ")                       // printf("\n%4d  ",nnt[k]);
            for(j in 1..nnt[k]) print(" ${nmt[41*k+j]}") // printf("%3d",nmt[41*k+j]);
        }
        print("\n")
        print48(ti,0,"o")
        */
        kmin = 0
        var ok = 0
        for(k in 0..4) {
            if(k == 1 || k == 2) continue
            for(j in 1..54) t[j] = ti[j]
            for(j in 1..nnt[k]) RotateA(t,j,nmt[41*k+j])
            // print48(t,nnt[k],"n")
            var ng = NGRubik(t,nnt[k])
            if(ng == 0) {
                ok = ok + 1
                if(ok == 1) {kmin = k; continue}
                if(nnt[kmin] > nnt[k]) kmin = k
            }
        }
        jtrace = 0
        jtrmin = 0
        if(ok > 0) jtrmin = nnt[kmin]

        MTH=7; nt=nnt[kmin];
        nii[MTH]=2; rds[25*MTH]=0; rds[25*MTH+1]=nng[kmin]; rds[25*MTH+2]=nt;
        for(j in 1..nt) {
            rdd[125*MTH+j] = nmt[41*kmin+j]
        }

        for(LLV in 0..6) { // get steps for MTH=0:6
            if(LLV==0)      {PLL=0; OLL=0; SLL=0;}
            else if(LLV<=3) {PLL=1; OLL=1; SLL=LLV;}
            else if(LLV==4) {PLL=4; OLL=1; SLL=0;}
            else if(LLV==5) {PLL=1; OLL=4; SLL=0;}
            else            {PLL=4; OLL=4; SLL=0;}
            kkkk=0;
            // Solve Rubik Cube
            for(j in 1..54) t[j] = ti[j]
            var nx=CubeSolver(0) // get steps for MTH=0:6
            nii[LLV]=ni; // nx=rds[ni];
            for(i in 0..ni) rds[i+25*LLV]=rdi[i];
            for(i in 0..nx) rdd[i+125*LLV]=rd[i];
        }

        for(j in 1..54) t[j] = ti[j]
        ni=nii[MTH]
        nt=rds[25*MTH+ni]
        for(j in 1..nt) {
            nm = rdd[125*MTH+j]
            RotateA(t,j,nm)
        }
        jtrace=0
        jtrmin=nt
        for(j in 1..54) tj[j] = ti[j]
        dispAns()
        display48(t,jtrace)
        viewBinding.face56Button.apply{text = textC[7]}
    }

    private fun PhaseONE():Int {
        // int t[2161],x[400]; // t[40][54],x[20][20]: t[1:54] x[0:20]
        // int nm1[16],ks[41],ki[6*6*3];
        // int mx,L,L1,i12,j; // n1,n3,nt0
        // int i0,i1,i2,i3,i4,i5,i6,i7,i8,i9; // replace i[10]
        // int k0,k1,k2,k3,k4,k5,k6,k7,k8,k9; // replace k[10]
        var n  = IntArray(19)
        var ks = IntArray(19)
        var i12: Int
        var L:   Int
        print48(t,0,"one")
        for(j in 1..40) xs[j]=0
        nxa = 40
        nxb = 1
        ioa = 0
        iob = 0
        io1 = 0
        var i0 = 0
        L = 0; n[L] = 0; nm1[L] = 0; ks[L] = 0
        n3=phase1(L); if(n3>=0) {return n3}
        for(L1 in 1..9) {          // 1,12 7,7 8,12
            for(j in 0..L1) n[j] = 0 // n[0:L1] = 0
            L = 1
            for(i1 in 1..6) {                 // for i(L)=1,6
                i12 = i0 - i1                     // 1+4,2+5 but not 4+1,5+2
                if(i12 == 0 || i12 == 3) continue // continue for-loop
                for(k1 in 1..3) {                 // for k(L)=1,3
                    n[L] = n[L] + 1
                    nm1[L] = 10 * i1 + k1
                    RotateA(t,L,nm1[L])
                    if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                    L = 2
                    for(i2 in 1..6) {                 // for i(L)=1,6
                        i12 = i1 - i2                     // 1+4,2+5 but not 4+1,5+2
                        if(i12 == 0 || i12 == 3) continue // continue for-loop
                        for(k2 in 1..3) {                 // for k(L)=1,3
                            n[L] = n[L] + 1
                            nm1[L] = 10 * i2 + k2
                            RotateA(t,L,nm1[L])
                            if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                            L = 3
                            for(i3 in 1..6) {                 // for i(L)=1,6
                                i12 = i2 - i3                     // 1+4,2+5 but not 4+1,5+2
                                if(i12 == 0 || i12 == 3) continue // continue for-loop
                                for(k3 in 1..3) {                 // for k(L)=1,3
                                    n[L] = n[L] + 1
                                    nm1[L] = 10 * i3 + k3
                                    RotateA(t,L,nm1[L])
                                    if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                    L = 4
                                    for(i4 in 1..6) {                 // for i(L)=1,6
                                        i12 = i3 - i4                     // 1+4,2+5 but not 4+1,5+2
                                        if(i12 == 0 || i12 == 3) continue // continue for-loop
                                        for(k4 in 1..3) {                 // for k(L)=1,3
                                            n[L] = n[L] + 1
                                            nm1[L] = 10 * i4 + k4
                                            RotateA(t,L,nm1[L])
                                            if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                            L = 5
                                            for(i5 in 1..6) {                 // for i(L)=1,6
                                                i12 = i4 - i5                     // 1+4,2+5 but not 4+1,5+2
                                                if(i12 == 0 || i12 == 3) continue // continue for-loop
                                                for(k5 in 1..3) {                 // for k(L)=1,3
                                                    n[L] = n[L] + 1
                                                    nm1[L] = 10 * i5 + k5
                                                    RotateA(t,L,nm1[L])
                                                    if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                                    L = 6
                                                    for(i6 in 1..6) {                 // for i(L)=1,6
                                                        i12 = i5 - i6                     // 1+4,2+5 but not 4+1,5+2
                                                        if(i12 == 0 || i12 == 3) continue // continue for-loop
                                                        for(k6 in 1..3) {                 // for k(L)=1,3
                                                            n[L] = n[L] + 1
                                                            nm1[L] = 10 * i6 + k6
                                                            RotateA(t,L,nm1[L])
                                                            if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                                            L = 7
                                                            for(i7 in 1..6) {                 // for i(L)=1,6
                                                                i12 = i6 - i7                     // 1+4,2+5 but not 4+1,5+2
                                                                if(i12 == 0 || i12 == 3) continue // continue for-loop
                                                                for(k7 in 1..3) {                 // for k(L)=1,3
                                                                    n[L] = n[L] + 1
                                                                    nm1[L] = 10 * i7 + k7
                                                                    RotateA(t,L,nm1[L])
                                                                    if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                                                    L = 8
                                                                    for(i8 in 1..6) {                 // for i(L)=1,6
                                                                        i12 = i7 - i8                     // 1+4,2+5 but not 4+1,5+2
                                                                        if(i12 == 0 || i12 == 3) continue // continue for-loop
                                                                        for(k8 in 1..3) {                 // for k(L)=1,3
                                                                            n[L] = n[L] + 1
                                                                            nm1[L] = 10 * i8 + k8
                                                                            RotateA(t,L,nm1[L])
                                                                            if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                                                            L = 9
                                                                            for(i9 in 1..6) {                 // for i(L)=1,6
                                                                                i12 = i8 - i9                     // 1+4,2+5 but not 4+1,5+2
                                                                                if(i12 == 0 || i12 == 3) continue // continue for-loop
                                                                                for(k9 in 1..3) {                 // for k(L)=1,3
                                                                                    n[L] = n[L] + 1
                                                                                    nm1[L] = 10 * i9 + k9
                                                                                    RotateA(t,L,nm1[L])
                                                                                    if(L==L1) {n3=phase1(L); if(n3>=0) {return n3} else {continue}}
                                                                                }};L=8}};L=7}};L=6}};L=5}};L=4}};L=3}};L=2}};L=1}}
        }
        return nt0
    }

    private fun phase1(L:Int):Int {
        var px = t2p0(t,L)
        var mx = bSearch(p0,x0,mp0,px) // Search solution from Table p0[mp0]
        // if(L<=1 || mx>=0) print("$L $px $mx\n")
        if(mx < 0) return mx           // Not find
        mx = m0[mx]                    // Find the solution m0[mx]
        n1 = p2nm0(mx,nm1,L)
        n1 = L + n1
        for(j in (L+1)..n1) RotateA(t,j,nm1[j])
        // print("\n$px $mx $L ${n1-L} $n1 ") // printf("\n%9X%8X%6d%3d%3d ",px,mx,L,n1-L,n1);
        // for(j in 1..n1) print(" ${nm1[j]}"); print("\n") // printf("%3d",nm1[j]);
        CubicIC(t,n1,x)
        var nt0 = PhaseTWO()
        ntg = n1
        io1 = io1 + 1
        if(io1 >= no1) return nt0
        return -1
    }

    private fun PhaseTWO():Int { // x[],nm1[n1],n1
        // int x[480]; // x[24][20] // x[0:19] = 0:19
        // int nm2[24],nms[40];
        // int nt2,L,L2,i12,j,ju,jd; // n1,n2,(n4),nt,nto,iu,id,iok,io2
        // int i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,ia,ib,ic;
        // int k0,k1,k2,k3,k4,k5,k6,k7,k8,k9,ka,kb,kc;
        var n  = IntArray(19)
        val kL = intArrayOf(1,2,2,1,2,2,1)
        val kU = intArrayOf(3,2,2,3,2,2,3)
        var i12: Int
        var i0:  Int
        var L:   Int
        io2 = 0;
        i0 = 0; L = 0; n[L] = 0; nm2[L] = 0
        n4=phase2(L); if(n4>=0) {return n4}
        for(L2 in 1..12) {
            for(j in 0..L2) n[j] = 0              // n[0:L2] = 0
            L = 1
            for(i1 in 1..6) {                     // for i(L)=1,6
                if(L==L2) {if(i1==3||i1==6) continue} // for Last step NO U,D-turn
                i12 = i0 - i1                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                if(i12==0 || i12==3) continue         // continue for-loop
                for(k1 in kL[i1]..kU[i1]) {           // for k(L)=kL[i],kU[i]
                    n[L] = n[L] + 1
                    nm2[L] = 10 * i1 + k1
                    RotateB(x,L,nm2[L])
                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                    L = 2
                    for(i2 in 1..6) {                     // for i(L)=1,6
                        if(L==L2) {if(i2==3||i2==6) continue} // for Last step NO U,D-turn
                        i12 = i1 - i2                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                        if(i12==0 || i12==3) continue         // continue for-loop
                        for(k2 in kL[i2]..kU[i2]) {           // for k(L)=kL[i],kU[i]
                            n[L] = n[L] + 1
                            nm2[L] = 10 * i2 + k2
                            RotateB(x,L,nm2[L])
                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                            L = 3
                            for(i3 in 1..6) {                     // for i(L)=1,6
                                if(L==L2) {if(i3==3||i3==6) continue} // for Last step NO U,D-turn
                                i12 = i2 - i3                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                if(i12==0 || i12==3) continue         // continue for-loop
                                for(k3 in kL[i3]..kU[i3]) {           // for k(L)=kL[i],kU[i]
                                    n[L] = n[L] + 1
                                    nm2[L] = 10 * i3 + k3
                                    RotateB(x,L,nm2[L])
                                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                    L = 4
                                    for(i4 in 1..6) {                     // for i(L)=1,6
                                        if(L==L2) {if(i4==3||i4==6) continue} // for Last step NO U,D-turn
                                        i12 = i3 - i4                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                        if(i12==0 || i12==3) continue         // continue for-loop
                                        for(k4 in kL[i4]..kU[i4]) {           // for k(L)=kL[i],kU[i]
                                            n[L] = n[L] + 1
                                            nm2[L] = 10 * i4 + k4
                                            RotateB(x,L,nm2[L])
                                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                            L = 5
                                            for(i5 in 1..6) {                     // for i(L)=1,6
                                                if(L==L2) {if(i5==3||i5==6) continue} // for Last step NO U,D-turn
                                                i12 = i4 - i5                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                if(i12==0 || i12==3) continue         // continue for-loop
                                                for(k5 in kL[i5]..kU[i5]) {           // for k(L)=kL[i],kU[i]
                                                    n[L] = n[L] + 1
                                                    nm2[L] = 10 * i5 + k5
                                                    RotateB(x,L,nm2[L])
                                                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                    L = 6
                                                    for(i6 in 1..6) {                     // for i(L)=1,6
                                                        if(L==L2) {if(i6==3||i6==6) continue} // for Last step NO U,D-turn
                                                        i12 = i5 - i6                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                        if(i12==0 || i12==3) continue         // continue for-loop
                                                        for(k6 in kL[i6]..kU[i6]) {           // for k(L)=kL[i],kU[i]
                                                            n[L] = n[L] + 1
                                                            nm2[L] = 10 * i6 + k6
                                                            RotateB(x,L,nm2[L])
                                                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                            L = 7
                                                            for(i7 in 1..6) {                     // for i(L)=1,6
                                                                if(L==L2) {if(i7==3||i7==6) continue} // for Last step NO U,D-turn
                                                                i12 = i6 - i7                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                if(i12==0 || i12==3) continue         // continue for-loop
                                                                for(k7 in kL[i7]..kU[i7]) {           // for k(L)=kL[i],kU[i]
                                                                    n[L] = n[L] + 1
                                                                    nm2[L] = 10 * i7 + k7
                                                                    RotateB(x,L,nm2[L])
                                                                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                    L = 8
                                                                    for(i8 in 1..6) {                     // for i(L)=1,6
                                                                        if(L==L2) {if(i8==3||i8==6) continue} // for Last step NO U,D-turn
                                                                        i12 = i7 - i8                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                        if(i12==0 || i12==3) continue         // continue for-loop
                                                                        for(k8 in kL[i8]..kU[i8]) {           // for k(L)=kL[i],kU[i]
                                                                            n[L] = n[L] + 1
                                                                            nm2[L] = 10 * i8 + k8
                                                                            RotateB(x,L,nm2[L])
                                                                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                            L = 9
                                                                            for(i9 in 1..6) {                     // for i(L)=1,6
                                                                                if(L==L2) {if(i9==3||i9==6) continue} // for Last step NO U,D-turn
                                                                                i12 = i8 - i9                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                                if(i12==0 || i12==3) continue         // continue for-loop
                                                                                for(k9 in kL[i9]..kU[i9]) {           // for k(L)=kL[i],kU[i]
                                                                                    n[L] = n[L] + 1
                                                                                    nm2[L] = 10 * i9 + k9
                                                                                    RotateB(x,L,nm2[L])
                                                                                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                                    L = 10
                                                                                    for(ia in 1..6) {                     // for i(L)=1,6
                                                                                        if(L==L2) {if(ia==3||ia==6) continue} // for Last step NO U,D-turn
                                                                                        i12 = i9 - ia                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                                        if(i12==0 || i12==3) continue         // continue for-loop
                                                                                        for(ka in kL[ia]..kU[ia]) {           // for k(L)=kL[i],kU[i]
                                                                                            n[L] = n[L] + 1
                                                                                            nm2[L] = 10 * ia + ka
                                                                                            RotateB(x,L,nm2[L])
                                                                                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                                            L = 11
                                                                                            for(ib in 1..6) {                     // for i(L)=1,6
                                                                                                if(L==L2) {if(ib==3||ib==6) continue} // for Last step NO U,D-turn
                                                                                                i12 = ia - ib                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                                                if(i12==0 || i12==3) continue         // continue for-loop
                                                                                                for(kb in kL[ib]..kU[ib]) {           // for k(L)=kL[i],kU[i]
                                                                                                    n[L] = n[L] + 1
                                                                                                    nm2[L] = 10 * ib + kb
                                                                                                    RotateB(x,L,nm2[L])
                                                                                                    if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                                                    L = 12
                                                                                                    for(ic in 1..6) {                     // for i(L)=1,6
                                                                                                        if(L==L2) {if(ic==3||ic==6) continue} // for Last step NO U,D-turn
                                                                                                        i12 = ib - ic                         // 1+4,2+5,3+6 but not 4+1,5+2,6+3
                                                                                                        if(i12==0 || i12==3) continue         // continue for-loop
                                                                                                        for(kc in kL[ic]..kU[ic]) {           // for k(L)=kL[i],kU[i]
                                                                                                            n[L] = n[L] + 1
                                                                                                            nm2[L] = 10 * ic + kc
                                                                                                            RotateB(x,L,nm2[L])
                                                                                                            if(L==L2) {n4=phase2(L); if(n4>=0) {return n4} else {continue}}
                                                                                                        }};L=11}};L=10}};L=9}};L=8}};L=7}};L=6}};L=5}};L=4}};L=3}};L=2}};L=1}}
        } // end L2
        return nto
    }

    private fun phase2(L:Int):Int {
        // int j,px,mx,ju,jd,nt2; // n1,n2,(n4),nt,nto,iu,id,iok,io1,io2
        // p2x(px,&x[20*L]);
        var (px, iuu, idd) = x2p1(x,L); iu = iuu; id = idd
        var mx = bSearch(p1,x1,mp1,px) // Search solution from Table p1[mp1]
        // if(L<=1 || mx>=0) print("$L $iu $id $px $mx\n")
        if(mx < 0) return mx           // goto L50;     // Not find
        var ju = m1[mx].and(0x0F)      // Find the solution m1[mx],d1[mx]
        var jd = ju / 4
        mx = m1[mx].shr(4)
        ju = ju - jd * 4
        iu = iu - ju
        id = jd - id
        if(iu < 0) iu = iu + 4
        if(id < 0) id = id + 4
        nt = L
        if(id > 0) {
            nt = nt + 1
            nm2[nt] = 60 + id
        }
        if(iu > 0) {
            nt = nt + 1
            nm2[nt] = 30 + iu
        }
        var nt2 = p2nm1(mx,nm2,nt)
        n2 = nt + nt2
        // printf("\n%9X%9X%3d%2d%3d%3d ",px,mx,L,nt-L,nt2,n2);
        // print("\n$px $mx $L ${nt-L} $nt2 $n2 ")
        // for(j in 1..n2) print(" ${nm2[j]}") // printf("%3d",nm2[j]);
        nt = n1 + n2
        for(j in 1..n1) nms[j] = nm1[j];
        for(j in 1..n2) nms[j+n1] = nm2[j];
        io2 = io2 + 1
        iok = no2*io1 + io2
        // printf("\n%5d%5d%4d%4d            ",iok,n1,n2,nt)
        // print("\n$iok $n1 $n2 $nt            ")
        // for(j in 1..nt) print(" ${nms[j]}") // printf("%3d",nms[j]);
        nt = combine(nms,nt)
        xs[nt] = xs[nt] + 1
        if(nt > nxb) {nxb = nt; iob = iok}
        if(nt < nxa) {nxa = nt; ioa = iok; nto = nt
            for(j in 1..nt) nmo[j] = nms[j]
        }
        if(iok >= no1*no2) {
            if(iok > 1) {
                // printf("\n%6d%6d%6d%3d      ",ioa,iob,nxa,nxb)
                // print("\n$ioa $iob $nxa $nxb      ")
                // for(j in nxa..nxb) print(" ${xs[j]}"); print("\n") // printf("%6d",xs[j]);
                return nto
            } else {
                return nt
            }
        }
        if(io2 >= no2) return nto
        return -1
    }

    private fun SetCXce(s:IntArray):Unit {
        var ic: Int
        for(k in 0..215) {xc[k]=0; cc[k]=0;}
        for(k in 0..35) {xe[k]=0; ce[k]=0;}
        for(k in 1..24 step 3) {
            ic = (k-1) / 3            // ic=0,1,2,3, 4, 5, 6, 7
            if(ic > 3) ic = ic + 4    //    0,1,2,3, 8, 9,10,11
            xc[s[k]+6*s[k+1]+36*s[k+2]-43] = ic
            xc[s[k+2]+6*s[k]+36*s[k+1]-43] = ic
            xc[s[k+1]+6*s[k+2]+36*s[k]-43] = ic
            ic = 10*(ic+1)         // ic/10=1,2,3,4, 9,10,11,12
            cc[s[k]+6*s[k+1]+36*s[k+2]-43] = ic
            cc[s[k+2]+6*s[k]+36*s[k+1]-43] = ic + 1
            cc[s[k+1]+6*s[k+2]+36*s[k]-43] = ic + 2
        }
        for(k in 25..48 step 2) {
            ic = (k-1) / 2 - 4      // ic=8,9,10,11, 12,13,14,15, 16,17,18,19
            if(ic < 12) ic = ic - 4 //    4,5, 6, 7, 12,13,14,15, 16,17,18,19
            xe[s[k]+6*s[k+1]-7] = ic
            xe[s[k+1]+6*s[k]-7] = ic
            ic = 10 * (ic + 1)     // ic/10=5,6,7,8, 13,14,15,16, 17,18,19,20
            ce[s[k]+6*s[k+1]-7] = ic
            ce[s[k+1]+6*s[k]-7] = ic + 1
        }
        return
    }

    private fun print48(t:IntArray, k:Int, msg:String):Unit {
        for(i in 1..48) {
            print(t[54*k+i])
            if(i <=24 && i % 3 == 0) print(" ")
            if(i > 24 && i % 2 == 0) print(" ")
        }; print("  $msg\n")
        return
    }

    private fun display48(t:IntArray, k:Int):Unit {
        info = -1
        var t0 = 54*k
        if(k>=0) for(j in 1..54) faceC[j] = t[t0+j]
        viewBinding.face01Button.apply{this.setBackgroundColor(argbC[faceC[1]]); text=textC[faceC[1]]}
        viewBinding.face02Button.apply{this.setBackgroundColor(argbC[faceC[2]]); text=textC[faceC[2]]}
        viewBinding.face03Button.apply{this.setBackgroundColor(argbC[faceC[3]]); text=textC[faceC[3]]}
        viewBinding.face04Button.apply{this.setBackgroundColor(argbC[faceC[4]]); text=textC[faceC[4]]}
        viewBinding.face05Button.apply{this.setBackgroundColor(argbC[faceC[5]]); text=textC[faceC[5]]}
        viewBinding.face06Button.apply{this.setBackgroundColor(argbC[faceC[6]]); text=textC[faceC[6]]}
        viewBinding.face07Button.apply{this.setBackgroundColor(argbC[faceC[7]]); text=textC[faceC[7]]}
        viewBinding.face08Button.apply{this.setBackgroundColor(argbC[faceC[8]]); text=textC[faceC[8]]}
        viewBinding.face09Button.apply{this.setBackgroundColor(argbC[faceC[9]]); text=textC[faceC[9]]}
        viewBinding.face10Button.apply{this.setBackgroundColor(argbC[faceC[10]]); text=textC[faceC[10]]}
        viewBinding.face11Button.apply{this.setBackgroundColor(argbC[faceC[11]]); text=textC[faceC[11]]}
        viewBinding.face12Button.apply{this.setBackgroundColor(argbC[faceC[12]]); text=textC[faceC[12]]}
        viewBinding.face13Button.apply{this.setBackgroundColor(argbC[faceC[13]]); text=textC[faceC[13]]}
        viewBinding.face14Button.apply{this.setBackgroundColor(argbC[faceC[14]]); text=textC[faceC[14]]}
        viewBinding.face15Button.apply{this.setBackgroundColor(argbC[faceC[15]]); text=textC[faceC[15]]}
        viewBinding.face16Button.apply{this.setBackgroundColor(argbC[faceC[16]]); text=textC[faceC[16]]}
        viewBinding.face17Button.apply{this.setBackgroundColor(argbC[faceC[17]]); text=textC[faceC[17]]}
        viewBinding.face18Button.apply{this.setBackgroundColor(argbC[faceC[18]]); text=textC[faceC[18]]}
        viewBinding.face19Button.apply{this.setBackgroundColor(argbC[faceC[19]]); text=textC[faceC[19]]}
        viewBinding.face20Button.apply{this.setBackgroundColor(argbC[faceC[20]]); text=textC[faceC[20]]}
        viewBinding.face21Button.apply{this.setBackgroundColor(argbC[faceC[21]]); text=textC[faceC[21]]}
        viewBinding.face22Button.apply{this.setBackgroundColor(argbC[faceC[22]]); text=textC[faceC[22]]}
        viewBinding.face23Button.apply{this.setBackgroundColor(argbC[faceC[23]]); text=textC[faceC[23]]}
        viewBinding.face24Button.apply{this.setBackgroundColor(argbC[faceC[24]]); text=textC[faceC[24]]}
        viewBinding.face25Button.apply{this.setBackgroundColor(argbC[faceC[25]]); text=textC[faceC[25]]}
        viewBinding.face26Button.apply{this.setBackgroundColor(argbC[faceC[26]]); text=textC[faceC[26]]}
        viewBinding.face27Button.apply{this.setBackgroundColor(argbC[faceC[27]]); text=textC[faceC[27]]}
        viewBinding.face28Button.apply{this.setBackgroundColor(argbC[faceC[28]]); text=textC[faceC[28]]}
        viewBinding.face29Button.apply{this.setBackgroundColor(argbC[faceC[29]]); text=textC[faceC[29]]}
        viewBinding.face30Button.apply{this.setBackgroundColor(argbC[faceC[30]]); text=textC[faceC[30]]}
        viewBinding.face31Button.apply{this.setBackgroundColor(argbC[faceC[31]]); text=textC[faceC[31]]}
        viewBinding.face32Button.apply{this.setBackgroundColor(argbC[faceC[32]]); text=textC[faceC[32]]}
        viewBinding.face33Button.apply{this.setBackgroundColor(argbC[faceC[33]]); text=textC[faceC[33]]}
        viewBinding.face34Button.apply{this.setBackgroundColor(argbC[faceC[34]]); text=textC[faceC[34]]}
        viewBinding.face35Button.apply{this.setBackgroundColor(argbC[faceC[35]]); text=textC[faceC[35]]}
        viewBinding.face36Button.apply{this.setBackgroundColor(argbC[faceC[36]]); text=textC[faceC[36]]}
        viewBinding.face37Button.apply{this.setBackgroundColor(argbC[faceC[37]]); text=textC[faceC[37]]}
        viewBinding.face38Button.apply{this.setBackgroundColor(argbC[faceC[38]]); text=textC[faceC[38]]}
        viewBinding.face39Button.apply{this.setBackgroundColor(argbC[faceC[39]]); text=textC[faceC[39]]}
        viewBinding.face40Button.apply{this.setBackgroundColor(argbC[faceC[40]]); text=textC[faceC[40]]}
        viewBinding.face41Button.apply{this.setBackgroundColor(argbC[faceC[41]]); text=textC[faceC[41]]}
        viewBinding.face42Button.apply{this.setBackgroundColor(argbC[faceC[42]]); text=textC[faceC[42]]}
        viewBinding.face43Button.apply{this.setBackgroundColor(argbC[faceC[43]]); text=textC[faceC[43]]}
        viewBinding.face44Button.apply{this.setBackgroundColor(argbC[faceC[44]]); text=textC[faceC[44]]}
        viewBinding.face45Button.apply{this.setBackgroundColor(argbC[faceC[45]]); text=textC[faceC[45]]}
        viewBinding.face46Button.apply{this.setBackgroundColor(argbC[faceC[46]]); text=textC[faceC[46]]}
        viewBinding.face47Button.apply{this.setBackgroundColor(argbC[faceC[47]]); text=textC[faceC[47]]}
        viewBinding.face48Button.apply{this.setBackgroundColor(argbC[faceC[48]]); text=textC[faceC[48]]}
        return
    }

    private fun NGRubik(t:IntArray, k:Int):Int {
        var ng = 0
        for(j in 1..48) {
            if (t[54 * k + j] != s[j]) ng = ng + 1
        }
        return ng
    }

    private fun NGFace9(t:IntArray, fc:IntArray):Int {
        var ng = 0
        for(j in 1..6) fc[j] = 1
        for(j in 1..48) fc[t[j]] = fc[t[j]] + 1
        for(j in 1..6) if(fc[j] != 9) ng = ng + 1
        return ng
    }

    private fun NGCubIC(t:IntArray, xx:IntArray):Int {
        var cc = IntArray(21)
        var ng = 0
        var jj = 0
        var p3 = 0
        var p2 = 0
        var p1 = 0
        CubicIC(t,0,xx)
        for(j in 0..20) cc[j] = 0; cc[0] = 1
        for(j in 0..19) {
            jj = xx[j]/10
            cc[jj] = cc[jj] + 1
            if((jj > 4 && jj <= 8) || jj > 12) p2 = p2 + xx[j] % 10
            else p3 = p3 + xx[j]%10 // jj:(1,2,3,4, 9,10,11,12)
        }
        ng = p3%3 + p2%2
        for(j in 0..20) if(cc[j] != 1) ng = ng + 1
        xx[20] = p3%3; xx[21] = p2%2
        xx[22] = p1%2; if(ng > 0) return ng
        for(j in 0..19) cc[j+1] = xx[j]/10
        for(j in 1..20) {
            if(cc[j] <= 0) continue
            jj = j
            while(cc[jj] != j) {cc[jj] = -cc[jj]; jj = -cc[jj]; p1 = p1 + 1}
            cc[jj] = -cc[jj]
        }
        xx[22] = p1%2; ng = p1%2
        return ng
    }

    private fun dispERR(fc:IntArray):Unit {
        var answerL = "Face count(9:OK)\n"
        for (j in 1..6) answerL = answerL + "${fc[j]} "
        viewBinding.solutionL.apply { this.setBackgroundColor(argbC[3]); text = answerL }
    }

    private fun dispERC(xx:IntArray):Unit {
        var answerL = "Cubic IC(1:20:OK)\n"
        for (j in 0..19) answerL = answerL + "${xx[j]/10} "
        answerL = answerL + "\n\nParity C3:E2:P1(0:OK)\n"
        for (j in 20..22) answerL = answerL + "${xx[j]} "
        viewBinding.solutionL.apply { this.setBackgroundColor(argbC[3]); text = answerL }
    }

    private fun t2p0(t:IntArray, L:Int):Int {
        var xx = IntArray(20)
        var pc = IntArray(8)
        var pe = IntArray(12)
        var p0: Int
        var Fn: Int
        var Fk: Int
        var nn: Int
        CubicIC(t,L,xx)
        for(i in 0..3) {
            pc[i]   = xx[i]
            pe[i]   = xx[i+4]
            pc[i+4] = xx[i+8]
            pe[i+4] = xx[i+12]
            pe[i+8] = xx[i+16]
        }
        var icc = 0
        for(i in 0..6) {
            icc = 3*icc + (pc[i] % 10)
        }
        var iee = 0
        for(i in 0..10) {
            iee = 2*iee + (pe[i] % 10)
        }
        var ipp = 0
        var k = 3
        for(n in 11 downTo 0) {
            if(pe[n] >= 170) {
                k = k - 1
                if(k < 0) break
                continue
            }
            Fn = 1
            Fk = 1
            nn = n
            for(kk in k downTo 1) {
                Fn = Fn * nn // Fn = n!/(n-k)! = nPk
                Fk = Fk * kk // Fk = k!        = nPo
                nn = nn - 1
            }
            ipp = ipp + Fn/Fk // Fn/Fk = n!/(n-k)!/k! = nCk
        }  //   ipp = 0:494 //   495 = 12!/(8!4!)  cccc cccc
        // 3^7 2^11 495 = 2187*2048*495 = 2217093120  cccc eeee
        // 4^7 2^11 512 = 2187*2048*512 = 2293235712  eeee eeep
        p0 = icc.shl(20).or(iee.shl(9)).or(ipp) // pppp pppp
        if(kkk > 2) {  // kkk = kkk - 1;
            print("\n")                              // printf("\n");
            for(i in 0..19) print(" ${xx[i]}") // printf("%4d",x[i]);
            print(" $icc ${iee*2} $ipp $p0\n")
            // printf("%4X%4X%4X%9X\n",icc,iee*2,ipp,p0);
        }
        return p0
    }

    private fun x2p1(x:IntArray, L:Int):Triple<Int, Int, Int> {
        /*
        union usint {unsigned int uv; int sv;} p1;
        unsigned int p2; // union usint p1;
        */
        val ip = intArrayOf(0,1,2,3,0,1,2,3)
        var pc = IntArray(8)
        var pe = IntArray(12)
        var sc: Int
        var se: Int
        var j:  Int
        var iu = 7
        var id = 15
        var x0 = 20*L
        for(i in 6 downTo 4) {
            if(x[i+x0]   > x[iu+x0]) iu = i   // iu= 7: 6: 5:4
            if(x[i+8+x0] > x[id+x0]) id = i+8 // id=15:14:13:12
        }
        iu =  7 - iu         // iu=0:1:2:3
        id = 15 - id         // id=0:1:2:3
        for(i in 0..3) {     // pc/e    x
            j = ip[i+iu]
            pc[j] = x[x0+i]    // 0:3    0:3
            pe[j] = x[x0+i+4]  // 0:3    4:7
            j = ip[i+id] + 4
            pc[j] = x[x0+i+8]  // 4:7    8:11
            pe[j] = x[x0+i+12] // 4:7   12:15
            pe[i+8]=x[x0+i+16] // 8:11  16:19
        }
        var pcc  = 0
        var pee  = 0
        var fact = 1
        for(i in 1..7) {
            sc = 0
            se = 0
            for(j in 0..(i-1)) {
                if(pc[j] > pc[i]) sc = sc + 1
                if(pe[j] > pe[i]) se = se + 1
            }
            fact = fact * i
            pcc  = pcc + sc * fact // pcc = 0 : 40319
            pee  = pee + se * fact // pee = 0 : 40319
        }
        var kee = 0
        fact = 1
        for(i in 9..11) {
            se = 0
            for(j in 8..(i-1)) {
                if(pe[j] > pe[i]) se = se + 1
            }
            fact = fact * (i-8)
            kee  = kee + se * fact // kee = 0 : 23
        }
        var ipp = q1[pee/24] + (pee % 6)
        // ipp = bSearch(q1,mq1,pee)  // ipp = 0 : 2519  <-  pee = 0 : 40319
        var p2 = 40320 * ipp + pcc //  p2 = 0 :  101,606399
        //  p1 = 0 : 2438,553623
        var sv = ((24L * p2 + kee).and(0xFFFFFFFF)).toInt()
        if(kkk > 2) {
            print("\n")                                 // printf("\n");
            for(i in 0..19) print(" ${x[x0+i]}")  // printf("%3d",x[i]);
            print(" $pee $ipp ${ipp*40320} $pcc $p2 $kee $sv\n")
            // printf("%5d%5d%8X%5X%8X%3X%9X\n",pee,ipp,ipp*40320,pcc,p2,kee,p1,p1.uv);
        }
        return Triple(sv, iu, id) // *iuu=iu; *id=id;
    }
    /*
    private fun p2x(sp:Int, xx:IntArray):Unit {
        /*
        union usint {unsigned int uv; int sv;} p1;
        unsigned int p2; // union usint p1;
        */
        var pc = IntArray(8)
        var pe = IntArray(8)
        var ke = IntArray(4)
        var ic = IntArray(8)
        var ie = IntArray(8)
        var pci: Int
        var pei: Int
        var k: Int
        var sv = sp                                  // .uv = 0:2438,553623
        var kee =(sv.toUInt() % 24.toUInt()).toInt() // kee = 0:23
        var p2 = (sv.toUInt() / 24.toUInt()).toInt() // p2  = 0:101,606399
        var pcc = p2 % 40320              // pcc = 0:40319
        var ipp = p2 / 40320              // ipp = 0:2519
        var pee = q2[ipp]                 // pee = 0:40319
        for(i in 0..7) {
            ic[i]=7-i // 7 6 5 4 3 2 1 0
            ie[i]=7-i // 7 6 5 4 3 2 1 0
        }
        var fact=40320
        for(i in 7 downTo 0) {
            fact=fact/(i+1)
            pci=pcc/fact    // 0:i
            pei=pee/fact    // 0:i
            pcc=pcc-pci*fact
            pee=pee-pei*fact
            pc[i]=ic[pci]
            pe[i]=ie[pei]
            k = pci
            while(k < i) {
                ic[k]=ic[k+1]
                k=k+1
            }
            k = pei
            while(k < i) {
                ie[k]=ie[k+1]
                k=k+1
            }
        }
        for(i in 0..3) {
            ie[i]=3-i // 3 2 1 0
        }
        fact=24
        for(i in 3 downTo 0) {
            fact=fact/(i+1)
            pei=kee/fact    // 0:i
            kee=kee-pei*fact
            ke[i]=ie[pei]
            k = pei
            while(k < i) {
                ie[k]=ie[k+1]
                k=k+1
            }
        }
        for(i in 0..4) {
            if(pc[i] >= 4) pc[i]=pc[i]+4
            if(pe[i] >= 4) pe[i]=pe[i]+4
            pe[i]=pe[i]+4
        }
        for(i in 0..3) {
            xx[i   ]=pc[i  ]   // xx[ 0: 3]=pc[0:3];
            xx[i+ 8]=pc[i+4]   // xx[ 8:11]=pc[4:7];
            xx[i+ 4]=pe[i  ]   // xx[ 4: 7]=pe[0:3];
            xx[i+12]=pe[i+4]   // xx[12:15]=pe[4:7];
            xx[i+16]=ke[i]+1   // xx[16:19]=ke[0:3]+16;
        }
        var (px, iuu, idd) = x2p1(xx,0)
        if(kkk > 4 || px != sp) {
            print("\n")                              // printf("\n");
            for(i in 0..19) print(" ${xx[i]}") // printf("%3d",x[i]);
            print(" $pee $ipp ${ipp*40320} $pcc $p2 $kee $sv $px $iuu $idd\n")
            // printf("%5d%5d%8X%5X%8X%3X%9X%2d%2d\n",
            // pee,ipp,ipp*40320,pcc,p2,kee,p1.uv,px,iuu,idd);
        }
        return
    }
    */
    private fun p2nm0(mx:Int, nm:IntArray, nt0:Int):Int {
        var ni = intArrayOf(0,0,0,0,0,0,0,0,0,0,0,0) // ni[12]
        val np = intArrayOf(
            63,62,61,23,22,21,43,42,41,53,52,51,33,32,31,
            13,12,11,63,62,61,43,42,41,53,52,51,33,32,31,
            13,12,11,23,22,21,43,42,41,53,52,51,63,62,61,
            13,12,11,23,22,21,63,62,61,53,52,51,33,32,31,
            13,12,11,23,22,21,43,42,41,63,62,61,33,32,31,
            13,12,11,23,22,21,43,42,41,53,52,51,33,32,31)
        var nx: Int
        var ms = mx
        var nt = 0
        var i = 6
        var j = 0
        while(ms>0) {
            nx = ms.and(15)
            ms = ms.shr(4)
            nt = j + 1
            ni[j] = np[15*i + nx - 16] // ni[0:nt-1]=np[0:89]
            i = ni[j]/10
            j = j + 1
        }
        for(j in 1..nt) nm[j+nt0] = ni[nt-j] // nm[1:nt]=ni[nt-1:0]
        /* if(kkk > 6) {
          print("\n $p2nm0 : $mx ")              // printf("\n p2nm0 :%7X :",mx);
          for(j in 1..nt) print(" ${nm[j+nt0]}") // printf("%3d",nm[j+nt0]);
          print("\n")                            // printf("\n");
        } */
        return nt
    }

    private fun p2nm1(mx:Int, nm:IntArray, nt1:Int):Int {
        var np = intArrayOf(0,12,22,42,52,33,32,31,63,62,61)
        var nx: Int
        var nt = 0
        for(j in 28 downTo 0 step 4) {
            nx = mx.shr(j).and(15)
            if(nx > 0) {
                nt = nt + 1
                nm[nt+nt1] = np[nx] // nm[1:nt]=np[1:7]
            }
        }
        /* if(kkk > 6) {
          print("\n $p2nm1 : $mx ") // printf("\n p2nm1 :%9X :",mx);
          for(j in 1..nt) print(" ${nm[j+nt1]}"); print("\n") // printf("%3d",nm[j+nt1]);
        } */
        return nt
    }

    private fun bSearch(p1:IntArray, x1:IntArray, mp:Int, px:Int):Int {
        var mx = -1
        var ia = 0
        var ib = mp
        var ic = (ia + ib) / 2
        var icx = 0
        while(true) {
            //  if(kkk > 8) printf("%12d%12d%12d%9X%9X%12d%12d\n",ia,ib,ic,p1[ic],px,p1[ic],px);
            if(kkk > 8) println("$ia $ib $ic ${p1[ic]} $px")
            icx = x1[ic]
            if(px == p1[icx]) {
                mx = icx
                break
            } else if(px < p1[icx]) {
                if(ib == ic) break
                ib = ic
            } else {
                if(ia == ic) break
                ia = ic
            }
            ic = (ia + ib) / 2
        } // printf("%12d%9X%12d%12d\n",mp,px,px,mx);
        if(kkk > 1) print("bSearch: mp,px,mx = $mp $px $mx\n")
        return mx
    }

    private fun combine(nm:IntArray, nti:Int):Int {
        var nt: Int
        var nr: Int
        var k: Int
        var ntn = nti
        do {
            nt = ntn
            nr = 1
            for(j in 2 .. nt) {
                if(nm[nr]/10 != nm[j]/10) {
                    nm[++nr] = nm[j]
                } else {
                    k = ((nm[nr] % 10) + (nm[j] % 10)) % 4;
                    nm[nr] = (nm[nr]/10)*10 + k
                    if(k == 0) {
                        if(j == nt) {nr--}
                        else {nm[nr] = (nm[j+1]/10)*10}
                    }
                }
            }
            ntn = nr
        } while(nr < nt && nr > 1)
        /* if(nr < nti) {
            // printf("\n%18d%3d         ",nti,nr);
            print("\n$nti $nr         ")
            for(j in 1..nr) print(" ${nm[j]}") // printf("%3d",nm[j])
        } */
        return nr
    }

    private fun Setq1():Unit {
        var pe = IntArray(9)
        var ie = IntArray(9)
        var pei: Int
        var n = 0
        for(p in 0..40319) {
            var pee = p
            for(i in 1..8) ie[i] = 8-i // 7 6 5 4 3 2 1 0
            var fact = 40320 // 8! = 40320
            for(i in 8 downTo 1) {
                fact = fact/i
                pei = pee/fact // 0:(i-1)
                pee = pee - pei*fact
                pe[i] = ie[pei+1]
                for(k in pei+1 .. i-1) ie[k] = ie[k+1]
            }
            iu = 4
            id = 8
            for(i in 3 downTo 1) {
                if(pe[i]   > pe[iu]) iu = i   // iu = 4 3 2 1
                if(pe[i+4] > pe[id]) id = i+4 // id = 8 7 6 5
            }
            if(iu != 4 || id != 8) continue
            q1[n] = p
            // if(n%6==0) println("${q1[n]} $n")
            // else if(q1[n] != q1[n-1]+1) println("${q1[n]} NG")
            n = n+1
        }
        mq1 = n // mq1 = 2520
        // for(j in 0..mq1-1) println("${q1[j]} $j) // QY01.txt
        // for(j in 0..mq1-1) ix[j]=j; ipp = bSearch(q1,ix,mq1,pee)
        for(j in 0..mq1-1) q2[j]=q1[j]
        for(j in 0..mq1-1 step 6) q1[q1[j]/24] = j // ipp = q1[pee/24] + pee%6
        return
    }

    private fun Setp0():Unit {
//  integer xx[20],cc,ce,s,px
//  integer LL(0:18),i(0:18),k(0:18),ks(0:18)
//  integer ki(3,6,6)
//  integer t(54,20),x(20,20),nm(18)
//  integer q1,x0,x1,p0,p1,m0,m1,mq1,mp0,mp1
//  real*8 n(18)
//  common nl1,nl2,no1,no2
//  common/Cks/ s(54)
//  common/CIX/ cc(6,6,6),ce(6,6)
//  common/CIP/ x0(3702717),p0(3702717),m0(3702717),mp0,q1(2520),mq1
// *           ,x1(3696619),p1(3696619),m1(3696619),mp1
        var t  = IntArray(1081) // t[20][54]
        var n  = IntArray(18)
        var ks = IntArray(19)
        var nm = IntArray(18)
        var px:  Int
        var i12: Int
        var L:   Int
        // open(1,file='QY05k.txt')
        for(j in 1..54) t[j]=s[j]
        var nn = 0
        p0[nn] = 0
        m0[nn] = 0
        ks[nn] = 0
        var i0 = 6                      // for First step NO U,D-turn
        for(L1 in 1..5) {               // 1,5 1,6 1,7
            for(j in 0..L1) n[j] = 0      // n[0:L1] = 0
            L=1
            for(i1 in 1..6) {             // for i(L)=1,6
                i12 = i0 - i1                 // 1+4,2+5,3+6 but
                if(i12==0 || i12==3) continue // not 4+1,5+2,6+3
                for(k1 in 1..3) {             // for k(L)=1,3
                    if(k1==2) continue            // NO 180-turn for 1st step
                    n[L] = n[L] + 1
                    nm[L] = 10*i1 + k1
                    ks[L] = ks[L-1].or(ki[18*i0+3*i1+k1-22].shl(4*(L-1)))
                    RotateA(t,L,nm[L])
                    if(L> L1) continue
                    if(L==L1) {px=t2p0(t,L); p0[++nn]=px; m0[nn]=ks[L]; continue}
                    L=2
                    for(i2 in 1..6) {             // for i(L)=1,6
                        i12 = i1 - i2                 // 1+4,2+5,3+6 but
                        if(i12==0 || i12==3) continue // not 4+1,5+2,6+3
                        for(k2 in 1..3) {             // for k(L)=1,3
                            n[L] = n[L] + 1
                            nm[L] = 10*i2 + k2
                            ks[L] = ks[L-1].or(ki[18*i1+3*i2+k2-22].shl(4*(L-1)))
                            RotateA(t,L,nm[L])
                            if(L> L1) continue
                            if(L==L1) {px=t2p0(t,L); p0[++nn]=px; m0[nn]=ks[L]; continue}
                            L=3
                            for(i3 in 1..6) {             // for i(L)=1,6
                                i12 = i2 - i3                 // 1+4,2+5,3+6 but
                                if(i12==0 || i12==3) continue // not 4+1,5+2,6+3
                                for(k3 in 1..3) {             // for k(L)=1,3
                                    n[L] = n[L] + 1
                                    nm[L] = 10*i3 + k3
                                    ks[L] = ks[L-1].or(ki[18*i2+3*i3+k3-22].shl(4*(L-1)))
                                    RotateA(t,L,nm[L])
                                    if(L> L1) continue
                                    if(L==L1) {px=t2p0(t,L); p0[++nn]=px; m0[nn]=ks[L]; continue}
                                    L=4
                                    for(i4 in 1..6) {             // for i(L)=1,6
                                        i12 = i3 - i4                 // 1+4,2+5,3+6 but
                                        if(i12==0 || i12==3) continue // not 4+1,5+2,6+3
                                        for(k4 in 1..3) {             // for k(L)=1,3
                                            n[L] = n[L] + 1
                                            nm[L] = 10*i4 + k4
                                            ks[L] = ks[L-1].or(ki[18*i3+3*i4+k4-22].shl(4*(L-1)))
                                            RotateA(t,L,nm[L])
                                            if(L> L1) continue
                                            if(L==L1) {px=t2p0(t,L); p0[++nn]=px; m0[nn]=ks[L]; continue}
                                            L=5
                                            for(i5 in 1..6) {             // for i(L)=1,6
                                                i12 = i4 - i5                 // 1+4,2+5,3+6 but
                                                if(i12==0 || i12==3) continue // not 4+1,5+2,6+3
                                                for(k5 in 1..3) {             // for k(L)=1,3
                                                    n[L] = n[L] + 1
                                                    nm[L] = 10*i5 + k5
                                                    ks[L] = ks[L-1].or(ki[18*i4+3*i5+k5-22].shl(4*(L-1)))
                                                    RotateA(t,L,nm[L])
                                                    if(L> L1) continue
                                                    if(L==L1) {px=t2p0(t,L); p0[++nn]=px; m0[nn]=ks[L]; continue}
                                                }};L=4}};L=3}};L=2}};L=1}}
            // if(L1 < 5) continue
            mp0 = nn + 1
            heapl(p0,x0,mp0)
            var mp = 0
            var ixp = -1
            var ixm = -1
            for(j in 0..nn) {
                var jxp = p0[x0[j]]
                if(jxp!=ixp) {
                    mp = mp + 1
                    ixp = jxp
                    ixm = m0[x0[j]]
                    // if(L1==5 && mp%5000==0) print("$ixp ${m0[x0[j]]}\n")
                } else {m0[x0[j]] = ixm}
            }
            // print(" $L1 ${n[L1]} $mp0 $mp\n")
        } // L1
        // close(1)
        return
    }

    private fun Setp1():Unit {
//  integer LL(0:18),i(0:18),k(0:18),ks(0:18)
//  integer kL(6),kU(6),ki(3,6),nm(18),x(20,20),xc,xe,px
//  integer q1,x0,x1,p0,p1,m0,m1,mq1,mp0,mp1
//  real*8 n(18)
//  common nl1,nl2,no1,no2
//  common/CID/ xc(6,6,6),xe(6,6)
//  common/CIP/ x0(277390),p0(277390),m0(277390),mp0,q1(2520),mq1
// *           ,x1(544908),p1(544908),m1(544908),mp1
//  data kL/2,2,1,2,2,1/,kU/2,2,3,2,2,3/
//  data ki/0,1,0, 0,2,0, 5,6,7, 0,3,0, 0,4,0, 8,9,10/
//  open(1,file='QY03.txt',form='unformatted',access='stream'
// *                      ,status='old',err=1)
//  read(1) mq1,mp0,mp1
//  read(1) q1(1:mq1)
//  goto 2
//1 open(1,file='QY01.txt')
//  mq1=2520
//  do j=1,mq1
//    read(1,'(2z8)') q1(j)
//  enddo
//2 close(1)
//  do j=1,mq1,6
//    q1(q1(j)/24+1) = j
//  enddo
        var kL = intArrayOf(0, 2,2,1,2,2,1)
        var kU = intArrayOf(0, 2,2,3,2,2,3)
        var ki = intArrayOf(0,1,0, 0,2,0, 5,6,7, 0,3,0, 0,4,0, 8,9,10)
        var n  = IntArray(18)
        var ks = IntArray(19)
        var nm = IntArray(18)
        var i12: Int
        var L:   Int
        // open(1,file='QY07k.txt')
        for(j in 0..19) x[j] = j
        var nn = 0
        ks[nn] = 0
        p1[nn] = 0
        m1[nn] = 0
        var i0 = 0
        for(L2 in 1..7) { // 1,7
            for(j in 1..L2) n[j] = 0
            L = 1
            for(i1 in 1..6) {                   // for i(L)=1,6
                if(L==L2) if(i1==3||i1==6) continue // for Last step NO U,D-turn
                i12 = i0 - i1                       // 1+4,2+5,3+6 but
                if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                for(k1 in kL[i1]..kU[i1]) {         // for k(L)=kL(i(L)),kU(i(L))
                    n[L] = n[L] + 1
                    nm[L]=10*i1 + k1
                    ks[L]=ks[L-1]+ki[3*i1+k1-4].shl(4*L) // use only 31 bits
                    RotateB(x,L,nm[L])
                    if(L> L2) continue
                    if(L==L2) {var (px,iu,id)=x2p1(x,L)
                        p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                    L = 2
                    for(i2 in 1..6) {                   // for i(L)=1,6
                        if(L==L2) if(i2==3||i2==6) continue // for Last step NO U,D-turn
                        i12 = i1 - i2                       // 1+4,2+5,3+6 but
                        if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                        for(k2 in kL[i2]..kU[i2]) {         // for k(L)=kL(i(L)),kU(i(L))
                            n[L] = n[L] + 1
                            nm[L]=10*i2 + k2
                            ks[L]=ks[L-1]+ki[3*i2+k2-4].shl(4*L) // use only 31 bits
                            RotateB(x,L,nm[L])
                            if(L> L2) continue
                            if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                            L = 3
                            for(i3 in 1..6) {                   // for i(L)=1,6
                                if(L==L2) if(i3==3||i3==6) continue // for Last step NO U,D-turn
                                i12 = i2 - i3                       // 1+4,2+5,3+6 but
                                if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                                for(k3 in kL[i3]..kU[i3]) {         // for k(L)=kL(i(L)),kU(i(L))
                                    n[L] = n[L] + 1
                                    nm[L]=10*i3 + k3
                                    ks[L]=ks[L-1]+ki[3*i3+k3-4].shl(4*L) // use only 31 bits
                                    RotateB(x,L,nm[L])
                                    if(L> L2) continue
                                    if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                        p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                                    L = 4
                                    for(i4 in 1..6) {                   // for i(L)=1,6
                                        if(L==L2) if(i4==3||i4==6) continue // for Last step NO U,D-turn
                                        i12 = i3 - i4                       // 1+4,2+5,3+6 but
                                        if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                                        for(k4 in kL[i4]..kU[i4]) {         // for k(L)=kL(i(L)),kU(i(L))
                                            n[L] = n[L] + 1
                                            nm[L]=10*i4 + k4
                                            ks[L]=ks[L-1]+ki[3*i4+k4-4].shl(4*L) // use only 31 bits
                                            RotateB(x,L,nm[L])
                                            if(L> L2) continue
                                            if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                                p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                                            L = 5
                                            for(i5 in 1..6) {                   // for i(L)=1,6
                                                if(L==L2) if(i5==3||i5==6) continue // for Last step NO U,D-turn
                                                i12 = i4 - i5                       // 1+4,2+5,3+6 but
                                                if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                                                for(k5 in kL[i5]..kU[i5]) {         // for k(L)=kL(i(L)),kU(i(L))
                                                    n[L] = n[L] + 1
                                                    nm[L]=10*i5 + k5
                                                    ks[L]=ks[L-1]+ki[3*i5+k5-4].shl(4*L) // use only 31 bits
                                                    RotateB(x,L,nm[L])
                                                    if(L> L2) continue
                                                    if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                                        p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                                                    L = 6
                                                    for(i6 in 1..6) {                   // for i(L)=1,6
                                                        if(L==L2) if(i6==3||i6==6) continue // for Last step NO U,D-turn
                                                        i12 = i5 - i6                       // 1+4,2+5,3+6 but
                                                        if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                                                        for(k6 in kL[i6]..kU[i6]) {         // for k(L)=kL(i(L)),kU(i(L))
                                                            n[L] = n[L] + 1
                                                            nm[L]=10*i6 + k6
                                                            ks[L]=ks[L-1]+ki[3*i6+k6-4].shl(4*L) // use only 31 bits
                                                            RotateB(x,L,nm[L])
                                                            if(L> L2) continue
                                                            if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                                                p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                                                            L = 7
                                                            for(i7 in 1..6) {                   // for i(L)=1,6
                                                                if(L==L2) if(i7==3||i7==6) continue // for Last step NO U,D-turn
                                                                i12 = i6 - i7                       // 1+4,2+5,3+6 but
                                                                if(i12==0 || i12==3) continue       // not 4+1,5+2,6+3
                                                                for(k7 in kL[i7]..kU[i7]) {         // for k(L)=kL(i(L)),kU(i(L))
                                                                    n[L] = n[L] + 1
                                                                    nm[L]=10*i7 + k7
                                                                    ks[L]=ks[L-1]+ki[3*i7+k7-4].shl(4*L) // use only 31 bits
                                                                    RotateB(x,L,nm[L])
                                                                    if(L> L2) continue
                                                                    if(L==L2) {var (px,iu,id)=x2p1(x,L)
                                                                        p1[++nn]=px; m1[nn]=ks[L].or(4*id+iu); continue}
                                                                }};L=6}};L=5}};L=4}};L=3}};L=2}};L=1}}
            // if(L2 < 7) continue
            mp1 = nn + 1
            heapl(p1,x1,mp1)
            var mp = 0
            var ixp = -1
            var ixm = -1
            for(j in 0..nn) {
                var jxp = p1[x1[j]]
                if(jxp!=ixp) {
                    mp = mp + 1
                    ixp = jxp
                    ixm = m1[x1[j]]
                    // if(L2==7 && mp%10000==0) print("$ixp ${m1[x1[j]]}\n")
                } else {m1[x1[j]] = ixm}
            }
            // print(" $L2 ${n[L2]} $mp1 $mp\n")
        } // L2
        // close(1)
        return
    }

    private fun rd2nm(rm:Float):Int {
        var nm: Int
        if(rm >= 10) {       // [11 12 13 61 62 63]
            nm = rm.toInt()
        } else if(rm >= 1) { // [1 2 +3 4 +5 6]
            nm = ( 10*rm + 1).toInt()
        } else if(rm < 0) {  // [-1 -2 -3 -4 -5 -6]
            nm = (-10*rm + 3).toInt()
        } else {             // [.1 .2 .3 .4 .5 .6]
            nm = (100*rm + 2).toInt()
        }
        return nm
    }

    private fun random():Double {
        nseed = (405*nseed + 3).and(32767)
        var rx = nseed / 32768.0
        return rx
    }

    /**********************************************************************/
    private fun heapl(a:IntArray, l:IntArray, n:Int):Unit {
/*    int heapl(a,l,n) double a[]; int l[],n; {                       */
/*    ============================================================    */
        // int i,k,m,lx; int shiftl();
        // --a; --l;
/*    ============================================================    */
/*    heap sort : after sorting  a(l(i)) <= a(l(i+1))                 */
/*    ============================================================    */
        var lx: Int
        for (i in 0..n - 1) l[i] = i
/*    +----------------------------------------------------------+    */
/*    | form heap (a(l(i)),i=k,n) for k=n/2 ... 1                |    */
/*    +----------------------------------------------------------+    */
        for (k in n / 2 downTo 1) {
            lx = l[k - 1]
            shiftl(a, l, k, n, lx)
        }
/*    +----------------------------------------------------------+    */
/*    | put max of a(l(1:m)) in the correct position m           |    */
/*    | form heap (a(l(i)),i=1,m-1) for m=n ... 2                |    */
/*    +----------------------------------------------------------+    */
        for (m in n downTo 2) {
            lx = l[m - 1]
            l[m - 1] = l[0]
            shiftl(a, l, 1, m - 1, lx)
        }
        return
    }

    /**********************************************************************/
    private fun shiftl(a:IntArray, l:IntArray, k:Int, m:Int, lx:Int):Unit {
/*    int shiftl(a,l,k,m,lx) double a[]; int l[],k,m,lx; {            */
/*    ============================================================    */
//    int i,j; --a; --l;
/*    ============================================================    */
/*    given lx and heap a(l(k:m-1))  where  k  <=  m                  */
/*    shift a(lx) down to form new heap a(l(k:m))                     */
/*    a: a(l(i)) >= a(l(2*i))  &&  a(l(i)) >= a(l(2*i+1))             */
/*    ============================================================    */
        var i = k
        var j = i + i
        while(j <= m) {
            if(j < m) {
                if(a[l[j]] > a[l[j-1]]) j=j+1
                else {
                    if(a[l[j]] == a[l[j-1]]) {
                        if(l[j] > l[j-1]) j=j+1
                    }
                }
            }
            if(a[l[j-1]] <  a[lx]) break
            if(a[l[j-1]] == a[lx]) {
                if(l[j-1]  <    lx) break
            }
/*      +------------------------------------------------------+    */
/*      | shift a(lx) down to position j                       |    */
/*      +------------------------------------------------------+    */
            l[i-1] = l[j-1]
            i = j
            j = i + i
        }
/*    +----------------------------------------------------------+    */
/*    | no more shift down : i is the correct position for a(lx) |    */
/*    +----------------------------------------------------------+    */
        l[i-1] = lx
        return
    }
    /**********************************************************************/
}

private fun CubeSolver(nr:Int):Int {
//--------------------------------------------------------------------------
// float nmx[20];
// int vpx[20];
//int ok,nx,ns,nr,i,ix;
// var nmx = IntArray(20);
//--------------------------------------------------------------------------
    var t0 = 54*nr;
    for(i in 1..54) t[i]=t[i+t0];
    var nx=0;
    var ns=0;
    var ok=OKcheck(ns);
    if(kkkk>0) print("\nns,ok = $ns $ok");
    ni=0; rdi[ni]=0;
    while(ok<=6) {
        if     (ok==0) nx=SolveL1e0(ns); // a0A a0B
        else if(ok==1) nx=SolveL121(ns); // F2L      (4)*7
        else if(ok==2) nx=SolveL121(ns); // F2L(x2e)
        else if(ok==3) nx=SolveT3e3(ns); // a3A a3B  (2)*6
        else if(ok==4) nx=SolveT3c4(ns); // a4A a4B  (2)*8
        else if(ok==5) nx=SolveS3c5(ns); // a5A a5B  (2)*9
        else if(ok==6) nx=SolveS3e6(ns); // a8A a8B  (2)*11
        if(kkkk>0) print("\nnx,ns = $nx $ns\n");
        for(ix in 0..nx-1) {
            ns=ns+1;
            rd[ns]=nmx[ix]; // vp[ns]=vpx[ix];
            RotateA(t,ns,rd[ns]); // n=1:6; m=1,2,3
        }
        ok=OKcheck(ns);
        if(ok>0) {ni=ni+1; rdi[ni]=ns;}
        if(kkkk>0) print("\nnx,ns,ok = $nx $ns $ok\n");
    }
    return ns; // rd[1:nr]; nr=sum(nx);
}

private fun OKcheck(k:Int):Int {
// q = intArrayOf(25,1,27,4,29,7,31,10);
// int s[55],p[55],i,ok,kk;
    var ok: Int;
    var kk=54*k;
    for(i in 1..54) {p[i]=t[kk+i]; if(kkkk==9) print(" ${s[i]}${p[i]}");}
    ok=0; for(i in 33..40) if(p[i]!=s[i]) return ok; // L1e0
    ok=1; for(i in 13..24) if(p[i]!=s[i]) return ok; // L1c1
    ok=2; for(i in 41..48) if(p[i]!=s[i]) return ok; // L2e2
    ok=3; for(i in 25..31 step 2) if(p[i]!=3) return ok; // T3e3
    ok=4; for(i in  1..10 step 3) if(p[i]!=3) return ok; // T3c4
    ok=5; for(i in  1..12) if(p[i]!=s[i]) return ok; // S3c5
    ok=6; for(i in 25..32) if(p[i]!=s[i]) return ok; // S3e6
    ok=7; return ok;
}

private fun Formula12realface(a:IntArray, b:IntArray,
                              nz:Int, id:Int, f36:Int, m3:Int):Int {
//                                         123@LRU          remember by:
// a2A=[+2 +3 +2 +3 +2 -3 -2 -3 -2]; // [+23232 -3232]     (R)DoDoD UiUi
// a2B=[-1 -3 -1 -3 -1 +3 +1 +3 +1]; // [-13131 +3131]     (L)DoDoD UiUi
// a3A=[+2 +3 +1 -3 -1 -2];          // [+231 -312]
// a4A=[+2 +3 -2 +3 +2 .3 -2 -3];    // [+23 -2 +32 -3323] (R)DoUoD iiUi
// a4B=[-1 -3 +1 -3 -1 .3 +1 +3];    // [-13 +1 -31 +3313] (L)DoUoD iiUi
// a5A=[+2 -1 +2 .4 -2 +1 +2 .4 .2]; // [+2 -1 +244 -2 +124422]
// a5B=[-1 +2 -1 .5 +1 -2 -1 .5 .1]; // [-1 +2 -155 +1 -215511]
// a6A=[a2B .3 a2B]; a6C=[a4A -a4A];
// a6B=[a2A .3 a2A]; a6D=[a4B -a4B];
// a=[1 -2 .3 41 53 62] --> b=[2 -4 .3 51 13 62] for int f12[2]=[2 4]; id=2;
/* var f12r = intArrayOf(
    1,2,3,4,5,6,7,8,9, 2,4,3,5,1,6,8,7,9, 4,5,3,1,2,6,7,8,9, 5,1,3,2,4,6,8,7,9,
    2,1,6,5,4,3,8,7,9, 4,2,6,1,5,3,7,8,9, 1,5,6,4,2,3,7,8,9, 5,4,6,2,1,3,8,7,9);
*/
// int i,n,m,ib,idd; float ai,ais;
/// print("\n $id $f36 $m3 $nz");
    var n: Int;
    var m: Int;
    var ib=0;
    var idd=9*id-10;
    if(m3 != 0) {b[0]=10*f36+m3; ib=1;} /// print(" ${b[0].toInt()},");}
    for(i in 0..nz-1) {
        n=a[i]/10; m=a[i]-n*10; b[ib]=10*f12r[n+idd]+m;
        // ai=abs(a[i]); ais=a[i]/ai;
        /// print(" ${a[i]}");
        // if(ai < 1.0)       b[ib]=0.1*f12r[(ai*10.0+0.1).toInt()+idd];
        // else if(ai < 10.0) b[ib]=ais*f12r[ai.toInt()+idd];
        // else {n=(ai/10.0).toInt(); m=(ai-n*10.0).toInt(); b[ib]=10*f12r[n+idd]+m;}
        if(kkkk==9) print(" ${b[ib]},");
        ib=ib+1;
    }
    return ib;
}

private fun SolveL1e0(nr:Int):Int {
    var a0A = intArrayOf(23,62,21,62,23);
    var a0B = intArrayOf(23,63,21,61,23);
    var a0C = intArrayOf(22);
    var a0D = intArrayOf(21,61,13);
    var a0E = intArrayOf(23,61,13);
//                 L3T         L2L         L2R
//                 L3S         L1S         L1B
//  e = intArrayOf(25,27,29,31,48,41,44,45,42,43,46,47,
//                 26,28,30,32,34,36,38,40,33,35,37,39);
//  f = intArrayOf(0, 1,2,4,5, 1,2,4,5);
// int s[55],p[55];
// int i,i1,i2,i3,i4,ii, j0,j1,j2,j3,j4, m6, k,kk,ng,nx,nz;
// int aa0,id;
    var aa0: Int;
    var i1: Int;
    var i2: Int;
    var i4: Int;
    var j0: Int;
    var j1: Int;
    var j2: Int;
    var j3: Int;
    var j4: Int;
    var id: Int;
    var nx: Int;
    var nz: Int;
    var ng: Int;
    var m6: Int;
    var kk=54*nr;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print(" ${s[i]}${p[i]}");} print(" 0");
    i1=0; i2=0; i4=0; ng=0; m6=0; j0=0; j4=0; nx=0;
    for(i in 1..4) if(p[e[i+19]]!=6) {i4=i; break;} // check L1_Bottom
    if(kkkk==1) print("\n i4 = $i4");
    if(i4 == 0) {
        for(k in 0..3) {
            if(kkkk==1) print("\n k = $k");
            i2=0; ng=0;
            for(i in 1..4)
            {
                if(kkkk==1) print("\n i = $i ${p[e[i+15]]} ${f[i+k]}");
                if(p[e[i+15]]!=f[i+k]) {i1=i2; i2=i+k; ng=ng+1;}
                if(kkkk==1) print("\n i1,i2,ng = $i1 $i2 $ng");
            }
            if(kkkk==1) print("\n k,i1,i2,ng : $k $i1 $i2 $ng");
            if(ng<=2) {m6=(4-k)%4; break;}
        }
        nz=5; if(i2-i1==3) i2=i1; id=(i2+2)%4+1;
        if(ng==0) {nz=0;  aa0=1;}
        else if(i2-i1==2) aa0=1;
        else              aa0=2;
        if(kkkk==1) print("\nB1e0:i4:i1,i2,id,aa0,nz : $i4 $i1 $i2 $id $aa0 $nz");
        if(aa0==1) nx=Formula12realface(a0A,nmx,nz,id,6,m6);
        if(aa0==2) nx=Formula12realface(a0B,nmx,nz,id,6,m6);
        if(kkkk<0) print("\nS1e0:f1:i1:2(1:7) = ${f[id]} $i1$i2 $nx: ");
        return nx;
    }
    for(i in 0..19) if(p[e[i]]==6) {j4=i%4+1; j0=i; break;}
    j1=j4%4+1; j2=j1%4+1; j3=j2%4+1;
    if(kkkk==1) print("\nj0:4 : $j0 $j1 $j2 $j3 $j4");
    if(p[e[j4+19]]!=6) m6=0; else m6=(i4-j4+4)%4;
    if(j0 < 4)       {aa0=3; nz=1;} // L3_Top
    else if(j0 <  8) {aa0=4; nz=1;} // L2_Left
    else if(j0 < 12) {aa0=5; nz=1;} // L2_Right
    else if(j0 < 16) {aa0=4; nz=3;} // L3_Side
    else             {aa0=5; nz=3;} // L1_Side
    if(kkkk==1) print("\nB1e0:i4,j4,j0,j3,aa0,nz : $i4 $j4 $j0 $j3 $aa0 $nz");
    if(aa0==3) nx=Formula12realface(a0C,nmx,nz,j3,6,m6);
    if(aa0==4) nx=Formula12realface(a0D,nmx,nz,j3,6,m6);
    if(aa0==5) nx=Formula12realface(a0E,nmx,nz,j3,6,m6);
    if(kkkk<0) print("\nB1e0:i4:j4(1:5*4) = $i4 $j4  $nx: ");
    return nx;
}

private fun SolveT3e3(nr:Int):Int {
// a3A=[+2 +3 +1 -3 -1 -2];          // [+231 -312]        (R)D (L)iUoD (R)U
// a3B=[+2 +1 +3 -1 -3 -2];          // [+213 -132]        (R)D (L)UiDo (R)U
// a3C=[-2 -3 -4 +3 +4 +2];          // [-234 +342]
//--------------------------------------------------------------------------
// (L)3A        (R)3A        (T)3A
//         c3                 c3           (L)3A :[+2 +3 +1 -3 -1 -2]
//     (i4)  (e3)          e4   (i4)       (L)3A :[+2 +3 +1 -3 -1 -2]
//   c4    3A    c2     c4    3B    c2     (R)3A :[+2 +3 +1 -3 -1 -2]
//      e1    e2          (e1)   e2        (R)3A :[+2 +3 +1 -3 -1 -2]
//        (c1)               (c1)          (T)3A :(R)Do (L)Uo D (R)U
//        [c1 c1L c1] [c1 c1R c1]          (T)3A :(R)Do (L)Uo D (R)U
//--------------------------------------------------------------------------
    var a3A = intArrayOf(21,31,11,33,13,23); // a3A [+231 -312] (R)D (L)iUoD (R)U
    var a3B = intArrayOf(21,11,31,13,33,23); // a3B [+213 -132] (R)D (L)UiDo (R)U
    var a3C = intArrayOf(23,33,43,31,41,21); // a3C [-234 +342]
    var a3D = intArrayOf(23,43,33,41,31,21); // a3D [-243 +432]
    var a3E = intArrayOf(23,32,22,13,23,11,32,21,13,23,11);
    var a3F = intArrayOf(81,33,23,33,21,31,82,33,23,31,81,21);
    var a3G = intArrayOf(13,33,21,31,11,33,13,23,23,33,21,31,11); // G <-> H
    var a3H = intArrayOf(13,33,23,31,21,21,11,31,13,33,23,31,11); // G <-> H
    var a3I = intArrayOf(23,43,33,41,33,21,32,21,13,23,11);
//  f   = intArrayOf(0,1,2,4,5);
//  g   = intArrayOf(26,25, 28,27, 30,29, 32,31, 26,25);    // L3_edges:side(1):top(2)
//  u   = intArrayOf(1,2,3, 4,5,6, 7,8,9, 10,11,12, 1,2,3); // L3_corner:{top sid sid} in cc
//  cu  = intArrayOf(0, 1,4,7,10,1);
//  cs  = intArrayOf(0, 2,5,8,11,2);
//  cr  = intArrayOf(0, 3,6,9,12,3);
//  gu  = intArrayOf(0, 25,27,29,31,25);
//  gs  = intArrayOf(0, 26,28,30,32,26);
    var a3  = intArrayOf(2,4,1,2, 1,4,3,2);
    var d3  = intArrayOf(0,2,0,0, 3,3,3,1);
// int s[55],p[55];
// int i,i1,i2,i3,i4,i6,i6p1,ii,ie,ir,ic, j,j1,j2,j3,j4,jj,je, k,k1,k2,k3,k4,kk, l1,l2,l3,l4;
// int okx,oky,okz,oks, ng,nx,nz;
// int aa3,id; // int OLL=4; // 0:1:2:3:4
    var okx: Int;
    var oky: Int;
    var okz: Int;
    var oks: Int;
    var aa3: Int;
    var ng: Int;
    var nx: Int;
    var nz: Int;
    var id: Int;
    var i1: Int;
    var i2: Int;
    var i3: Int;
    var i4: Int;
    var i6: Int;
    var ie: Int;
    var ir: Int;
    var ic: Int;
    var j1: Int;
    var j2: Int;
    var j3: Int;
    var j4: Int;
    var je: Int;
    var k1: Int;
    var k2: Int;
    var k3: Int;
    var k4: Int;
    var kk: Int;
    kk=54*nr;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print("%2d%1d",s[i],p[i]);} print(" 3");
    ng=0; i4=0; ie=0; ir=0; k3=0; k2=0; k4=0; oks=0; nx=0;
    for(i in 1..4) {if(p[gu[i]]!=3) ng=ng+1; else {ie=i4; i4=i;}}
    if(ng == 2 && ie == 1 && i4 == 4) i4=1;
    i1=i4%4+1; i2=i1%4+1; i3=i2%4+1;
    nz=6;              id=i1; aa3=1; // a3A [+231 -312]
    okz=0;  j4=0; je=0;
    for(j in 1..4) {if(p[cu[j]]==3) {okz=okz+1; je=j4; j4=j;}}
    if(okz == 2 && je == 1 && j4 == 4) j4=1;
    j1=j4%4+1; j2=j1%4+1; j3=j2%4+1;
    if(okz>=1) if(p[cr[j3]]==3) ir=1; else ir=2; // for okz=1:2
    if(okz==0) { oks=0;   // LR side: B-C-3: LR  or  B#A: UU  or  BB: UU  or  AA: LR
        for(k in 1..4) { // LR :(ng=4): LR          LR :(ng=2): DD
            if(p[cs[k]]==3 && p[cr[k+1]]==3) {oks=oks+1; k3=k;} // ...k4     .k2
            k4=k3%4+1; k1=k4%4+1; k2=k1%4+1;
        }
    }
    if(ng == 4 && okz != 4 && OLL>0) {
        aa3=2; // a3B [+213 -132]
        if(okz==1) {          aa3=1; // a3A [+231 -312]
            id=(j4+ir)%4+1;
            // jj=3*j3-4;
            // if(p[cu[j3]]==3)  id=j3; //  2-   UT
            //   // a3=[a3A -3 a3B];    // A-B   LD
            // else              id=j2; //  3+   TU
            //   // a3=[a3A +3 a3B];    // A+B   DR
        }
        if(okz==2) {  // a3=a3B;     // B     LT
            if(j4-je==3)      id=j4; // B#A#4 LT
            else {            id=j3; // B#A-4 UT
                if(ir==1)     id=j1; // B-C 4 DT LT  UT
            }                        //          TD  TR
            if(OLL>2) {            // j4-je: 3,1 2  (ng)
                if(j4-je==2) {id=(id+2)%4+1; aa3=7;}
                else { i6=id%4+1;
                    if(p[cr[i6+1]]==3)       aa3=9;
                    else  {id=i6;            aa3=8;}
                }
            }
        }                              //        LR           UU
        if(okz==0) { id=k4; // LR side // B-C-3: LR  or  B#A: LR
            if(oks==2 && OLL>2)              aa3=5;
        }
        if(aa3==1) nx=Formula12realface(a3A,nmx,nz,id,3,0);
        if(aa3==2) nx=Formula12realface(a3B,nmx,nz,id,3,0);
        if(aa3==3) nx=Formula12realface(a3C,nmx,nz,id,3,0);
        if(aa3==5) nx=Formula12realface(a3E,nmx,11,id,3,0);
        if(aa3==7) nx=Formula12realface(a3G,nmx,13,id,3,0);
        if(aa3==8) nx=Formula12realface(a3H,nmx,13,id,3,0);
        if(aa3==9) nx=Formula12realface(a3I,nmx,11,id,3,0);
        if(kkkk<0) print("\nT3e3:f1:i4(i4:ie) = ${f[id]} $i4$ie $nx: ");
        return nx;
    }
    if(ng == 4 && okz == 4 && OLL>2)  {id=1; aa3=6;}
    if(ng == 2) {
        okx=0; oky=0;
        if(p[cr[i4]]==3) oky=oky+1;
        if(p[cs[i1]]==3) oky=oky+1;
        if(p[cu[i2]]==3) oky=oky+1;
        if(p[cu[i3]]==3){okx=okx+1; oky=oky+1;}
        if(p[cu[i4]]==3) okx=okx+1;
        if(p[cr[i1]]==3) okx=okx+1;
        if(p[cs[i2]]==3) okx=okx+1;
        if(i4-ie == 2) {                                                          // i4-ie == 2
            if(okx==4 || okx==1) {aa3=2; id=i4;}  // B    a3B
            else                 {aa3=2; id=i2;}  // B    a3B
            if(okz==4 &&  OLL>1) {aa3=1; id=i3;}  // A#A  H                       // i4-ie == 2  okz==4
            if(okz==0 &&  OLL>1 && oks==1 && (k2==i2 || k2==i4)) {aa3=1; id=k2;}} // i4-ie == 2  okz==0  AA   |  TT
        else if(okz==0 && OLL>1 && oks==1 &&  k4==i1)            {aa3=2; id=k4;}  // i4-ie != 2  okz==0  BB   _| __
        else if(okz==4 && OLL>1) {aa3=2; id=i1;}  // B#B  NW-arrow                // i4-ie != 2  okz==4
        else if(okz==1 && OLL>1) {                                                // i4-ie != 2  okz==1
            ic=(ir-1)*4+(j4-i3+4)%4;
            aa3=a3[ic];           // a3 = intArrayOf(2,4,1,2, 1,4,3,2);
            id=(j4+d3[ic]-1)%4+1; // d3 = intArrayOf(0,2,0,0, 3,3,3,1);
            if(kkkk==3) print("\nir,j4,i3,ic,aa3,id = $ir $j4 $i3 $ic $aa3 $id");
        }
        else {                                                                    // i4-ie != 2
            if((okx==4 || okx==1) && oky != 4)
            {aa3=3; id=i4;}  // C    a3C
            // else                 {aa3=1; id=i1;}  // A    a3A
        }
    }
    if(aa3==1) nx=Formula12realface(a3A,nmx,nz,id,3,0);
    if(aa3==2) nx=Formula12realface(a3B,nmx,nz,id,3,0);
    if(aa3==3) nx=Formula12realface(a3C,nmx,nz,id,3,0);
    if(aa3==4) nx=Formula12realface(a3D,nmx,nz,id,3,0);
    if(aa3==6) nx=Formula12realface(a3F,nmx,12,id,3,0);
    if(kkkk<0) print("\nT3e3:f1:i4(i4:ie) = ${f[id]} $i4$ie $nx: ");
    return nx;
}

private fun SolveT3c4(nr:Int):Int {
// a4A=[+2 +3 -2 +3 +2 .3 -2 -3];    // [+23 -2 +32 -3323] (R)DoUoD iiUi
// a4B=[-1 -3 +1 -3 -1 .3 +1 +3];    // [-13 +1 -31 +3313] (L)DoUoD iiUi
//--------------------------------------------------------------------------
// (L)4A2:4B3;  (R)4A3:4B4;  (T)4A3R:4B3L
//        (c4)               (c4)          (L)4A2:13[+ + - + + -- - -]
//     (e1)   e4           e1   (e4)       (L)4B3:13[- - + - - ++ + +]
//  +c1    4A  | c3+   -c1 |  4B    c3-    (R)4A3:23[+ + - + + -- - -]
//      e2  > e3           e2 <  e3        (R)4B4:23[- - + - - ++ + +]
//        +c2     R     L    -c2           (T)4A3:(R)DoUoDiiUi
//        [c3 c2L c2] [c2 c2R c1]          (T)4B3:(L)DoUoDiiUi
//--------------------------------------------------------------------------
    var a4A = intArrayOf(21,31,23,31,21,32,23); // (R)DoUoD iiU
    var a4B = intArrayOf(23,33,21,33,23,32,21); // (R)DoUoD iiU
    var a4C = intArrayOf(51,33,23,31,53,33,21); // +3,(+5,-3,-2,+3,-5,-3,+2)
    var a4D = intArrayOf(53,31,21,33,51,31,23); // -3,(-5,+3,+2,-3,+5,+3,-2)
    var a4E = intArrayOf(23,32,21,31,23,31,21); // a4B Reverse
    var a4F = intArrayOf(21,32,23,33,21,33,23); // a4A Reverse
    //  a4B = intArrayOf(13,33,11,33,13,32,11); // a4B 2 -> 1
    var a4G = intArrayOf(21,31,11,33,13,23);    // A#B
    var a4H = intArrayOf(53,21,31,23,33,51,31,21,33,23); // D <-> E
    var a4I = intArrayOf(21,31,23,33,53,31,21,33,23,51); // D <-> E
    var a4J = intArrayOf(22,61,23,32,21,63,23,32,23);
    var ids = intArrayOf(1,2, 1,2, 4,1, 2,3, 2,3, 3,4);
    var idc = intArrayOf(1,3, 4,4, 1,1, 1,1, 1,4, 1,3, 1,2); // +id,-id
    var ida = intArrayOf(1,-1, -1,1, 2,2); // L3.2a:b:c:d:e:f
    var j1234 = IntArray(8); // j1234(j4,j1,j2,j3, j4,j1,j2,j3)
//  ip  = intArrayOf(0,1,2,3,0,1,2,3);
//  f   = intArrayOf(0,1,2,4,5,1);
//  g   = intArrayOf(26,25, 28,27, 30,29, 32,31, 26,25);    // L3_edges:side(1):top(2)
//  c   = intArrayOf(2,3,1, 5,6,4, 8,9,7, 11,12,10, 2,3,1); // L3_corners:(s1 s2 t3) in ccw
//  cu  = intArrayOf(0, 1,4,7,10,1);
//  cs  = intArrayOf(0, 2,5,8,11,2);
//  cr  = intArrayOf(0, 3,6,9,12,3);
//  gu  = intArrayOf(0, 25,27,29,31,25);
//  gs  = intArrayOf(0, 26,28,30,32,26);
// int s[55],p[55];
// int i,i1,i2,i3,i4,ie,ii, j,j4,jj, kk,ng,nx,nz;
// int aa4,id,okt,oks; // int OLL=4; // 0:1:2:3:4
    var sCn: Int;
    var sEn: Int;
    var aa4: Int;
    var iss: Int;
    var ng: Int;
    var nx: Int;
    var nz: Int;
    var ia: Int;
    var ib: Int;
    var ic: Int;
    var id: Int;
    var i1: Int;
    var i2: Int;
    var i3: Int;
    var i4: Int;
    var ie: Int;
    var j1: Int;
    var j2: Int;
    var j3: Int;
    var j4: Int;
    var je: Int;
    var jj: Int;
    var kk: Int;
    var Spc=" ";
    kk=54*nr;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print("%2d%1d",s[i],p[i]);} print(" 4");
    ng=0; nz=7; nx=0; i4=1; ie=0; j4=0; // jd=0; je=0; jj=0; aa4=0;
    for(i in 1..4) {if(p[cu[i]]!=3) ng=ng+1; else i4=i;}
    CubicIC(p,0,x); sCn=0; // 0:sC0:4cNG 1:sC1:4cR1 4:sC4:4cOK
    for(j in 1..4) if((x[j-1]/10)%4+1==x[j]/10) sCn=sCn+1; // x[]/10 = 1:20
    if(ng==3) {       ic=6; ia=0; // ib=0;     // 3NGc  // a4A  ib=0 +spin
        j1234[0]=i4; for(j in 1..7) j1234[j]=j1234[j-1]%4+1;
        i1=j1234[1]; i2=j1234[2]; i3=j1234[3];
        if(p[cs[i1]]==3) { ib=1;               // ia=0; // a4B  ib=1 -spin
            if(SLL>0) {
                if(p[cr[i4]]==p[cr[i3]])          ia=1; // a4D = (-5,+3,+2,-3,+5,+3,-2)
                else if(iq[p[gs[i3]]]!=p[gs[i4]]) ia=0; // a4B = (-2,-3,+2,-3,-2,#3,+2)
                else if(iq[p[gs[i2]]]!=p[gs[i3]]) ia=2; // a4F = (+2,#3,-2,-3,+2,-3,-2)
                else                              ia=1; // a4D
            }
        } else {           ib=0;               // ia=0; // a4A  ib=0 +spin
            if(SLL>0) {
                if(p[cs[i4]]==p[cs[i1]])          ia=1; // a4C = (+5,-3,-2,+3,-5,-3,+2)
                else if(iq[p[gs[i1]]]!=p[gs[i2]]) ia=0; // a4A = (+2,+3,-2,+3,+2,#3,-2)
                else if(iq[p[gs[i2]]]!=p[gs[i3]]) ia=2; // a4E = (-2,#3,+2,+3,-2,+3,+2)
                else                              ia=1; // a4C
            }
        }
    } else { ic=0;
        if(ng==2) { // 3 =:  4 _|  5 _.._
            for(j in 1..4) {if(p[cs[j]]==3) j4=j;}           // ic=3:4:5
            jj=j4; for(j in 1..3) {jj=jj%4+1; if(p[cr[jj]]==3) {ic=6-j; break;}}
            id=(j4+1)%4+1;       aa4=1; // a4A = (+2,+3,-2,+3,+2,.3,-2); // (R)DoUoD iiU
            if(OLL>3) {
                for(i in 1..4) {if(p[cu[i]]!=3) {ie=i4; i4=i;}}
                if(i4-ie==2)            aa4=8;
                else if(p[cu[j4+1]]!=3) aa4=9;
                else                    aa4=10;
            }
        } else {    // 0 *||*  1 |=  2 ||                         // ic=1:2
            ic=0; for(j in 1..4) if(p[cr[j]]==3 && p[cs[j+1]]==3) {ic=ic+1; j4=j;}
            if(kkkk==4) print("\nic,j4 : $ic $j4");
            if(ic==1 && OLL>1) {
                id=j4%4+1; nz=6; aa4=7; // a4G = (+2,+3,+1,-3,-1,-2); // TT A#B OLL
            } else {                    // AA 3+   == =|
                id=(j4+1)%4+1;   aa4=1; // a4A = (+2,+3,-2,+3,+2,.3,-2);
            }
        }
        if(aa4>=7) {
            if(aa4==7) nx=Formula12realface(a4G,nmx,nz,id,3,0);
            if(aa4==8) nx=Formula12realface(a4H,nmx,10,id,3,0);
            if(aa4==9) nx=Formula12realface(a4I,nmx,10,id,3,0);
            if(aa4==10)nx=Formula12realface(a4J,nmx, 9,id,3,0);
            if(nx<10) Spc="  "; else Spc=" ";
            if(kkkk<0) print("\nT3c4:f1:ng(2:3:4) = ${f[id]} $ng$Spc$nx: ");
            return nx;
        }
        j1234[0]=j4; for(j in 1..7) j1234[j]=j1234[j-1]%4+1;
        j1=j1234[1]; j2=j1234[2]; j3=j1234[3];
        sEn=0; jj=j4; je=-1;   // 0:sE0:4eNG 1:sE1:4eR1 4:sE4:4eOK
        for(j in 1..4) {jj=jj%4+1; if(iq[p[gs[jj]]]==p[gs[jj+1]]) {sEn=sEn+1; je=j;}}
        if(ic==1 && sCn==0 && sEn==4) ic=0; // SLL4: if 4cNG(4eOK:Not |=):2cd; Else:2abef
        ia=0; ib=0;                         // a4A              // ic=0:1:2
        if(SLL>0 && sCn==0) ia=1;           // SLL4: if 4cNG:use cd            // ib=0; a4C
        if(SLL>1) {      // BLL: For 4cNG:If 4eR1:(v^<>): use cd; Else: use any cd.
            if(sCn==0 && sEn==1 && (ids[ic+ic]==je || ids[ic+ic+1]==je)) ib=1; // ia=1; a4D
            if(sCn==1) { // BLL: For 4cR1:If 4eOK(ece <- ->): use cd; Ef udOK(ss): use cd; (Else use any abef:QLL)
                if     (ic<=1 && p[cr[j1]]==p[gs[j1]] && p[cu[j1]]==p[gs[j2]] && sEn==4) {ib=0; ia=1; ic=0;} // ece j1
                else if(ic<=1 && p[cu[j4]]==p[gs[j4]] && p[cs[j4]]==p[gs[j1]] && sEn==4) {ib=1; ia=1; ic=0;} // ece j4
                else if(ic==4 && p[cr[j1]]==p[cu[j2]] && sEn==4) {ib=0; ia=1;}                 // T  r  R  r    ->
                else if(ic==4 && p[cs[j1]]==p[cu[j4]] && sEn==4) {ib=1; ia=1;}                 // R  r  T  r    ->
                else if(ic==5 && p[cr[j3]]==p[cr[j4]] && sEn==4) {ib=0; ia=1;}                 // L  l  U  l    <-
                else if(ic==5 && p[cs[j2]]==p[cs[j1]] && sEn==4) {ib=1; ia=1;}                 // D  l  L  l    <-
                else if(ic==5 && p[cs[j3]]==p[cr[j2]] && (je==1 || je==2)) {ib=0; ia=1;}       // UU u (ss)r
                else if(ic==5 && p[cr[j2]]==p[cs[j3]] && (je==3 || je==4)) {ib=1; ia=1;}       // DD d (ss)r
                else if(ic<=1 && p[cu[j3]]==p[cu[j2]] && (je==3 || je==4)) {ib=0; ia=1; ic=0;} // TT u (ss)l
                else if(ic<=1 && p[cu[j2]]==p[cu[j3]] && (je==1 || je==2)) {ib=1; ia=1; ic=0;} // TT d (ss)l
                else if(ic<=1 && p[cr[j2]]==p[cu[j1]]) {ib=0; ia=1; ic=1;}                     // LT u
                else if(ic<=1 && p[cs[j3]]==p[cu[j4]]) {ib=1; ia=1; ic=1;}                     // LT d
                else if(ic==2 && p[cr[j3]]==p[cs[j2]]) {ib=0; ia=1;}                           // LR u
                else if(ic==2 && p[cs[j4]]==p[cr[j1]]) {ib=1; ia=1;}                           // LR d
                else if(ic==3 && p[cu[j3]]==p[cr[j2]]) {ib=0; ia=1;}                           // TU u
                else if(ic==3 && p[cu[j4]]==p[cs[j1]]) {ib=1; ia=1;}                           // TD d
                else if(ic==4 && p[cs[j3]]==p[cs[j2]]) {ib=0; ia=1;}                           // UR u
                else if(ic==4 && p[cr[j3]]==p[cr[j4]]) {ib=1; ia=1;}                           // DR d
                else {ib=0; ia=0;} // Else use any abef:(QLL)
            }
        }
        if(SLL>2 && ia!=1) { // QLL
            if(sEn==4 && sCn!=0) {   // ic!=0; ia=0; ib=0; //   (.b.) 4eOK & 4cR1OK
                //  if(ic<=1) ic=1;      //        ia=0; ib=0; // a (oox) o = a | b
                if(ic==3) ia=2;      //              ib=0; // e (.a.) x = e | f
            }
            if(sEn==0 && sCn==1) {   // ic!=0; ia=0; ib=0; // a (bff) 4eNG & 4cR1
                if(ic==2 || ic==4 || ic==5) ia=2; // ib=0; // e (.xo)
            }                                              //   (aee)
            if(sEn==0 && sCn==4) {   // ic!=1; ia=0; ib=0;            4eNG & 4cOK
                j2=j1234[2]; j4=j1234[3];                    iss=0;
                if(p[gs[j2]]==p[cr[j2]] && (ic==3 || ic==5)) iss=1;
                if(p[gs[j2]]==p[cs[j2]] && (ic==2 || ic==4)) iss=1;
                if(p[gs[j2]]==p[cu[j2]] &&  ic<=1          ) iss=1;
                if(p[gs[j2]]==p[cu[j4]] &&         ic>=3   ) iss=2;
                if(p[gs[j2]]==p[cs[j4]] &&    ic<=2        ) iss=2;
                if(iss==1 && ic<=1) ib=1; ic=0; // b  \\
                if(iss==1 && ic==2) ib=0; ia=2; // e (bff)            4eNG & 4cOK
                if(iss==1 && ic>=3) ib=0; ia=0; // a (.ea)  ic=4 ib=0(\\) use a
                if(iss==1 && ic==5) ib=1; ia=2; // f (..a)          1(//) use b not f
                //  if(iss==2 && ic<=1) ib=0; ic=0; // a  // no ic=1 used
                if(iss==2 && ic==2) ib=1; ia=2; // f (..b)
                if(iss==2 && ic==3) ib=1; ia=0; // b (.fb)          1(\\) use f not b
                if(iss==2 && ic>=4) ib=0; ia=2; // e (aee)  ic=4 ib=0(//) use e
            }
            if(sEn==1 && sCn!=0) {   // ic!=0; ia=0; ib=0;            4eR1 & 4CR1OK
                for(j in 1..4) if(j1234[j]==je) jj=j;
                if(ic<=1) {                //     /\b  v   4
                    if(jj==1) ic=0;        // a   \/
                    //  if(jj==2) ic=1;        // a  a/\   v  2
                    if(jj==3){ic=1; ib=1;} // b  b\/   v  3
                    if(jj==4){ic=0; ib=1;} // b   /\
                }                          //     \/a  v   1
                if(ic==2) {
                    if(jj==1) ib=0;        // a
                    if(jj==2) ib=1;        // b  f/\b  vv 32
                    if(jj==3){ia=2; ib=1;} // f  e\/a  vv 41
                    if(jj==4){ia=2; ib=0;} // e
                }
                if(ic==3) {
                    if(jj==3) ib=0;        // a
                    if(jj==4) ib=1;        // b  a/\e  vv 32
                    if(jj==1){ia=2; ib=1;} // f  b\/f  vv 41
                    if(jj==2){ia=2; ib=0;} // e
                }                          //     /\b  x  (3)
                if(ic==4) {   // if(jj==1) // a    /f  v   4
                    if(jj==2) ia=2;        // e    \e  v   2
                    if(jj==4){ia=2; ib=1;} // f   \/a  v   1
                }                          //    f/\b  x (14)
                if(ic==5) {   // if(jj==1) // a   ..
                    if(jj==4) ia=2;        // e   ..
                }                          //    e\/a  v  41
            }
        }
    }
//  for(j in 0..7) {j1234[j]=j4; j4=j4%4+1;}
    id=j1234[idc[ic+ic+ib]+ida[ia+ia+ib]]; // ic=0:6; ib=0:1; ia=0:1:2(ab:cd:ef)
    aa4=ia+ia+ib+1; // aa4=1:6
    if(kkkk==4) print("\nid,aa4,nz : $id $aa4 $nz");
    if(aa4==1) nx=Formula12realface(a4A,nmx,nz,id,3,0);
    if(aa4==2) nx=Formula12realface(a4B,nmx,nz,id,3,0);
    if(aa4==3) nx=Formula12realface(a4C,nmx,nz,id,3,0);
    if(aa4==4) nx=Formula12realface(a4D,nmx,nz,id,3,0);
    if(aa4==5) nx=Formula12realface(a4E,nmx,nz,id,3,0);
    if(aa4==6) nx=Formula12realface(a4F,nmx,nz,id,3,0);
    if(nx<10) Spc="  "; else Spc=" ";
    if(kkkk<0) print("\nT3c4:f1:ng(2:3:4) = ${f[id]} $ng$Spc$nx: ");
    return nx;
}

private fun SolveS3c5(nr:Int):Int {
// a5A=[-2 +4 -2 .1 +2 -4 -2 .1 .2]; // [-2 +4 -211 +2 -421122] e4B
// a5B=[+1 -5 +1 .2 -1 +5 +1 .2 .1]; // [+1 -5 +122 -1 +512211] e4A
//--------------------------------------------------------------------------
// (L)5A5:5B2;  (R)5A1:5B4;  (T)5A1R:5B2L                   e4          e4
//        (c3)               (c3)          (L)5A4:[-1 +2 -1 .5 +1 -2 -1 .5 .1]e4T
//      e4    e3           e4    e3       *(L)5B2:[+1 -5 +1 .2 -1 +5 +1 .2 .1]e4B
//   c4    5A    c2     c4    5B    c2    *(R)5A1:[-2 +4 -2 .1 +2 -4 -2 .1 .2]e4B
//     (i4)   e2           e1   (i4)       (R)5B4:[+2 -1 +2 .4 -2 +1 +2 .4 .2]e4T
//         c1     R     L     c1      e4B *(T)5A1:(R)UoU (L)UU (R)DiU (L)UU (R)UU
//        [c1 c4L c4] [c3 c3R c2]     e4B *(T)5B2:(L)UoU (R)UU (L)DiU (R)UU (L)UU
//--------------------------------------------------------------------------
    var a5A = intArrayOf(23,41,23,12,21,43,23,12,22); // a5A [-2 +4 -211 +2 -421122] e4B
    var a5B = intArrayOf(11,53,11,22,13,51,11,22,12); // a5B [+1 -5 +122 -1 +512211] e4A
    var a5C = intArrayOf(53,31,23,32,51,33,21,53,31,23,32,51,33,21,31);       // fan+  -/-
    var a5D = intArrayOf(51,33,21,32,53,31,23,51,33,21,32,53,31,23,33);       // fan+  -\-
    var a5E = intArrayOf(13,23,31,21,31,23,33,21,11,23,33,21,31,21,13,23,11); // arrow \/
    var a5F = intArrayOf(21,33,21,31,41,63,41,61,42,21,41,23,43,23);          // kite  \\-
//  f   = intArrayOf(0,1,2,4,5,1);
    var fx  = intArrayOf(0,1,2,0,3,4);
//  g   = intArrayOf(12,26,2, 3,28,5, 6,30,8, 9,32,11, 12,26,2); // L3_sides:
//  gu  = intArrayOf(0, 25,27,29,31,25);
//  gs  = intArrayOf(0, 26,28,30,32,26);
//  cs  = intArrayOf(11,2,5,8,11,2);
//  cr  = intArrayOf(12,3,6,9,12,3);
// int s[55],p[55];
// int i,i1,i2,i3,i4,ii, j,j3,j4,jj, k3,k4,kk;
// int m3,m4, ng,okZ,okH,nx,nz;
// int aa5,id; // int PLL=2; // 0:1:2
    var okZ: Int;
    var okH: Int;
    var aa5: Int;
    var ng: Int;
    var nx: Int;
    var nz: Int;
    var id: Int;
    var i3: Int;
    var i4: Int;
    var j3: Int;
    var j4: Int;
    var k3: Int;
    var k4: Int;
    var kk: Int;
    var m3: Int;
    var m4: Int;
    var Spc=" ";
    kk=54*nr;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print("%2d%1d",s[i],p[i]);} print(" 5");
    ng=0; m3=0; i4=1; nx=0; nz=0; aa5=0;
    for(i in 1..4) {if(p[cr[i-1]]!=p[cs[i]]) {ng=ng+1;} else {i4=i;}}
    if(kkkk==5) print(" ng,i4 = $ng $i4");
    j4=0;
    if(ng==4 && PLL>1) {
        okZ=0; for(j in 1..4) {if(p[gs[j]]==p[cs[j]]) {okZ=okZ+1;}}
        if(kkkk==5) print("\n okZ = $okZ");
        if(okZ==4)     {aa5=3; j4=1; nz=15;}   // fan+  -/-

        if(j4==0) {
            okH=0; for(j in 1..4) {if(p[cr[j-1]]==p[gs[j]]) {okH=okH+1;}}
            if(okH==4) {aa5=4; j4=1; nz=15;}   // fan-  -\-
        }
        if(j4==0) {
            for(k4 in 1..4) {               // [1:2,k4] : [2:3,k1]
                if(p[cr[k4-1]]==p[gs[k4]] && p[gs[k4+1]]==p[cs[k4+1]])
                {aa5=5; j4=k4; nz=17;}  // arrow \/
            }
        }
        if(j4==0) {
            for(k4 in 1..4) {k3=(k4+2)%4+1; // [1:2,k4] : [2:3,k3]
                if(p[cr[k3]]==p[gs[k4]] && p[gs[k3]]==p[cs[k3]])
                {aa5=6; j4=k4; nz=14;}  // kite  \\-
            }
        }
    }
    if(kkkk==5) print(" ng,j4 = $ng $j4");
    if(j4>0) {
        // var f = intArrayOf(0,1,2,4,5,1);
        m4=fx[p[gs[j4]]];
        m3=(m4-j4+4)%4;
        id=m4;
        if(aa5==3) nx=Formula12realface(a5C,nmx,nz,id,3,m3);
        if(aa5==4) nx=Formula12realface(a5D,nmx,nz,id,3,m3);
        if(aa5==5) nx=Formula12realface(a5E,nmx,nz,id,3,m3);
        if(aa5==6) nx=Formula12realface(a5F,nmx,nz,id,3,m3);
        if(kkkk<0) print("\nPLL5:f1:j4:ng(34) = ${f[id]} $j4 $ng $nx:");
        return nx;
    }
    i3=(i4+2)%4+1; k3=3*i3-4; k4=3*i4-4; nz=9;
    if(kkkk==5) print(" ng,i4 = $ng $i4");
    if(ng<=3) {
        for(j in 1..4) {
            if(p[cr[i3]]==f[j]) {j4=j; m3=(j4-i4+4)%4;}
        }
    }
    j3=(j4+2)%4+1;
    if(kkkk==5) print("\n i34j34k34 = $i3 $i4 $j3 $j4 $k3 $k4");
    if(ng==0)      {nz=0; id=1;  aa5=1;}     // a5[1 = intArrayOf(0); {30+m3); m3>0
    else if(ng==3 && p[cr[i3]]==p[gs[i3]])   // i3 <- i4 +m3 j4 <- j1
    {m3=(m3+1)%4; id=j4; aa5=2;}     // a5B e4A
    else  // also for ng==4                  // i4 -> i1 +m3 j3 -> j4
    {m3=(m3+3)%4; id=j3; aa5=1;}     // a5A e4B

    if(kkkk==5) print("\nS3c5:i4,j4,id,m3,aa0,nz : $i4 $j4 $id $m3 $aa5 $nz");
    if(aa5==1) nx=Formula12realface(a5A,nmx,nz,id,3,m3);
    if(aa5==2) nx=Formula12realface(a5B,nmx,nz,id,3,m3);
    if(nx<10) Spc="  "; else Spc=" ";
    if(kkkk<0) print("\nS3c5:f1:i4 (1234) = ${f[id]} $i4$Spc$nx: ");
    return nx;
}

private fun SolveS3e6(nr:Int):Int {
// use formula base on (T) hand      // (L):1:3; (R):2:3;  (T):Two hand
// a2A=[+2 +3 +2 +3 +2 -3 -2 -3 -2]; // [+23232 -3232]     (R)DoDoD iUiU
// a2B=[-1 -3 -1 -3 -1 +3 +1 +3 +1]; // [-13131 +3131]     (L)DoDoD iUiU
// a3A=[+2 +3 +1 -3 -1 -2];          // [+231 -312]        (R)Do (L)Uo D (R)U
// a4A=[+2 +3 -2 +3 +2 .3 -2 -3];    // [+23 -2 +32 -3323] (R)DoUoD iiUi
// a4B=[-1 -3 +1 -3 -1 .3 +1 +3];    // [-13 +1 -31 +3313] (L)DoUoD iiUi
// 5A;5B;                            // (R)UoU (L)UU (R)DiU (L)UU (R)UU
// a5A=[-2 +4 -2 .1 +2 -4 -2 .1 .2]; // [-2 +4 -211 +2 -421122] e4B
// a5B=[+1 -5 +1 .2 -1 +5 +1 .2 .1]; // [+1 -5 +122 -1 +512211] e4B
// a6A=[a2B .3 a2B]; a7A=[a4A -a4A]; // a6A,a6B better than a7A,a7B
// a6B=[a2A .3 a2A]; a7B=[a4B -a4B]; //
// a8A[11]=[-2 +3 -2 -3 -2 -3 -2 +3 +2 +3 .2]; // [-2+3 -23232 +32322] (R)Uo UiUiU oDoDD
// a8B[11]=[+1 -3 +1 +3 +1 +3 +1 -3 -1 -3 .1]; // [+1-3 +13131 -31311] (L)Uo UiUiU oDoDD
// a8C[10]=[+2 +5 .3 -5 -2 +1 +4 .3 -4 -1];       // +
// a8D[12]=[.1 .4 -6 .5 .1 .4 .2 .1 .4 +6 .1 .4]; // // [.X -3 .2 .X .2 .X +3 .X]
// a8E[12]=[.1 .4 +6 .5 .1 .4 .2 .1 .4 -6 .1 .4]; // \\ [.X +3 .2 .X .2 .X -3 .X]
//--------------------------------------------------------------------------
// (L)2A4:2B1;  (R)2A1:2B2;  (T)2A1R:2B1L
//         c2                 c2           (L)2A4:13[+ + + + + - - - -]
//      e3    e2           e3    e2        (L)2B1:13[- - - - - + + + +]
//   c3    2B    c1     c3    2A    c1     (R)2A1:23[+ + + + + - - - -]
//     (e4)   e1           e3   (e1)       (R)2B2:23[- - - - - + + + +]
//   L  +>(c4)               (c4)<+  R     (T)2A1:(R)DoDoDiUiU
//        [c4 c4L c3] [c1 c4R c4]          (T)2B1:(L)DoDoDiUiU
//
// (L)3A        (R)3A        (T)3A
//         c3                 c3           (L)3A :[+2 +3 +1 -3 -1 -2]
//     (e4)   e3          (e4)  (e3)       (L)3A :[+2 +3 +1 -3 -1 -2]
//   c4    3A    c2     c4    3B    c2     (R)3A :[+2 +3 +1 -3 -1 -2]
//      e1   (e2)          e1    e2        (R)3A :[+2 +3 +1 -3 -1 -2]
//        (c1)               (c1)          (T)3A :(R)Do (L)Uo D (R)U
//        [c4 c4L c3] [c1 c4R c4]          (T)3A :(R)Do (L)Uo D (R)U
//
// (L)4A2:4B3;  (R)4A3:4B4;  (T)4A3R:4B3L
//        (c4)               (c4)          (L)4A2:13[+ + - + + -- - -]
//     (e1)   e4           e1   (e4)       (L)4B3:13[- - + - - ++ + +]
//  +c1    4A  | c3+   -c1 |  4B    c3-    (R)4A3:23[+ + - + + -- - -]
//      e2  > e3           e2 <  e3        (R)4B4:23[- - + - - ++ + +]
//        +c2     R     L    -c2           (T)4A3:(R)DoUoDiiUi
//        [c3 c2L c2] [c2 c2R c1]          (T)4B3:(L)DoUoDiiUi
//
// (L)5A5:5B2;  (R)5A1:5B4;  (T)5A1R:5B2L                   e4          e4
//        (c2)               (c1)          (L)5A4:[-1 +2 -1 .5 +1 -2 -1 .5 .1]e4T
//      e3    e2           e2    e1       *(L)5B2:[+1 -5 +1 .2 -1 +5 +1 .2 .1]e4B
//   c3    5A    c1     c2    5B    c4    *(R)5A1:[-2 +4 -2 .1 +2 -4 -2 .1 .2]e4B
//     (e4)   e1           e3   (e4)       (R)5B4:[+2 -1 +2 .4 -2 +1 +2 .4 .2]e4T
//         c4     R     L     c3      e4B *(T)5A1:(R)UoU (L)UU (R)DiU (L)UU (R)UU
//        [c1 c4L c4] [c3 c3R c2]     e4B *(T)5B2:(L)UoU (R)UU (L)DiU (R)UU (L)UU
//
// (L)6A2:6B5;  (R)6A4:6B1;  (T)6A2L:6B1R
//         c1                 c2           (L)6A2:13[2B1 .3 2B1][-.. .3 -..]
//      e2 <  e1           e3  > e2        (L)6B5:13[2A4 .3 2A4][+.. .3 +..]
//   c2 |  6A    c4     c3    6B  | c1     (R)6A4:23[2B2 .3 2B2][-.. .3 -..]
//      e3   (e4)         (e4)   e1        (R)6B1:23[2A1 .3 2A1][+.. .3 +..]
//   L     c3                 c4     R     (T)6A2:(L)DoDoDiUiU oo DoDoDiUiU
//        [c3 c3L c2] [c1 c4R c4]          (T)6B1:(R)DoDoDiUiU oo DoDoDiUiU
//
// (L)7A5:7B2;  (R)7A1:7B4;  (T)7A1R:7B2L
//         c2                 c1           (L)7A5:13[4A2 4B3][++-++..  --+--..]
//      e3 <  e2           e2  > e1        (L)7B2:13[4B3 4A2][--+--..  ++-++..]
//   c3    7A  | c1     c2 |  7B    c4     (R)7A1:23[4A3 4B4][++-++..  --+--..]
//     (e4)   e1           e3   (e4)       (R)7B4:23[4B4 4A3][--+--..  ++-++..]
//         c4     R     L     c3           (T)7A1:(R)DoUoDiiUi C3- (L)DoUoDiiUi
//        [c1 c4R c4] [c3 c3L c2]          (T)7B2:(L)DoUoDiiUi C3+ (R)DoUoDiiUi
//        [c1 c1L c4] [c3 c2R c2]
// (L)8A2:8B4;  (R)8A3:8B1;  (T)8A3R:8B4L
//         c4                 c3           (L)8A2:13[-+ -----+++.]
//      e1   (e4)         (e4)   e3        (L)8B4:13[+- +++++---.]
//   c1  | 8A    c3     c4    8B  | c2     (R)8A3:23[-+ -----+++.]
//      e2  > e3           e1 <  e2        (R)8B1:23[+- +++++---.]
//         c2     R     L     c1           (T)8A3:(R)Uo UiUiU oDoDD
//        [c3 c2R c2] [c1 c1L c4]          (T)8B4:(L)Uo UiUiU oDoDD
//        [c3 c3L c2] [c1 c4R c4]
//--------------------------------------------------------------------------
    var a6A = intArrayOf(23,31,23,33,23,33,23,31,21,31,22); // v+ [-2+3 -23232 +32322]
    var a6B = intArrayOf(11,33,11,31,11,31,11,33,13,33,12); // ^- [+1-3 +13131 -31311]
//  a6C = intArrayOf(21,51,32,53,23,11,41,32,43,11); i1:i3  (no X rotate)
    var a6C = intArrayOf(22,72,22,33,22,72,22,31); // +  i1:i3   D <-> D : (.2X2X)=(.X2X2)
    var a6D = intArrayOf(72,33,22,72,22,72,31,72); // // i1:i2 [.X -3  .2 .X .2 .X  +3 .X]
    var a6E = intArrayOf(72,31,22,72,22,72,33,72); // \\ i1:i4 [.X +3  .2 .X .2 .X  -3 .X]
//  f   = intArrayOf(0, 1,2,4,5);
//  g   = intArrayOf(26,25, 28,27, 30,29, 32,31, 26,25); // L3_edges:side(1):top(2)
//  gu  = intArrayOf(0, 25,27,29,31,25);
//  gs  = intArrayOf(0, 26,28,30,32,26);
// int s[55],p[55];
// int i,i1,i2,i3,i4,ii, kk,ng,nx,nz;
// int aa6,id; // int PLL=2; // 0:1:2
    var aa6: Int;
    var ng: Int;
    var nx: Int;
    var nz: Int;
    var id: Int;
    var i1: Int;
    var i2: Int;
    //  i3: Int;
    var i4: Int;
    var kk: Int;
    kk=54*nr;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print("%2d%1d",s[i],p[i]);} print(" 6");
    ng=0; i4=1; nx=0;
    for(i in 1..4) {
        if(p[gs[i]]+p[gu[i]]!=s[gs[i]]+s[gu[i]]) ng=ng+1; else i4=i;
    }
    i1=i4%4+1; i2=i1%4+1; // i3=i2%4+1;
    if(ng==4 && PLL>0) { nz=8; id=1;
        if     (p[gs[1]]+p[gu[1]]==s[gs[3]]+s[gu[3]]) aa6=3; // +   i1:i3
        else if(p[gs[1]]+p[gu[1]]==s[gs[2]]+s[gu[2]]) aa6=4; // //  i1:i2
        else                                          aa6=5; // \\  i1:i4
        if(aa6==3) nx=Formula12realface(a6C,nmx,nz,id,3,0);
        if(aa6==4) nx=Formula12realface(a6D,nmx,nz,id,3,0);
        if(aa6==5) nx=Formula12realface(a6E,nmx,nz,id,3,0);
        if(kkkk<0) print("\nS3e6:f1:i4 (1234) = ${f[id]} $i4  $nx: ");
        return nx;
    }
    nz=11;
    if(p[gs[i1]]+p[gu[i1]]==s[gs[i2]]+s[gu[i2]]) { // i1 : i2
        aa6=1; id=i2; // {-2,+3,-2,-3,-2,-3,-2,+3,+2,+3,.2);  // v+
    } else {          // (R)Uo  UiUiU          oDoDD
        aa6=2; id=i1; // {+1,-3,+1,+3,+1,+3,+1,-3,-1,-3,.1);  // ^-
    }
    if(aa6==1) nx=Formula12realface(a6A,nmx,nz,id,3,0);
    if(aa6==2) nx=Formula12realface(a6B,nmx,nz,id,3,0);
    if(kkkk<0) print("\nS3e6:f1:i4 (1234) = ${f[id]} $i4 $nx: ");
    return nx;
}

private fun SolveL121(nr:Int):Int {
// F2L : First 2 Layers
    var a2A = intArrayOf(23,33,21);
    var a2B = intArrayOf(23,32,21);
    var a2C = intArrayOf(23,31,21);
    var a2D = intArrayOf(11,31,13);
    var a2E = intArrayOf(11,32,13);
    var a2F = intArrayOf(11,33,13);
    var fx  = intArrayOf(0, 1,2,0,3,4);
//  f   = intArrayOf(0, 1,2,4,5,1);
//  g   = intArrayOf(26,25, 28,27, 30,29, 32,31);             // L3_edge {s t}
//  z   = intArrayOf(41,42, 44,43, 45,46, 48,47);             // L2_edge {L R}
//  u   = intArrayOf(1,2,3, 4,5,6, 7,8,9, 10,11,12);          // L3_corner {t s s} in cc
//  d   = intArrayOf(13,14,15, 16,17,18, 19,20,21, 22,23,24); // L1_corner {b s s} in cc
    var x3  = intArrayOf(0, 0,0,3,2,0,0,2,1, 0,3,1,1,3,1,1,0, 3,1,0,3,1,0,3,3);
    var a2G = IntArray(3);
// int s[55],p[55];
// int i,i1,i2,i3,i4,ii, j,j1,j2,j3,j4,jj;
// int k,k1,k2,k3,k4,kk, m2,m3,m4,m6,n4, nz,nx,ic;
// int f1,f2,f3;
// int aa2,id;
    var aa2: Int;
    var nz: Int;
    var nx: Int;
    var n4: Int;
    var ic: Int;
    var id: Int;
    var i4: Int;
    var ii: Int;
    var j4: Int;
    var jj: Int;
    var k1: Int;
    var k2: Int;
    var k3: Int;
    var k4: Int;
    var kk: Int;
    var m2: Int;
    var m3: Int;
    var m4: Int;
    var f1: Int;
    var f2: Int;
    var f3: Int;
    var Spc=" ";
    kk=54*nr; nz=3;
    for(i in 1..54) p[i]=t[i+kk]; /// if(i<=48) print("%2d%1d",s[i],p[i]);} print(" 2");
    jj=0; k2=0; k3=0; k4=0; nx=0; aa2=0; // ii=0; k1=0;
// E3C3
    for(i4 in 1..4) { ii=2*i4-3;   // E3
        if(kkkk==2) print(" x1 i4 : $i4");
        if(p[g[1+ii]]==3 || p[g[2+ii]]==3) continue;
        if(kkkk==2) print(" x11");
        f1=p[g[1+ii]];  f3=p[g[2+ii]];  j4=0;
        for(j in 1..4) { jj=3*j-4; // C3
            for(k in 1..3) {
                if(p[u[k+jj]]==6) {
                    k3=k; k1=k3%3+1; k2=k1%3+1;
                    if     (p[u[k1+jj]]==f1 && p[u[k2+jj]]==f3) {j4=j; k4=1; break;}
                    else if(p[u[k2+jj]]==f1 && p[u[k1+jj]]==f3) {j4=j; k4=2; break;}
                }
            }
            if(j4>0) break;
        }
        // Case 0:6 7:8
        if(kkkk==2) print(" j4 : $j4\n");
        if(j4>0) { jj=3*j4-4;
            id=p[u[k2+jj]];
            m4=fx[id]; id=m4;
            m2=(i4-j4+4)%4+1;
            ic=(k3-1)*8+(k4-1)*4+m2; // 1:24
            // x3 = intArrayOf(0, 0,0,3,2,0,0,2,1, 0,3,1,1,3,1,1,0, 3,1,0,3,1,0,3,3);
            m3=(m4-j4+4+x3[ic])%4;
            when(ic) {
                10 -> aa2=3; // break; // C|E  7- -3
                16 -> aa2=4; // break; // C/E  8+  0
                19 -> aa2=1; // break; // C/E  8-  0
                21 -> aa2=6; // break; // C|E  7+ +3
                else -> j4=0; // continue;
            }
            if(j4==0) continue;
            if(kkkk==2) print("\n1 $aa2:");
            if(aa2==1) nx=Formula12realface(a2A,nmx,nz,id,3,m3);
            if(aa2==3) nx=Formula12realface(a2C,nmx,nz,id,3,m3);
            if(aa2==4) nx=Formula12realface(a2D,nmx,nz,id,3,m3);
            if(aa2==6) nx=Formula12realface(a2F,nmx,nz,id,3,m3);
            if(ic<10) Spc="  "; else Spc=" ";
            if(kkkk<0) print("\nE3C3:jk:ik($j4$k3:$i4$k4) = ${f[id]}$Spc$ic $nx: ");
            return nx;
        }
    }
// E3C1
    for(i4 in 1..4) { ii=2*i4-3;   // E3
        if(kkkk==2) print(" x2 i4 : $i4");
        if(p[g[1+ii]]==3 || p[g[2+ii]]==3) continue;
        if(kkkk==2) print(" x21");
        f1=p[g[1+ii]];  f3=p[g[2+ii]];  j4=0;
        for(j in 1..4) { jj=3*j-4; // C1
            if(kkkk==2) print(" x211 j : $j");
            for(k in 1..3) {
                if(kkkk==2) print("\n x2111 k,jj,f1,f3 : $k $jj $f1 $f3");
                if(p[d[k+jj]]==6) {
                    k3=k; k1=k3%3+1; k2=k1%3+1;
                    if(kkkk==2) print("\n x21111 k1:3,d1:2,p1:2 : $k1 $k2 $k3 ${d[k1+jj]} ${d[k2+jj]} ${p[d[k1+jj]]} ${p[d[k2+jj]]}");
                    if     (p[d[k1+jj]]==f1 && p[d[k2+jj]]==f3) {j4=j; k4=1; break;}
                    else if(p[d[k2+jj]]==f1 && p[d[k1+jj]]==f3) {j4=j; k4=2; break;}
                }
            }
            if(kkkk==2) if(j4>0) print(" x21111 j4,k4 : $j4 $k4");
            if(j4>0) break;
        }
        if(kkkk==2) print(" j4 : $j4\n");
        if(j4>0) {
            n4=fx[p[d[k2+jj]]];
            if(kkkk==2) print("\n2 j4 : $j4:");
            if(k3==1) { // 6D
                m3=(j4-i4+k4+5)%4;   // m3=j4-i4+(k4-1)+2+4
                // m4=(n4-j4+k4*2+1)%4; // m4=n4-j4+(k4-1)*2+3
                if(k4==1) a2G = intArrayOf(11,33,13);
                else      a2G = intArrayOf(23,31,21);
                // a2G = intArrayOf((4-3*k4),(6*k4-9),(3*k4-4));
                if(kkkk==2) print("\n6D m3 : $m3");
                nx=Formula12realface(a2G,nmx,nz,j4,3,m3);
            } else {   // 6R
                m3=(j4-i4-k4+6)%4;   // m3=j4-i4+(2-k4)+4
                // m4=(n4-j4-k3*2+9)%4; // m4=n4-j4+(3-k3)*2+3
                if(k4==1) a2G = intArrayOf(23,31+k3%3,21);
                else      a2G = intArrayOf(11,31+k3%3,13);
                // a2G = intArrayOf((3*k4-5),(6*k3-15),(5-3*k4));
                if(kkkk==2) print("\n6R m3 : $m3");
                nx=Formula12realface(a2G,nmx,nz,j4,3,m3);
            }
            // float a2[3]=[3*k4-5,6*k3-15,5-3*k4);
            // if k3==2;
            //     if k4==1;
            //         a2=[-2 -3 +2]; // m3=j4-i4+1 C/E
            //         a3=[-2 -3 +2]; // m4=n4-j4+5
            //     else;
            //         a2=[+1 -3 -1]; // m3=j4-i4   E|C
            //         a3=[+1 -3 -1]; // m4=n4-j4+5
            //     end
            // else;// k3==3;
            //     if k4==1;
            //         a2=[-2 +3 +2]; // m3=j4-i4+1 C|E
            //         a3=[-2 +3 +2]; // m4=n4-j4+3
            //     else;
            //         a2=[+1 +3 -1]; // m3=j4-i4   E/C
            //         a3=[+1 +3 -1]; // m4=n4-j4+3
            //     end
            // end
            // if(aa2==7) nx=Formula12realface(a2G,nmx,nz,j4,3,m3);
            if(kkkk<0) print("\nE3C1:jk:ik($j4$k3:$i4$k4) = ${f[j4]} ${f[n4]}  $nx: ");
            return nx;
        }
    }
// E3C3
    for(i4 in 1..4) { ii=2*i4-3;   // E3
        if(kkkk==2) print(" x3");
        if(p[g[1+ii]]==3 || p[g[2+ii]]==3) continue;
        if(kkkk==2) print(" x31");
        f1=p[g[1+ii]];  f3=p[g[2+ii]];  j4=0;
        for(j in 1..4) { jj=3*j-4; // C3
            for(k in 1..3) {
                if(p[u[k+jj]]==6) {
                    k3=k; k1=k3%3+1; k2=k1%3+1;
                    if     (p[u[k1+jj]]==f1 && p[u[k2+jj]]==f3) {j4=j; k4=1; break;}
                    else if(p[u[k2+jj]]==f1 && p[u[k1+jj]]==f3) {j4=j; k4=2; break;}
                }
            }
            if(j4>0) break;
        }
        // Case 0:6 7:8
        if(kkkk==2) print(" j4 : $j4\n");
        if(j4>0) { jj=3*j4-4;
            id=p[u[k2+jj]];
            m4=fx[id]; id=m4;
            m2=(i4-j4+4)%4+1;
            ic=(k3-1)*8+(k4-1)*4+m2; // 1:24
            // x3 = intArrayOf(0, 0,0,3,2,0,0,2,1, 0,3,1,1,3,1,1,0, 3,1,0,3,1,0,3,3);
            m3=(m4-j4+4+x3[ic])%4;
            when(ic) {
                1, 4, 11, 19 -> aa2=1; // break;
                2, 3, 12, 14 -> aa2=2; // break;
                10,15, 18, 22 -> aa2=3; // break;
                6, 7, 16, 24 -> aa2=4; // break;
                5, 8, 17, 23 -> aa2=5; // break;
                9,13, 20, 21 -> aa2=6; // break;
            }
            // case  1; a2=[-2 -3 +2  .3  -2 -3 +2  +3  -2 -3 +2];// Case 0  0
            // case  2; a2=[-2 .3 +2  +3  -2 -3 +2];              // Case 2  0
            // case  3; a2=[-2 .3 +2  -3  -2 +3 +2];              // Case 1 -3
            // case  4; a2=[-2 -3 +2  -3  -2 +3 +2];              // Case 1 .3
            // case  5; a2=[+1 .3 -1  -3  +1 +3 -1];              // Case 2  0
            // case  6; a2=[+1 +3 -1  .3  +1 +3 -1  -3  +1 +3 -1];// Case 0  0
            // case  7; a2=[+1 +3 -1  +3  +1 -3 -1];              // Case 1 .3
            // case  8; a2=[+1 .3 -1  +3  +1 -3 -1];              // Case 1 +3
            //
            // case  9; a2=[+1 -3 -1  .3  -2 -3 +2];// Case 3-  0
            // case 10; a2=[-2 +3 +2];              // C|E  7- -3
            // case 11; a2=[-2 -3 +2  .3  -2 +3 +2];// Case 4+ +3
            // case 12; a2=[-2 .3 +2  .3  -2 +3 +2];// Case 4+ +3
            // case 13; a2=[+1 -3 -1  +3  +1 +3 -1];// Case 6- -3
            // case 14; a2=[-2 .3 +2  -3  +1 +3 -1];// Case 5+ +3
            // case 15; a2=[-2 +3 +2  -3  +1 +3 -1];// Case 5+ +3
            // case 16; a2=[+1 +3 -1];              // C/E  8+  0
            //
            // case 17; a2=[+1 .3 -1  +3  -2 -3 +2];// Case 5- -3
            // case 18; a2=[-2 +3 +2  -3  -2 -3 +2];// Case 6+ +3
            // case 19; a2=[-2 -3 +2];              // C/E  8-  0
            // case 20; a2=[+1 -3 -1  +3  -2 -3 +2];// Case 5- -3
            // case 21; a2=[+1 -3 -1];              // C|E  7+ +3
            // case 22; a2=[-2 +3 +2  .3  +1 +3 -1];// Case 3+  0
            // case 23; a2=[+1 .3 -1  .3  +1 -3 -1];// Case 4- -3
            // case 24; a2=[+1 +3 -1  .3  +1 -3 -1];// Case 4- -3
            if(kkkk==2) print("\n4 $aa2:");
            if(aa2==1) nx=Formula12realface(a2A,nmx,nz,id,3,m3);
            if(aa2==2) nx=Formula12realface(a2B,nmx,nz,id,3,m3);
            if(aa2==3) nx=Formula12realface(a2C,nmx,nz,id,3,m3);
            if(aa2==4) nx=Formula12realface(a2D,nmx,nz,id,3,m3);
            if(aa2==5) nx=Formula12realface(a2E,nmx,nz,id,3,m3);
            if(aa2==6) nx=Formula12realface(a2F,nmx,nz,id,3,m3);
            if(ic<10) Spc="  "; else Spc=" ";
            if(kkkk<0) print("\nE3C3:jk:ik($j4$k3:$i4$k4) = ${f[id]}$Spc$ic $nx: ");
            return nx;
        }
    }
// E2C3 <- C3
    j4=0;
    for(j in 1..4) { jj=3*j-4;
        if(kkkk==2) print(" x4");
        for(k in 1..3) if(p[u[k+jj]]==6) {j4=j; k3=k; break;}
        if(kkkk==2) print(" j4,k : $j4 $k3\n");
        if(j4>0) { // C3
            k1=k3%3+1; k2=k1%3+1; i4=0;
            f1=p[u[k1+jj]]; f2=p[u[k2+jj]];
            for(i in 1..4) { ii=2*i-3; // E2
                if     (p[z[1+ii]]==f1 && p[z[2+ii]]==f2) {i4=i; k4=1; break;}
                else if(p[z[2+ii]]==f1 && p[z[1+ii]]==f2) {i4=i; k4=2; break;}
            }
            if(kkkk==2) print(" i4,f1:2,k1:4 = $i4 $f1 $f2 $k1 $k2 $k3 $k4\n");
            if(i4>0) {
                if(k3==1) { // 6U -> joint (E|C)(E/C) and move E2C3 to E3C3
                    m3=(i4-j4+4)%4;
                    id=i4; aa2=3;
                } else {    // 6R
                    m3=(i4-j4+3+(3-k3)*2)%4;
                    m4=(j4+m3-1)%4+1;
                    id=m4; aa2=7;
                    if(k3==2) {
                        if(k4==1) a2G = intArrayOf(13,33,11); // m3=i4-j4+5
                        else      a2G = intArrayOf(13,31,11);
                    } else {
                        if(k4==1) a2G = intArrayOf(21,31,23); // m3=i4-j4+3
                        else      a2G = intArrayOf(21,33,23);
                    }
                    // a2G = intArrayOf((3*k3-7),((5-2*k3)*(2*k4-3)*3),(7-3*k3));
                    if(aa2==7) nx=Formula12realface(a2G,nmx,nz,id,3,m3);
                    // if k3==2;
                    //     if k4==1; a2=[-1 -3 +1];     // m3=i4-j4+5
                    //     else;     a2=[-1 +3 +1]; end
                    // else;
                    //     if k4==1; a2=[+2 +3 -2];     // m3=i4-j4+3
                    //     else;     a2=[+2 -3 -2]; end
                    // end
                }
                if(kkkk==2) print("\n5 $aa2:");
                if(aa2==3) nx=Formula12realface(a2C,nmx,nz,id,3,m3);
                // if(aa2==7) nx=Formula12realface(a2G,nmx,nz,id,3,m3);
                if(kkkk<0) print("\nE2C3:jk:ik($j4$k3:$i4$k4) = ${f[id]} $id  $nx: ");
                return nx;
            }
        }
    }
// E2C1 <- E2
    for(i4 in 1..4) { ii=2*i4-3; // E2 : move E2 to E3
        if(kkkk==2) print("x5");
        if(p[z[1+ii]]!=f[i4] || p[z[2+ii]]!=f[i4+1]) {
            id=i4; aa2=3; // {-2,+3,+2);
            if(kkkk==2) print("\n6 $aa2:");
            if(aa2==3) nx=Formula12realface(a2C,nmx,nz,id,3,0);
            if(kkkk<0) print("\nE2C1:i4:i4( $i4: $i4) = ${f[id]} $id  $nx: ");
            return nx;
        }
    }
// E2C1 <- C1
    j4=0;
    for(j in 1..4) { jj=3*j-4; // C1 : move C1 to C3
        if(kkkk==2) print("x6");
        if(p[d[1+jj]]!=6 || p[d[2+jj]]!=f[j+1] || p[d[3+jj]]!=f[j]) {
            for(k in 1..3) if(p[d[k+jj]]==6) {j4=j; k3=k; break;}
        }
        if(kkkk==2) print("\nj4 : $j4");
    }
    if(kkkk==2) print(" j4 : $j4\n");
    if(j4>0) {
        id=j4;
        if(k3==3) aa2=4; // {+1,+3,-1}
        else      aa2=1; // {-2,-3,+2}
        if(kkkk==2) print("\n7 $aa2:");
        if(aa2==1) nx=Formula12realface(a2A,nmx,nz,id,3,0);
        if(aa2==4) nx=Formula12realface(a2D,nmx,nz,id,3,0);
        if(kkkk<0) print("\nE2C1:j4:j4( $j4: $j4) = ${f[id]} $id  $nx: ");
        return nx;
    }
// Error
    if(kkkk<0) print("\n error 0:");
    a2G = intArrayOf(11,12,11);
    return 3;
}

private fun RotateA(t:IntArray, L:Int, nm:Int):Unit {
    // rt[6][4][5],ip[8],t[54],o[54]
    /* val rt = intArrayOf(
        1, 2, 3,25,26,11,12,10,48,47,22,23,24,33,34,14,15,13,42,41,
        4, 5, 6,27,28, 2, 3, 1,41,42,13,14,15,35,36,17,18,16,43,44,
        6, 4, 5,30,29, 9, 7, 8,32,31,12,10,11,26,25, 3, 1, 2,28,27,
        7, 8, 9,29,30, 5, 6, 4,44,43,16,17,18,37,38,20,21,19,46,45,
        10,11,12,31,32, 8, 9, 7,45,46,19,20,21,39,40,23,24,22,47,48,
        15,13,14,34,33,24,22,23,40,39,21,19,20,38,37,18,16,17,36,35,
        27,28,51, 1, 1,32,31,53, 1, 1,39,40,54, 1, 1,36,35,50, 1, 1,  // face 7 X
        29,30,51, 1, 1,26,25,49, 1, 1,33,34,54, 1, 1,38,37,52, 1, 1,  // face 8 Y
        43,44,52, 1, 1,46,45,53, 1, 1,47,48,49, 1, 1,42,41,50, 1, 1); // face 9 Z
    */
    val ip = intArrayOf(0,1,2,3,0,1,2,3)
    var o0 = 54 * L
    var t0 = o0 - 54
    var nj0: Int
    var nj1: Int
    var n = nm / 10
    var m = nm - n * 10
    var n20 = 20*(n-1)
    for(i in 1..54) t[i+o0] = t[i+t0]
    for(j0 in 0..3) {
        nj0 = n20 + 5 * j0
        nj1 = n20 + 5 * ip[j0+m]
        for(i in 0..4) {                 // rt[0:119] := 1:48
            t[rt[nj1+i]+o0] = t[rt[nj0+i]+t0] // t[1:54]   := 1:6
        }
    }
    /* if(kkk > 0) {
      print48(t,L-1,"$nl1 t")
      print48(t,L,  "$nm n")
    } */
    return
}

private fun RotateB(x:IntArray, L:Int, nm:Int):Unit {
    // rx[2][4][6],ip[8],x[20],o[20]
    // square No of 6-rotations about 5-faces for RotateB
    val rx = intArrayOf(
        1,5,  4,20,  12,13,  9,17,
        2,6,  1,17,   9,14, 10,18,
        4,5,  1, 6,   2, 7,  3, 8,
        3,7,  2,18,  10,15, 11,19,
        4,8,  3,19,  11,16, 12,20,
        9,13, 12,16, 11,15, 10,14)
    val ip = intArrayOf(0,1,2,3,0,1,2,3)
    var o0 = 20 * L - 1
    var x0 = o0 - 20
    var nj0: Int
    var nj1: Int
    var n = nm / 10
    var m = nm - n * 10
    var n8 = 8 * (n - 1)
    for(i in 1..20) x[i+o0] = x[i+x0]
    for(j0 in 0..3) {
        nj0 = n8 + 2 * j0
        nj1 = n8 + 2 * ip[j0 + m]
        x[rx[nj1  ]+o0] = x[rx[nj0  ]+x0] // rx[0:47] := 1:20
        x[rx[nj1+1]+o0] = x[rx[nj0+1]+x0] // x[0:19]  := 0:19
    }
    /* if(kkk > 0) {
      for(i in 1..20) print("${x[i+x0]} ") // printf("%3d",x[i+x0]);
      print(" $nm t\n")                    // printf(" %4d RotB\n",nm);
      for(i in 1..20) print("${x[i+o0]} ") // printf("%3d",x[i+o0]);
      print(" $nm n\n")                    // printf(" %4d\n",nm);
    } */
    return
}

private fun CubicIC(t:IntArray, L:Int, xx:IntArray):Unit {
    var ix = intArrayOf(0,1,2,3,8,9,10,11,4,5,6,7,12,13,14,15,16,17,18,19)
    var t0 = 54 * L
    if(kkk > 7) {
        for(k in 1..6) {for(j in 1..6) {for(i in 1..6) {
            var kji = 36*k + 6*j + i - 43
            if(cc[kji] > 0) print("\n $i $j $k ${cc[kji]}")
            // printf("\n%2d%2d%2d%4d",i,j,k,cc[kji]);
        }}}
        for(j in 1..6) {for(i in 1..6) {
            var ji = 6*j + i - 7
            if(ce[ji] > 0) print("\n $i $j ${ce[ji]}")
            // printf("\n%2d%2d%4d",i,j,ce[ji]);
        }}
    }
    for(i in 0..7) {   // 3:3:24          2:3:23        1:3:22
        xx[ix[i]] = cc[36*t[3*i+3+t0] + 6*t[3*i+2+t0] + t[3*i+1+t0] - 43]
    }
    for(i in 8..19) { // 26:2:48       25:2:47
        xx[ix[i]] = ce[6*t[2*i+10+t0] + t[2*i+9+t0] - 7] // t[1:54] := 1:6
    }
    if(kkk > 7) {
        for(i in 0..19) print(" ${xx[i]}"); print("\n") // printf("%4d",xx[i]);
    }
    return
}
