// File: /workspace/github_cpp_makefile_star2_O3/xbai0624[P]dnn/src/UnitTest.cpp
// Function: UnitTest::TestCNN()
void UnitTest::TestCNN()
{
    // step1: setup all layers.............................................................................................................
    // 1) Data interface, this is a tool class, for data prepare
    DataInterface *data_interface = new DataInterface("unit_test_data/data_signal.dat", "unit_test_data/data_cosmic.dat", LayerDimension::_2D);

    // 3) input layer   ID=0
    LayerParameterList p_list0(LayerType::input, LayerDimension::_2D, data_interface, 0, 0, 
            std::pair<size_t, size_t>(0, 0), 0, false, 0, 0, Regularization::Undefined, 0, ActuationFuncType::Undefined, TrainingType::NewTraining, false);
    Layer* layer_input = new ConstructLayer(p_list0);
    layer_input->Init();

    // 4) middle layer 1 : cnn layer ID=1
    LayerParameterList p_list1(LayerType::cnn, LayerDimension::_2D, data_interface, 0, 2, 
            std::pair<size_t, size_t>(2, 2), 0.1, false, 0, 0.5, Regularization::L2, 0.1, ActuationFuncType::Relu, TrainingType::NewTraining, false);
    Layer *l1 = new ConstructLayer(p_list1);
    l1->SetPrevLayer(layer_input);
    l1->Init();

    // 4) middle layer 1 : fc layer ID=6
    LayerParameterList p_list6(LayerType::fullyConnected, LayerDimension::_1D, data_interface, 10, 0, 
            std::pair<size_t, size_t>(0, 0), 0.1, false, 0, 0.5, Regularization::L2, 0.1, ActuationFuncType::Relu, TrainingType::NewTraining, false);
    Layer *l6 = new ConstructLayer(p_list6);
    l6->SetPrevLayer(l1);
    l6->Init();

    // 5) output layer ID = 7
    LayerParameterList p_list_output(LayerType::output, LayerDimension::_1D, data_interface, 2, 0, 
            std::pair<size_t, size_t>(0, 0), 0.1, false, 0, 0., Regularization::L2, 0.1, ActuationFuncType::SoftMax, TrainingType::NewTraining, false);
    Layer* layer_output = new ConstructLayer(p_list_output);
    layer_output -> SetPrevLayer(l6);
    layer_output -> Init();

    // 6) connect all layers; SetNextLayer must be after all layers have finished initialization
    //                        input layer not needed to set, input layer has no update on w & b
    //                        input layer is just for data transfer (prepare)
    l1->SetNextLayer(l6);
    //l2->SetNextLayer(l3);
    l6->SetNextLayer(layer_output); // This line is ugly, to be improved


    // step 2: forward propagate
    data_interface -> Reset();
    layer_input->EpochInit();
    l1->EpochInit();
    l6->EpochInit();
    layer_output->EpochInit();

    //layer_input->BatchInit();
    l1->BatchInit();
    l6->BatchInit();
    layer_output->BatchInit();


    data_interface->GetNewBatchData();
    data_interface->GetNewBatchLabel();
    layer_input -> FillBatchDataToInputLayerA();


    int sample_size = data_interface->GetBatchSize();
    for(int i=0;i<sample_size;i++)
    {
        l1->ForwardPropagate_Z_ForSample(i);
        l1->ForwardPropagate_SigmaPrimeAndA_ForSample(i);
        l6->ForwardPropagate_Z_ForSample(i);
        l6->ForwardPropagate_SigmaPrimeAndA_ForSample(i);
        layer_output->ForwardPropagate_Z_ForSample(i);
        layer_output->ForwardPropagate_SigmaPrimeAndA_ForSample(i);
    }

    // helper functions
    auto print_a_images = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::'A' images from layer: "<<l->GetID()<<endl;
        auto & images = l->GetImagesFullA();
        int sample_IIID = 0;
        for(auto &i: images)
        {
            cout<<"---------------------- sample id: "<<sample_IIID<<endl;
            int kernel_id = 0;
            for(auto &j: i.OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
            sample_IIID++;
        }
    };
    auto print_z_images = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::'Z' images from layer: "<<l->GetID()<<endl;
        auto & images = l->GetImagesFullZ();
        int sample_IIID = 0;
        for(auto &i: images)
        {
            cout<<"---------------------- sample id: "<<sample_IIID<<endl;
            int kernel_id = 0;
            for(auto &j: i.OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
            sample_IIID++;
        }
    };


    auto print_W_B_images = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::W&B matrix from layer: "<<l->GetID()<<endl;
        auto w_images = l->GetWeightMatrixOriginal();
        auto b_images = l->GetBiasVectorOriginal();
        assert((*w_images).size() == (*b_images).size());

        for(size_t kernel = 0;kernel<(*w_images).size();kernel++)
        {
            cout<<"----kernel id: "<<kernel<<endl;
            cout<<"w"<<kernel<<":"<<endl;
            cout<<(*w_images)[kernel]<<endl;
            cout<<"b"<<kernel<<":"<<endl;
            cout<<(*b_images)[kernel]<<endl;
        }
    };

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    print_W_B_images(layer_input);
    print_z_images(layer_input);
    print_a_images(layer_input);

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_W_B_images(l1);
    //print_z_images(l1);
    //print_a_images(l1);

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_W_B_images(l6);
    //print_z_images(l6);
    //print_a_images(l6);

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_W_B_images(layer_output);
    //print_z_images(layer_output);
    //print_a_images(layer_output);


    // backward propagation
    for(int i=0;i<sample_size;i++)
    {
        // must inverse order
        layer_output->BackwardPropagateForSample(i);
        l6->BackwardPropagateForSample(i);
        l1->BackwardPropagateForSample(i);
    }


    auto print_sigmaPrime_images = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::'SigmaPrime' images from layer: "<<l->GetID()<<endl;
        auto & images = l->GetImagesFullSigmaPrime();
        int sample_IIID = 0;
        for(auto &i: images)
        {
            cout<<"---------------------- sample id: "<<sample_IIID<<endl;
            int kernel_id = 0;
            for(auto &j: i.OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
            sample_IIID++;
        }
    };

    auto print_delta_images = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::'Delta' images from layer: "<<l->GetID()<<endl;
        auto & images = l->GetImagesFullDelta();
        int sample_IIID = 0;
        for(auto &i: images)
        {
            cout<<"---------------------- sample id: "<<sample_IIID<<endl;
            int kernel_id = 0;
            for(auto &j: i.OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
            sample_IIID++;
        }
    };

    auto print_w_b_gradients = [&](Layer *l)
    {
        // print a images
        cout<<"XXXXXX::'w & b' gradients from layer: "<<l->GetID()<<endl;
        auto w_images = l->GetWeightGradients();
        auto b_images = l->GetBiasGradients();
        assert(w_images.size() == b_images.size());
        for(size_t i=0;i<w_images.size();i++)
        {
            cout<<"---------------------- sample id: "<<i<<endl;
            int kernel_id = 0;
            for(auto &j: w_images[i].OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
            kernel_id = 0;
            for(auto &j: b_images[i].OutputImageFromKernel)
            {
                cout<<"----kernel id: "<<kernel_id<<endl;
                cout<<j<<endl;
                kernel_id++;
            }
        }
    };

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    print_a_images(layer_output);
    print_sigmaPrime_images(layer_output); 
    print_delta_images(layer_output);
    print_W_B_images(layer_output);

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_a_images(l6);
    //print_sigmaPrime_images(l6); 
    //print_delta_images(l6);
    //print_W_B_images(l6);


    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_a_images(l1);
    //print_sigmaPrime_images(l1); 
    //print_delta_images(l1);
    //print_W_B_images(l1);

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_a_images(layer_input); 

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    print_w_b_gradients(l1); 

    // update weights and gradients
    layer_output->UpdateWeightsAndBias();
    l6->UpdateWeightsAndBias();
    //cout<<"?????????????????"<<endl;
    l1->UpdateWeightsAndBias();

    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_w_b_gradients(l1); 
    cout<<"ooooooooo000000000oooooooooo000000000ooooooooooo00000000oooooooooo0000000000000ooooooooooooo"<<endl;
    //print_W_B_images(l1);


}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
movl $0xc8, %edi
callq 0x4270
movq %rax, %r13
leaq 0x7bfa(%rip), %rsi      # 0x2b5bf
leaq 0x7c12(%rip), %rdx      # 0x2b5de
movq %rax, %rdi
movl $0x1, %ecx
callq 0x19144
movl $0x490, %edi            # imm = 0x490
callq 0x4270
movq %rax, %rbp
movabsq $0x100000003, %rax      # imm = 0x100000003
leaq 0x210(%rsp), %rsi
movq %rax, (%rsi)
movq %r13, 0x8(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rsi)
movups %xmm0, 0x20(%rsi)
movups %xmm0, 0x29(%rsi)
movl $0x0, 0x3c(%rsi)
xorl %r14d, %r14d
movq %r14, 0x40(%rsi)
movl $0x2, 0x48(%rsi)
movq %r14, 0x50(%rsi)
movq $0x4, 0x58(%rsi)
movb $0x0, 0x60(%rsi)
movl $0xd, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbp, %rdi
callq 0x4a54
movq (%rbp), %rax
movq %rbp, %rdi
callq *0x10(%rax)
movl $0x490, %edi            # imm = 0x490
callq 0x4270
movq %rax, %r12
movabsq $0x100000001, %rax      # imm = 0x100000001
leaq 0x1a8(%rsp), %rsi
movq %rax, (%rsi)
movq %r13, 0x8(%rsi)
movq $0x0, 0x10(%rsi)
movl $0x2, %eax
movq %rax, 0x18(%rsi)
movq %rax, 0x20(%rsi)
movq %rax, 0x28(%rsi)
movabsq $0x3fb999999999999a, %rbx # imm = 0x3FB999999999999A
movq %rbx, 0x30(%rsi)
movb %r14b, 0x38(%rsi)
movl %r14d, 0x3c(%rsi)
movabsq $0x3fe0000000000000, %r15 # imm = 0x3FE0000000000000
movq %r15, 0x40(%rsi)
movl %r14d, 0x48(%rsi)
movq %rbx, 0x50(%rsi)
movq $0x3, 0x58(%rsi)
movb %r14b, 0x60(%rsi)
movl $0xd, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r12, %rdi
callq 0x4a54
movq (%r12), %rax
movq %r12, %rdi
movq %rbp, %rsi
callq *0x1e8(%rax)
movq (%r12), %rax
movq %r12, %rdi
callq *0x10(%rax)
movl $0x490, %edi            # imm = 0x490
callq 0x4270
movq %rax, %r14
xorl %eax, %eax
leaq 0x140(%rsp), %rsi
movq %rax, (%rsi)
movq %r13, 0x8(%rsi)
movq $0xa, 0x10(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x18(%rsi)
movq %rax, 0x28(%rsi)
movq %rbx, 0x30(%rsi)
movb %al, 0x38(%rsi)
movl %eax, 0x3c(%rsi)
movq %r15, 0x40(%rsi)
movl %eax, 0x48(%rsi)
movq %rbx, 0x50(%rsi)
movq $0x3, 0x58(%rsi)
movb %al, 0x60(%rsi)
movl $0xd, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
callq 0x4a54
movq (%r14), %rax
movq %r14, %rdi
movq %r12, %rsi
callq *0x1e8(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *0x10(%rax)
movl $0x490, %edi            # imm = 0x490
callq 0x4270
movq %rax, %r15
leaq 0xd8(%rsp), %rsi
movq $0x4, (%rsi)
movq %r13, 0x8(%rsi)
movq $0x2, 0x10(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x18(%rsi)
movq $0x0, 0x28(%rsi)
movq %rbx, 0x30(%rsi)
xorl %eax, %eax
movb %al, 0x38(%rsi)
movups %xmm0, 0x3c(%rsi)
movq %rbx, 0x50(%rsi)
movq $0x1, 0x58(%rsi)
movb %al, 0x60(%rsi)
movl $0xd, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r15, %rdi
callq 0x4a54
movq (%r15), %rax
movq %r15, %rdi
movq %r14, %rsi
callq *0x1e8(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x10(%rax)
movq (%r12), %rax
movq %r12, %rdi
movq %r14, %rsi
callq *0x1f0(%rax)
movq (%r14), %rax
movq %r14, %rdi
movq %r15, %rsi
callq *0x1f0(%rax)
movq %r13, %rdi
callq 0x19d98
movq (%rbp), %rax
movq %rbp, %rdi
callq *0x18(%rax)
movq (%r12), %rax
movq %r12, %rdi
callq *0x18(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *0x18(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x18(%rax)
movq (%r12), %rax
movq %r12, %rdi
callq *0x88(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *0x88(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *0x88(%rax)
movq %r13, %rdi
callq 0x198a4
movq %r13, %rdi
callq 0x19bd4
movq (%rbp), %rax
movq %rbp, %rdi
callq *0x180(%rax)
movl (%r13), %r13d
testl %r13d, %r13d
jle 0x23cd3
xorl %ebx, %ebx
movq (%r12), %rax
movq %r12, %rdi
movl %ebx, %esi
callq *0x28(%rax)
movq (%r12), %rax
movq %r12, %rdi
movl %ebx, %esi
callq *0x30(%rax)
movq (%r14), %rax
movq %r14, %rdi
movl %ebx, %esi
callq *0x28(%rax)
movq (%r14), %rax
movq %r14, %rdi
movl %ebx, %esi
callq *0x30(%rax)
movq (%r15), %rax
movq %r15, %rdi
movl %ebx, %esi
callq *0x28(%rax)
movq (%r15), %rax
movq %r15, %rdi
movl %ebx, %esi
callq *0x30(%rax)
incl %ebx
cmpl %ebx, %r13d
jne 0x23c88
movl %r13d, 0x94(%rsp)
movq %r15, 0x80(%rsp)
movq %r14, 0x98(%rsp)
movq %r12, 0x88(%rsp)
movq 0x132de(%rip), %rbx     # 0x36fd8
leaq 0x7a73(%rip), %rsi      # 0x2b774
movl $0x5c, %edx
movq %rbx, %rdi
callq 0x4280
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %rbp, %rdi
callq 0x24858
leaq 0x7d12(%rip), %rsi      # 0x2ba56
movl $0x1f, %edx
movq %rbx, %rdi
callq 0x4280
movq (%rbp), %rax
movq %rbp, %rdi
callq *0x298(%rax)
movq %rbx, %rdi
movl %eax, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%rbp), %rax
movq %rbp, 0xb8(%rsp)
movq %rbp, %rdi
callq *0xe0(%rax)
movq (%rax), %r14
movq 0x8(%rax), %rax
movq %rax, 0x78(%rsp)
cmpq %rax, %r14
je 0x23ed4
xorl %ebx, %ebx
movq 0x13213(%rip), %r12     # 0x36fd8
leaq 0x7c76(%rip), %r13      # 0x2ba42
movl $0x22, %edx
movq %r12, %rdi
leaq 0x7c9b(%rip), %rsi      # 0x2ba76
callq 0x4280
movq %r12, %rdi
movl %ebx, 0x70(%rsp)
movl %ebx, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r14), %rbx
movq %r14, 0x68(%rsp)
movq 0x8(%r14), %rbp
cmpq %rbp, %rbx
je 0x23eba
xorl %r14d, %r14d
movl $0xf, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x4280
movq %r12, %rdi
movl %r14d, %esi
callq 0x43c0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1ba81
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
incl %r14d
addq $0x18, %rbx
cmpq %rbp, %rbx
jne 0x23e30
movl 0x70(%rsp), %ebx
incl %ebx
movq 0x68(%rsp), %r14
addq $0x18, %r14
cmpq 0x78(%rsp), %r14
jne 0x23dcc
movq 0xb8(%rsp), %rdi
callq 0x24ae4
leaq 0x788c(%rip), %rbx      # 0x2b774
movl $0x5c, %edx
movq 0x130e4(%rip), %r13     # 0x36fd8
movq %r13, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl 0x94(%rsp), %ebp
testl %ebp, %ebp
movq 0x88(%rsp), %r14
movq 0x98(%rsp), %r15
movq 0x80(%rsp), %r12
jle 0x23fe4
xorl %ebx, %ebx
movq (%r12), %rax
movq %r12, %rdi
movl %ebx, %esi
callq *0x38(%rax)
movq (%r15), %rax
movq %r15, %rdi
movl %ebx, %esi
callq *0x38(%rax)
movq (%r14), %rax
movq %r14, %rdi
movl %ebx, %esi
callq *0x38(%rax)
incl %ebx
cmpl %ebx, %ebp
jne 0x23fbc
leaq 0x7789(%rip), %rsi      # 0x2b774
movl $0x5c, %edx
movq %r13, %rdi
callq 0x4280
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %r12, %rdi
callq 0x24ae4
leaq 0x7a8a(%rip), %rsi      # 0x2bab9
movl $0x28, %edx
movq %r13, %rdi
callq 0x4280
movq (%r12), %rax
movq %r12, %rdi
callq *0x298(%rax)
movq %r13, %rdi
movl %eax, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r12), %rax
movq %r12, %rdi
callq *0xf0(%rax)
movq (%rax), %r14
movq 0x8(%rax), %rax
movq %rax, 0x78(%rsp)
cmpq %rax, %r14
je 0x241b7
xorl %ebx, %ebx
movq 0x12f30(%rip), %r12     # 0x36fd8
leaq 0x7993(%rip), %r13      # 0x2ba42
movl $0x22, %edx
movq %r12, %rdi
leaq 0x79b8(%rip), %rsi      # 0x2ba76
callq 0x4280
movq %r12, %rdi
movl %ebx, 0x70(%rsp)
movl %ebx, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r14), %rbx
movq %r14, 0x68(%rsp)
movq 0x8(%r14), %rbp
cmpq %rbp, %rbx
je 0x2419d
xorl %r14d, %r14d
movl $0xf, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x4280
movq %r12, %rdi
movl %r14d, %esi
callq 0x43c0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1ba81
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
incl %r14d
addq $0x18, %rbx
cmpq %rbp, %rbx
jne 0x24113
movl 0x70(%rsp), %ebx
incl %ebx
movq 0x68(%rsp), %r14
addq $0x18, %r14
cmpq 0x78(%rsp), %r14
jne 0x240af
movq 0x12e1a(%rip), %rbx     # 0x36fd8
leaq 0x791d(%rip), %rsi      # 0x2bae2
movl $0x23, %edx
movq %rbx, %rdi
callq 0x4280
movq 0x80(%rsp), %r14
movq (%r14), %rax
movq %r14, %rdi
callq *0x298(%rax)
movq %rbx, %rdi
movl %eax, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r14), %rax
movq %r14, %rdi
callq *0x100(%rax)
movq (%rax), %r14
movq 0x8(%rax), %rax
movq %rax, 0x78(%rsp)
cmpq %rax, %r14
je 0x24353
xorl %ebx, %ebx
movq 0x12d94(%rip), %r12     # 0x36fd8
leaq 0x77f7(%rip), %r13      # 0x2ba42
movl $0x22, %edx
movq %r12, %rdi
leaq 0x781c(%rip), %rsi      # 0x2ba76
callq 0x4280
movq %r12, %rdi
movl %ebx, 0x70(%rsp)
movl %ebx, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r14), %rbx
movq %r14, 0x68(%rsp)
movq 0x8(%r14), %rbp
cmpq %rbp, %rbx
je 0x24339
xorl %r14d, %r14d
movl $0xf, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x4280
movq %r12, %rdi
movl %r14d, %esi
callq 0x43c0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1ba81
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
incl %r14d
addq $0x18, %rbx
cmpq %rbp, %rbx
jne 0x242af
movl 0x70(%rsp), %ebx
incl %ebx
movq 0x68(%rsp), %r14
addq $0x18, %r14
cmpq 0x78(%rsp), %r14
jne 0x2424b
movq 0x80(%rsp), %rdi
callq 0x24858
leaq 0x740d(%rip), %rbx      # 0x2b774
movl $0x5c, %edx
movq 0x12c65(%rip), %r15     # 0x36fd8
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
leaq 0x76b5(%rip), %rsi      # 0x2bb06
movl $0x26, %edx
movq %r15, %rdi
callq 0x4280
movq 0x88(%rsp), %r14
movq (%r14), %rax
movq %r14, %rdi
callq *0x298(%rax)
movq %r15, %rdi
movl %eax, %esi
callq 0x43c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq (%r14), %rax
movq %r14, %rdi
callq *0x240(%rax)
leaq 0xa0(%rsp), %rdi
movq %rax, %rsi
callq 0x26c3c
movq (%r14), %rax
movq %r14, %rdi
callq *0x248(%rax)
leaq 0xc0(%rsp), %rdi
movq %rax, %rsi
callq 0x26c3c
movq 0xa0(%rsp), %rax
movq 0xa8(%rsp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
movq 0xc8(%rsp), %rsi
subq 0xc0(%rsp), %rsi
cmpq %rsi, %rdx
jne 0x247dd
cmpq %rax, %rcx
je 0x2470b
movq $0x0, 0x68(%rsp)
movq 0x12ab2(%rip), %rbp     # 0x36fd8
leaq 0x7515(%rip), %r12      # 0x2ba42
movl $0x22, %edx
movq %rbp, %rdi
leaq 0x753a(%rip), %rsi      # 0x2ba76
callq 0x4280
movq %rbp, %rdi
movq 0x68(%rsp), %rsi
callq 0x4180
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq 0xa0(%rsp), %rax
movq 0x68(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
movq (%rax,%rcx,8), %r14
movq %rcx, 0x70(%rsp)
movq 0x8(%rax,%rcx,8), %r13
cmpq %r13, %r14
je 0x2462a
xorl %ebx, %ebx
movl $0xf, %edx
movq %rbp, %rdi
movq %r12, %rsi
callq 0x4280
movq %rbp, %rdi
movl %ebx, %esi
callq 0x43c0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %rbp, %rdi
movq %r14, %rsi
callq 0x1ba81
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
incl %ebx
addq $0x18, %r14
cmpq %r13, %r14
jne 0x245a2
movq 0xc0(%rsp), %rax
movq 0x70(%rsp), %rcx
movq (%rax,%rcx,8), %r14
movq 0x8(%rax,%rcx,8), %r13
cmpq %r13, %r14
je 0x246d3
xorl %ebx, %ebx
movl $0xf, %edx
movq %rbp, %rdi
movq %r12, %rsi
callq 0x4280
movq %rbp, %rdi
movl %ebx, %esi
callq 0x43c0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movq %rbp, %rdi
movq %r14, %rsi
callq 0x1ba81
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
incl %ebx
addq $0x18, %r14
cmpq %r13, %r14
jne 0x2464b
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
movq 0x68(%rsp), %rdx
incq %rdx
sarq $0x3, %rax
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rax
movq %rdx, 0x68(%rsp)
cmpq %rax, %rdx
jb 0x2452d
leaq 0xc0(%rsp), %rdi
callq 0x1357a
leaq 0xa0(%rsp), %rdi
callq 0x1357a
movq 0x80(%rsp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
movq 0x98(%rsp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
movq 0x88(%rsp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
leaq 0x701e(%rip), %rbx      # 0x2b774
movl $0x5c, %edx
movq 0x12876(%rip), %r14     # 0x36fd8
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r14, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movl $0x5c, %edx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4280
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r14, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7349(%rip), %rdi      # 0x2bb2d
leaq 0x71ff(%rip), %rsi      # 0x2b9ea
leaq 0x7209(%rip), %rcx      # 0x2b9fb
movl $0x269, %edx            # imm = 0x269
callq 0x4160
movq %rax, %rbx
movq %r15, %rdi
jmp 0x24822
movq %rax, %rbx
movq %r14, %rdi
jmp 0x24822
movq %rax, %rbx
movq %r12, %rdi
jmp 0x24822
movq %rbp, %rdi
movq %rax, %rbx
jmp 0x24822
movq %rax, %rbx
movq %r13, %rdi
callq 0x4230
jmp 0x2484f
movq %rax, %rbx
jmp 0x24842
jmp 0x24832
jmp 0x24832
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x1357a
leaq 0xa0(%rsp), %rdi
callq 0x1357a
movq %rbx, %rdi
callq 0x43e0
nop