// File: /workspace/github_cpp_makefile_star2_O2/WeiqiangZhou[P]BIRD/source/predict_main.cpp
// Function: main
int main(int argc, char *argv[])
{
	char infile[255];
	char outfile[255];
    char outfile_expr[255];
	char libfile[255]="./model_file.bin";
	int write_flag = 0;
    int log_flag = 0;
	int locus_model = 0;
	double up_bound = 14;
	int opt;
    int match_mode = 0;
    std::string sep_str = ".";

	if(argc == 1)
	{
		help_info();
		return 1;
	}

	while ((opt = getopt(argc,argv,"b:i:o:u:wthle")) != EOF)
	{
		switch(opt)
		{
			case 'b':
				strcpy(libfile, optarg);
				break;
			case 'i':
				strcpy(infile, optarg);
				break;
			case 'o':
				strcpy(outfile, optarg);
				break;
			case 'u':
				up_bound = atof(optarg);
				break;
			case 'w':
				write_flag = 1;
				break;
            case 't':
                log_flag = 1;
                break;
			case 'h':
				help_info();
				return 1;
			case 'l':
				locus_model = 1;
				break;
            case 'e':
                match_mode = 1;
                break;
			case '?':
				std::cout << "Please input the correct parameters." << std::endl;
				std::cout << "Standard output: BIRD_predict -b model_file.bin -i input_file.txt -o output_file.txt" << std::endl;
				std::cout << "WIG output: BIRD_predict -b model_file.bin -i input_file.txt -o output_name -w" << std::endl;
				return 1;
			default:
				abort();
		}
	}

	//output parameters
	std::cout << "Using model file: " << libfile << std::endl;
	std::cout << "Input file name: " << infile << std::endl;
	std::cout << "Output file name: " << outfile << std::endl;
	std::cout << "Using upper bound: " << up_bound << std::endl;
	if(write_flag)
	{
		std::cout << "Output mode: wig file" << std::endl;
	}
	else
	{
		std::cout << "Output mode: data matrix" << std::endl;
	}

	if(locus_model)
	{
		std::cout << "Prediction mode: locus-level model" << std::endl;
	}
	else
	{
		std::cout << "Prediction mode: full model" << std::endl;
	}

	Exondata exonin;
	Exondata *indata = &exonin;
	int predictor_size, sample_size, cluster_size, var_size, loci_size, bin_size, DH_num1, DH_num2, DH_num3;

	if (ReadPar(libfile, loci_size, predictor_size, cluster_size, bin_size, var_size, DH_num1, DH_num2, DH_num3))
	{
		return 1;
	}

	double *quantile_in = new double[predictor_size];
	int *cluster_idx = new int[predictor_size];
	double *exon_mean = new double[predictor_size];
	double *exon_sd = new double[predictor_size];
	double *DNase_mean = new double[loci_size];
	double *DNase_sd = new double[loci_size];

	double **coef = new double *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		coef[j] = new double[loci_size]();
	}

	int **pre_idx = new int *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		pre_idx[j] = new int[loci_size]();
	}

	char **select_loci = new char *[loci_size];
	for (int j = 0; j < loci_size; j++)
	{
		select_loci[j] = new char[30];
	}

	char **TC_id = new char *[predictor_size];
	for (int j = 0; j < predictor_size; j++)
	{
		TC_id[j] = new char[30];
	}

	//DH cluster model
	double **dis_matrix = new double *[3];
	for (int j = 0; j < 3; j++)
	{
		dis_matrix[j] = new double[loci_size]();
	}

	int **DH_cluster = new int *[3];
	for (int j = 0; j < 3; j++)
	{
		DH_cluster[j] = new int[loci_size]();
	}

	double **DH_coef1 = new double *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_coef1[j] = new double[DH_num1]();
	}

	double **DH_coef2 = new double *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_coef2[j] = new double[DH_num2]();
	}

	double **DH_coef3 = new double *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_coef3[j] = new double[DH_num3]();
	}

	int **DH_pre_idx1 = new int *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_pre_idx1[j] = new int[DH_num1]();
	}

	int **DH_pre_idx2 = new int *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_pre_idx2[j] = new int[DH_num2]();
	}

	int **DH_pre_idx3 = new int *[var_size];
	for (int j = 0; j < var_size; j++)
	{
		DH_pre_idx3[j] = new int[DH_num3]();
	}

	//read in modle file
	if (ReadinModel(libfile, quantile_in, exon_mean, exon_sd, coef, DNase_mean, DNase_sd, pre_idx, TC_id, cluster_idx, select_loci, predictor_size, var_size, loci_size, dis_matrix, DH_cluster, DH_coef1, DH_coef2, DH_coef3, DH_pre_idx1, DH_pre_idx2, DH_pre_idx3, DH_num1, DH_num2, DH_num3))
	{
		return 1;
	}
	//read in gene expression data
	if (ReadinExon(infile, indata))
	{
		return 1;
	}

    int *match_idx = new int[predictor_size];
    
    //match and check gene expression data
    std::cout << "Matching the input gene expression data." << std::endl;
    if(match_mode == 1)
    {
        //use exact match
        if (MatchExon(TC_id, indata, predictor_size, match_idx))
        {
            std::cout << "Gene expression data format incorrect: No gene id matches the library file." << std::endl;
            std::cout << "Please check sample input file for reference." << std::endl;
            return 1;
        }
    }
    else
    {
        //match id before separate character
        if (MatchExon_sep(TC_id, indata, predictor_size, match_idx, sep_str))
        {
            std::cout << "Gene expression data format incorrect: No gene id matches the library file." << std::endl;
            std::cout << "Please check sample input file for reference." << std::endl;
            return 1;
        }
    }
    
    std::cout << "Processing data..." << std::endl;
    
	sample_size = (int)exonin.sample_name.size();

	double ** data_norm = new double *[sample_size];
	double ** data_mean = new double *[sample_size];
	double ** output = new double *[sample_size];
	double ** DH_pre1 = new double *[sample_size];
	double ** DH_pre2 = new double *[sample_size];
	double ** DH_pre3 = new double *[sample_size];

	for (int i = 0; i < sample_size; i++)
	{
		data_norm[i] = new double[predictor_size]();
		data_mean[i] = new double[cluster_size]();
		output[i] = new double[loci_size]();
		DH_pre1[i] = new double[DH_num1]();
		DH_pre2[i] = new double[DH_num2]();
		DH_pre3[i] = new double[DH_num3]();
	}

	for (int i = 0; i < sample_size; i++)
	{
		for (int j = 0; j < predictor_size; j++)
		{
            if(match_idx[j] != -1)
            {
                data_norm[i][j] = log2(exonin.data[match_idx[j]][i] + 1);
            }
            else
            {
                data_norm[i][j] = 0;
            }
		}
	}
    
    strcpy(outfile_expr, infile);
    strcat(outfile_expr, ".match.txt");
    WriteExpr(data_norm, exonin.sample_name, TC_id, outfile_expr, predictor_size, sample_size);
    
    for (int i = 0; i < sample_size; i++)
    {
        QuantileNorm(data_norm[i], quantile_in, predictor_size);
    }

	StandardizeRow(data_norm, exon_mean, exon_sd, predictor_size, sample_size); //standardize gene expression data
	ClusterMean(data_norm, data_mean, cluster_idx, predictor_size, cluster_size, sample_size); //get gene expression cluster mean;

	if(locus_model != 1)
	{
		//Locus level prediction
		Regression(data_mean, output, coef, pre_idx, var_size, loci_size, sample_size);

		//DH cluster level prediction
		Regression(data_mean, DH_pre1, DH_coef1, DH_pre_idx1, var_size, DH_num1, sample_size);
		Regression(data_mean, DH_pre2, DH_coef2, DH_pre_idx2, var_size, DH_num2, sample_size);
		Regression(data_mean, DH_pre3, DH_coef3, DH_pre_idx3, var_size, DH_num3, sample_size);

		//Combine result from locus level and DH cluster level
		ModelAverage(output, DH_pre1, DH_pre2, DH_pre3, dis_matrix, DH_cluster, loci_size, sample_size);
		std::cout << "Using full model for prediction." << std::endl;
	}
	else
	{
		//Locus level prediction
		Regression(data_mean, output, coef, pre_idx, var_size, loci_size, sample_size);
		std::cout << "Using locus-level model for prediction." << std::endl;
	}

  	//convert predicted value back to original scale
	StandardizeRow_r(output, DNase_mean, DNase_sd, loci_size, sample_size);

  	//write output file
	std::cout << "Writing output file..." << std::endl;
	if (WriteWIG(output, select_loci, exonin.sample_name, outfile, bin_size, loci_size, sample_size, write_flag, up_bound, log_flag))
	{
		return 1;
	}

	//release memory.
	ReleaseExondata(exonin);
	delete[] quantile_in;
	delete[] cluster_idx;
	for (int i = 0; i < sample_size; i++)
	{
		delete[] data_norm[i];
		delete[] data_mean[i];
		delete[] output[i];
		delete[] DH_pre1[i];
		delete[] DH_pre2[i];
		delete[] DH_pre3[i];
	}
	for (int i = 0; i < var_size; i++)
	{
		delete[] coef[i];
		delete[] pre_idx[i];
		delete[] DH_coef1[i];
		delete[] DH_coef2[i];
		delete[] DH_coef3[i];
		delete[] DH_pre_idx1[i];
		delete[] DH_pre_idx2[i];
		delete[] DH_pre_idx3[i];
	}
	for (int i = 0; i < 3; i++)
	{
		delete[] dis_matrix[i];
		delete[] DH_cluster[i];
	}
	for (int i = 0; i < predictor_size; i++)
	{
		delete[] TC_id[i];
	}
	for (int i = 0; i < loci_size; i++)
	{
		delete[] select_loci[i];
	}
	delete[] data_norm;
	delete[] data_mean;
	delete[] output;
	delete[] DH_pre1;
	delete[] DH_pre2;
	delete[] DH_pre3;
	delete[] coef;
	delete[] pre_idx;
	delete[] DH_coef1;
	delete[] DH_coef2;
	delete[] DH_coef3;
	delete[] DH_pre_idx1;
	delete[] DH_pre_idx2;
	delete[] DH_pre_idx3;
	delete[] TC_id;
	delete[] select_loci;
	delete[] dis_matrix;
	delete[] DH_cluster;
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x648, %rsp            # imm = 0x648
movq %rsi, %rbx
movl %edi, %r14d
leaq 0x4b33(%rip), %rsi      # 0x7080
leaq -0x370(%rbp), %rdi
movl $0xff, %edx
callq 0x2180
leaq 0x522d(%rip), %rsi      # 0x7792
leaq -0x220(%rbp), %rdi
leaq -0x1b0(%rbp), %rdx
callq 0x20d0
cmpl $0x1, %r14d
jne 0x25a6
callq 0x5718
pushq $0x1
popq %rbx
leaq -0x220(%rbp), %rdi
callq 0x2110
movl %ebx, %eax
addq $0x648, %rsp            # imm = 0x648
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x1
popq %r13
movsd 0x4a56(%rip), %xmm0     # 0x7008
movsd %xmm0, -0x128(%rbp)
movl $0x0, -0x100(%rbp)
leaq 0x4bb4(%rip), %r15      # 0x717f
leaq 0x4a4e(%rip), %r12      # 0x7020
movl $0x0, -0x6c(%rbp)
movq $0x0, -0x160(%rbp)
xorl %eax, %eax
movq %rax, -0x68(%rbp)
movl %r14d, %edi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x2080
leal -0x62(%rax), %ecx
cmpl $0x15, %ecx
ja 0x2689
movslq (%r12,%rcx,4), %rcx
addq %r12, %rcx
movl %r13d, %eax
jmpq *%rcx
movq 0x89b1(%rip), %rax      # 0xafc8
movq (%rax), %rsi
leaq -0x370(%rbp), %rdi
jmp 0x2662
movl %r13d, -0x100(%rbp)
jmp 0x2680
movl %r13d, -0x6c(%rbp)
jmp 0x2680
movl %r13d, %eax
movq %rax, -0x160(%rbp)
jmp 0x2680
movq 0x8983(%rip), %rax      # 0xafc8
movq (%rax), %rsi
leaq -0x670(%rbp), %rdi
jmp 0x2662
movq 0x8970(%rip), %rax      # 0xafc8
movq (%rax), %rsi
leaq -0x570(%rbp), %rdi
callq 0x21b0
jmp 0x2680
movq 0x8958(%rip), %rax      # 0xafc8
movq (%rax), %rdi
callq 0x2230
movsd %xmm0, -0x128(%rbp)
movq -0x68(%rbp), %rax
jmp 0x25e6
cmpl $-0x1, %eax
je 0x26ed
cmpl $0x3f, %eax
jne 0x36b8
movq 0x893a(%rip), %rdi      # 0xafd8
leaq 0x4ae8(%rip), %rsi      # 0x718d
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x891f(%rip), %rdi      # 0xafd8
leaq 0x4af2(%rip), %rsi      # 0x71b2
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x8904(%rip), %rdi      # 0xafd8
leaq 0x4b2c(%rip), %rsi      # 0x7207
callq 0x21d0
movq %rax, %rdi
callq 0x2120
jmp 0x2583
movq 0x88e4(%rip), %rdi      # 0xafd8
leaq 0x4b5b(%rip), %rsi      # 0x7256
callq 0x21d0
leaq -0x370(%rbp), %rsi
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x88ba(%rip), %rdi      # 0xafd8
leaq 0x4b44(%rip), %rsi      # 0x7269
callq 0x21d0
leaq -0x570(%rbp), %rsi
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x8890(%rip), %rdi      # 0xafd8
leaq 0x4b2c(%rip), %rsi      # 0x727b
callq 0x21d0
leaq -0x670(%rbp), %rsi
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x8866(%rip), %rdi      # 0xafd8
leaq 0x4b15(%rip), %rsi      # 0x728e
callq 0x21d0
movq %rax, %rdi
movsd -0x128(%rbp), %xmm0
callq 0x2300
movq %rax, %rdi
callq 0x2120
cmpl $0x0, -0x68(%rbp)
leaq 0x4b17(%rip), %rax      # 0x72b8
leaq 0x4afa(%rip), %rsi      # 0x72a2
cmoveq %rax, %rsi
movq 0x8825(%rip), %rdi      # 0xafd8
callq 0x21d0
movq %rax, %rdi
callq 0x2120
cmpl $0x0, -0x6c(%rbp)
leaq 0x4b29(%rip), %rax      # 0x72f4
leaq 0x4aff(%rip), %rsi      # 0x72d1
cmoveq %rax, %rsi
movq 0x87fb(%rip), %rdi      # 0xafd8
callq 0x21d0
movq %rax, %rdi
callq 0x2120
xorpd %xmm0, %xmm0
movapd %xmm0, -0x180(%rbp)
movapd %xmm0, -0x190(%rbp)
movapd %xmm0, -0x1a0(%rbp)
movapd %xmm0, -0x1b0(%rbp)
andq $0x0, -0x170(%rbp)
subq $0x8, %rsp
leaq -0x70(%rbp), %rax
leaq -0x74(%rbp), %r10
leaq -0x78(%rbp), %r11
leaq -0x370(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq -0x2c(%rbp), %rdx
leaq -0x108(%rbp), %rcx
leaq -0x12c(%rbp), %r8
leaq -0x3c(%rbp), %r9
pushq %rax
pushq %r10
pushq %r11
callq 0x4c7a
addq $0x20, %rsp
pushq $0x1
popq %rcx
movl %ecx, -0x104(%rbp)
testl %eax, %eax
jne 0x36a1
movslq -0x2c(%rbp), %r14
leaq (,%r14,8), %rdi
testq %r14, %r14
pushq $-0x1
popq %rbx
cmovsq %rbx, %rdi
movq %rdi, -0x58(%rbp)
callq 0x2030
movq %rax, -0x120(%rbp)
leaq (,%r14,4), %rdi
movq %r14, -0xb8(%rbp)
testl %r14d, %r14d
cmovsq %rbx, %rdi
callq 0x2030
movq %rax, -0x118(%rbp)
movq -0x58(%rbp), %rbx
movq %rbx, %rdi
callq 0x2030
movq %rax, -0x158(%rbp)
movq %rbx, %rdi
callq 0x2030
movq %rax, -0x150(%rbp)
movslq -0x30(%rbp), %r15
leaq (,%r15,8), %r14
testq %r15, %r15
pushq $-0x1
popq %rax
cmovsq %rax, %r14
movq %r14, %rdi
callq 0x2030
movq %rax, -0x148(%rbp)
movq %r14, %rdi
callq 0x2030
movq %rax, -0x140(%rbp)
movslq -0x3c(%rbp), %rbx
leaq (,%rbx,8), %rdi
testq %rbx, %rbx
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
movq %rdi, -0x50(%rbp)
callq 0x2030
movq %rax, -0x88(%rbp)
xorl %r13d, %r13d
testl %ebx, %ebx
movl $0x0, %eax
movq %rbx, -0x110(%rbp)
cmovgl %ebx, %eax
movq %rax, -0x38(%rbp)
cmpq %r13, -0x38(%rbp)
je 0x2970
movq %r14, %rdi
callq 0x2030
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0x88(%rbp), %rax
movq %r12, (%rax,%r13,8)
incq %r13
jmp 0x2942
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0x80(%rbp)
leaq (,%r15,4), %r12
testl %r15d, %r15d
pushq $-0x1
popq %rax
cmovsq %rax, %r12
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x29bc
movq %r12, %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x2140
movq -0x80(%rbp), %rax
movq %r13, (%rax,%rbx,8)
incq %rbx
jmp 0x2991
movq %r14, %rdi
callq 0x2030
movq %rax, -0xf8(%rbp)
xorl %ebx, %ebx
testl %r15d, %r15d
movq %r15, %rax
movl $0x0, %r15d
movq %rax, -0x48(%rbp)
cmovgl %eax, %r15d
pushq $0x1e
popq %r13
cmpq %rbx, %r15
je 0x2a02
movq %r13, %rdi
callq 0x2030
movq -0xf8(%rbp), %rcx
movq %rax, (%rcx,%rbx,8)
incq %rbx
jmp 0x29e5
movq -0x58(%rbp), %rdi
callq 0x2030
movq %rax, -0x58(%rbp)
xorl %ebx, %ebx
movq -0xb8(%rbp), %rax
testl %eax, %eax
movl $0x0, %r13d
cmovgl %eax, %r13d
pushq $0x1e
popq %r15
cmpq %rbx, %r13
je 0x2a42
movq %r15, %rdi
callq 0x2030
movq -0x58(%rbp), %rcx
movq %rax, (%rcx,%rbx,8)
incq %rbx
jmp 0x2a28
pushq $0x18
popq %rdi
callq 0x2030
movq %rax, -0xf0(%rbp)
xorl %ebx, %ebx
cmpq $0x3, %rbx
je 0x2a81
movq %r14, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0xf0(%rbp), %rax
movq %r15, (%rax,%rbx,8)
incq %rbx
jmp 0x2a53
pushq $0x18
popq %rdi
callq 0x2030
movq %rax, -0xe8(%rbp)
xorl %ebx, %ebx
cmpq $0x3, %rbx
je 0x2ac0
movq %r12, %rdi
callq 0x2030
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x2140
movq -0xe8(%rbp), %rax
movq %r14, (%rax,%rbx,8)
incq %rbx
jmp 0x2a92
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0xe0(%rbp)
movslq -0x78(%rbp), %rax
leaq (,%rax,8), %r14
movq %rax, -0xb0(%rbp)
testq %rax, %rax
pushq $-0x1
popq %rax
cmovsq %rax, %r14
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x2b1d
movq %r14, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0xe0(%rbp), %rax
movq %r15, (%rax,%rbx,8)
incq %rbx
jmp 0x2aef
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0xd8(%rbp)
movslq -0x74(%rbp), %rax
leaq (,%rax,8), %r14
movq %rax, -0xa8(%rbp)
testq %rax, %rax
pushq $-0x1
popq %rax
cmovsq %rax, %r14
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x2b7a
movq %r14, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0xd8(%rbp), %rax
movq %r15, (%rax,%rbx,8)
incq %rbx
jmp 0x2b4c
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0xd0(%rbp)
movslq -0x70(%rbp), %r13
leaq (,%r13,8), %r14
testq %r13, %r13
pushq $-0x1
popq %rax
cmovsq %rax, %r14
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x2bd0
movq %r14, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0xd0(%rbp), %rax
movq %r15, (%rax,%rbx,8)
incq %rbx
jmp 0x2ba2
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0xc8(%rbp)
movq -0xb0(%rbp), %rax
leaq (,%rax,4), %r14
testl %eax, %eax
pushq $-0x1
popq %rax
cmovsq %rax, %r14
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x2c28
movq %r14, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2140
movq -0xc8(%rbp), %rax
movq %r15, (%rax,%rbx,8)
incq %rbx
jmp 0x2bfa
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rax
leaq (,%rax,4), %r15
testl %eax, %eax
pushq $-0x1
popq %rax
cmovsq %rax, %r15
xorl %ebx, %ebx
cmpq %rbx, -0x38(%rbp)
je 0x2c80
movq %r15, %rdi
callq 0x2030
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x2140
movq -0xc0(%rbp), %rax
movq %r12, (%rax,%rbx,8)
incq %rbx
jmp 0x2c52
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, %r15
leaq (,%r13,4), %rbx
testl %r13d, %r13d
pushq $-0x1
popq %rax
cmovsq %rax, %rbx
xorl %r14d, %r14d
cmpq %r14, -0x38(%rbp)
je 0x2cc8
movq %rbx, %rdi
callq 0x2030
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
movq %rbx, %rdx
callq 0x2140
movq %r12, (%r15,%r14,8)
incq %r14
jmp 0x2ca1
subq $0x8, %rsp
leaq -0x370(%rbp), %rdi
movq -0x120(%rbp), %rsi
movq -0x158(%rbp), %rdx
movq -0x150(%rbp), %rcx
movq -0x88(%rbp), %r8
movq -0x148(%rbp), %r9
pushq %r13
pushq -0xa8(%rbp)
pushq -0xb0(%rbp)
pushq %r15
pushq -0xc0(%rbp)
pushq -0xc8(%rbp)
pushq -0xd0(%rbp)
pushq -0xd8(%rbp)
pushq -0xe0(%rbp)
pushq -0xe8(%rbp)
pushq -0xf0(%rbp)
pushq -0x48(%rbp)
pushq -0x110(%rbp)
pushq -0xb8(%rbp)
pushq -0xf8(%rbp)
pushq -0x118(%rbp)
pushq -0x58(%rbp)
pushq -0x80(%rbp)
pushq -0x140(%rbp)
callq 0x492a
addq $0xa0, %rsp
testl %eax, %eax
jne 0x36a1
leaq -0x570(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x4238
testl %eax, %eax
jne 0x36a1
movslq -0x2c(%rbp), %rax
leaq (,%rax,4), %rdi
testq %rax, %rax
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
callq 0x2030
movq %rax, %r12
movq 0x822d(%rip), %rdi      # 0xafd8
leaq 0x455e(%rip), %rsi      # 0x7310
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movl -0x2c(%rbp), %ebx
cmpl $0x0, -0x100(%rbp)
je 0x2e1f
leaq -0x1b0(%rbp), %rsi
movq -0x58(%rbp), %rdi
movl %ebx, %edx
movq %r12, %rcx
callq 0x3f41
testl %eax, %eax
je 0x2e60
movq 0x81ed(%rip), %rdi      # 0xafd8
leaq 0x4547(%rip), %rsi      # 0x7339
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq 0x81d2(%rip), %rdi      # 0xafd8
leaq 0x4578(%rip), %rsi      # 0x7385
callq 0x21d0
movq %rax, %rdi
callq 0x2120
jmp 0x36a1
leaq -0x200(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x2270
leaq -0x1b0(%rbp), %rsi
leaq -0x200(%rbp), %r8
movq -0x58(%rbp), %rdi
movl %ebx, %edx
movq %r12, %rcx
callq 0x3d32
movl %eax, %ebx
leaq -0x200(%rbp), %rdi
callq 0x2110
testl %ebx, %ebx
jne 0x2de4
movq 0x8171(%rip), %rdi      # 0xafd8
leaq 0x4545(%rip), %rsi      # 0x73b3
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movq -0x1a8(%rbp), %r14
subq -0x1b0(%rbp), %r14
movq %r14, %rax
shlq $0x1b, %rax
movq %rax, %r13
sarq $0x1d, %r13
testq %rax, %rax
pushq $-0x1
popq %rax
cmovsq %rax, %r13
movq %r13, %rdi
callq 0x2030
movq %rax, %rbx
movq %r13, %rdi
callq 0x2030
movq %rax, -0x60(%rbp)
movq %r13, %rdi
callq 0x2030
movq %rax, -0x48(%rbp)
movq %r13, %rdi
callq 0x2030
movq %rax, -0xa0(%rbp)
movq %r13, %rdi
callq 0x2030
movq %rax, -0x98(%rbp)
movq %r13, %rdi
callq 0x2030
movq %rax, -0x90(%rbp)
movq %r15, -0x168(%rbp)
shrq $0x5, %r14
movq %r14, %rdx
movslq -0x2c(%rbp), %r14
leaq (,%r14,8), %rsi
testq %r14, %r14
pushq $-0x1
popq %rcx
cmovsq %rcx, %rsi
movq %rsi, -0x100(%rbp)
movslq -0x108(%rbp), %rax
leaq (,%rax,8), %rsi
testq %rax, %rax
cmovsq %rcx, %rsi
movq %rsi, -0x50(%rbp)
movslq -0x30(%rbp), %rax
leaq (,%rax,8), %rsi
testq %rax, %rax
cmovsq %rcx, %rsi
movq %rsi, -0xb8(%rbp)
movslq -0x78(%rbp), %rax
leaq (,%rax,8), %rsi
testq %rax, %rax
cmovsq %rcx, %rsi
movq %rsi, -0xb0(%rbp)
movslq -0x74(%rbp), %rax
leaq (,%rax,8), %rsi
testq %rax, %rax
cmovsq %rcx, %rsi
movq %rsi, -0xa8(%rbp)
movslq -0x70(%rbp), %rax
leaq (,%rax,8), %rsi
testq %rax, %rax
cmovsq %rcx, %rsi
movq %rsi, -0x110(%rbp)
xorl %r15d, %r15d
testl %edx, %edx
movl $0x0, %eax
movq %rdx, -0x138(%rbp)
cmovgl %edx, %eax
movq %rax, -0x38(%rbp)
cmpq %r15, -0x38(%rbp)
je 0x30b7
movq -0x100(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0x100(%rbp), %rdx
callq 0x2140
movq %r13, (%rbx,%r15,8)
movq -0x50(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0x50(%rbp), %rdx
callq 0x2140
movq -0x60(%rbp), %rax
movq %r13, (%rax,%r15,8)
movq -0xb8(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0xb8(%rbp), %rdx
callq 0x2140
movq -0x48(%rbp), %rax
movq %r13, (%rax,%r15,8)
movq -0xb0(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0xb0(%rbp), %rdx
callq 0x2140
movq -0xa0(%rbp), %rax
movq %r13, (%rax,%r15,8)
movq -0xa8(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0xa8(%rbp), %rdx
callq 0x2140
movq -0x98(%rbp), %rax
movq %r13, (%rax,%r15,8)
movq -0x110(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq -0x110(%rbp), %rdx
callq 0x2140
movq -0x90(%rbp), %rax
movq %r13, (%rax,%r15,8)
incq %r15
jmp 0x2fb6
xorl %r15d, %r15d
cmpq -0x38(%rbp), %r15
je 0x311a
xorl %r13d, %r13d
movslq %r14d, %rax
cmpq %rax, %r13
jge 0x3115
movslq (%r12,%r13,4), %rax
cmpq $-0x1, %rax
je 0x3107
movq -0x180(%rbp), %rcx
imulq $0x18, %rax, %rax
movq (%rcx,%rax), %rax
movsd (%rax,%r15,8), %xmm0
addsd 0x3f1e(%rip), %xmm0     # 0x7010
callq 0x2360
movq (%rbx,%r15,8), %rax
movsd %xmm0, (%rax,%r13,8)
movl -0x2c(%rbp), %r14d
jmp 0x3110
movq (%rbx,%r15,8), %rax
andq $0x0, (%rax,%r13,8)
incq %r13
jmp 0x30c3
incq %r15
jmp 0x30ba
leaq -0x470(%rbp), %r12
leaq -0x570(%rbp), %rsi
movq %r12, %rdi
callq 0x21b0
movq %r12, %rdi
callq 0x20f0
movabsq $0x742e686374616d2e, %rcx # imm = 0x742E686374616D2E
movq %rcx, -0x470(%rbp,%rax)
movl $0x747874, -0x469(%rbp,%rax) # imm = 0x747874
leaq -0x1e0(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x3772
movq -0x168(%rbp), %r15
movq -0x138(%rbp), %r9
movl -0x2c(%rbp), %r8d
leaq -0x1e0(%rbp), %rsi
leaq -0x470(%rbp), %rcx
movq %rbx, %rdi
movq -0x58(%rbp), %rdx
callq 0x408f
leaq -0x1e0(%rbp), %rdi
callq 0x37c6
xorl %r14d, %r14d
cmpq %r14, -0x38(%rbp)
je 0x31c1
movq (%rbx,%r14,8), %rdi
movl -0x2c(%rbp), %edx
movq -0x120(%rbp), %rsi
callq 0x4643
incq %r14
jmp 0x31a3
movl -0x2c(%rbp), %ecx
movq %rbx, %rdi
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdx
movq -0x138(%rbp), %r14
movl %r14d, %r8d
callq 0x4791
movl -0x2c(%rbp), %ecx
movl -0x108(%rbp), %r8d
movq %rbx, %rdi
movq -0x60(%rbp), %rsi
movq -0x118(%rbp), %rdx
movl %r14d, %r9d
callq 0x483f
movl -0x3c(%rbp), %r8d
movl -0x30(%rbp), %r9d
cmpl $0x0, -0x6c(%rbp)
je 0x323e
subq $0x8, %rsp
movq -0x60(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x88(%rbp), %rdx
movq -0x80(%rbp), %rcx
pushq %r14
callq 0x4d81
popq %rax
popq %rcx
leaq 0x41b9(%rip), %rsi      # 0x73f2
jmp 0x331f
subq $0x8, %rsp
movq -0x60(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x88(%rbp), %rdx
movq -0x80(%rbp), %rcx
pushq %r14
callq 0x4d81
popq %rax
popq %rcx
movl -0x3c(%rbp), %r8d
movl -0x78(%rbp), %r9d
subq $0x8, %rsp
movq -0x60(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0xe0(%rbp), %rdx
movq -0xc8(%rbp), %rcx
pushq %r14
callq 0x4d81
popq %rax
popq %rcx
movl -0x3c(%rbp), %r8d
movl -0x74(%rbp), %r9d
subq $0x8, %rsp
movq -0x60(%rbp), %rdi
movq -0x98(%rbp), %rsi
movq -0xd8(%rbp), %rdx
movq -0xc0(%rbp), %rcx
pushq %r14
callq 0x4d81
popq %rax
popq %rcx
movl -0x3c(%rbp), %r8d
movl -0x70(%rbp), %r9d
subq $0x8, %rsp
movq -0x60(%rbp), %rdi
movq -0x90(%rbp), %rsi
movq -0xd0(%rbp), %rdx
movq %r15, %rcx
pushq %r14
callq 0x4d81
popq %rax
popq %rcx
movl -0x30(%rbp), %eax
movq -0x48(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
movq -0x90(%rbp), %rcx
movq -0xf0(%rbp), %r8
movq -0xe8(%rbp), %r9
pushq %r14
pushq %rax
callq 0x4e07
popq %rax
popq %rcx
leaq 0x40b2(%rip), %rsi      # 0x73d1
movq 0x7cb2(%rip), %rdi      # 0xafd8
callq 0x21d0
movq %rax, %rdi
callq 0x2120
movl -0x30(%rbp), %ecx
movq -0x48(%rbp), %rdi
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rdx
movl %r14d, %r8d
callq 0x47fa
movq 0x7c81(%rip), %rdi      # 0xafd8
leaq 0x40bc(%rip), %rsi      # 0x741a
callq 0x21d0
movq %rax, %rdi
callq 0x2120
leaq -0x1c8(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x3772
movl -0x12c(%rbp), %r8d
movl -0x30(%rbp), %r9d
subq $0x8, %rsp
leaq -0x1c8(%rbp), %rdx
leaq -0x670(%rbp), %rcx
movq -0x48(%rbp), %rdi
movq -0xf8(%rbp), %rsi
movsd -0x128(%rbp), %xmm0
pushq -0x160(%rbp)
pushq -0x68(%rbp)
pushq %r14
callq 0x4ee4
addq $0x20, %rsp
movl %eax, %r12d
leaq -0x1c8(%rbp), %rdi
callq 0x37c6
testl %r12d, %r12d
jne 0x36a1
leaq -0x268(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x37f2
leaq -0x268(%rbp), %rdi
callq 0x3c30
leaq -0x268(%rbp), %rdi
callq 0x3852
movq -0x120(%rbp), %rdi
callq 0x2240
movq -0x118(%rbp), %rdi
callq 0x2240
xorl %r14d, %r14d
cmpq %r14, -0x38(%rbp)
je 0x349c
movq (%rbx,%r14,8), %rdi
testq %rdi, %rdi
je 0x3434
callq 0x2240
movq -0x60(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3446
callq 0x2240
movq -0x48(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3458
callq 0x2240
movq -0xa0(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x346d
callq 0x2240
movq -0x98(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3482
callq 0x2240
movq -0x90(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3497
callq 0x2240
incq %r14
jmp 0x3420
xorl %r14d, %r14d
movslq -0x3c(%rbp), %rax
cmpq %rax, %r14
jge 0x3552
movq -0x88(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x34c1
callq 0x2240
movq -0x80(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x34d3
callq 0x2240
movq -0xe0(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x34e8
callq 0x2240
movq -0xd8(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x34fd
callq 0x2240
movq -0xd0(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3512
callq 0x2240
movq -0xc8(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3527
callq 0x2240
movq -0xc0(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x353c
callq 0x2240
movq (%r15,%r14,8), %rdi
testq %rdi, %rdi
je 0x354a
callq 0x2240
incq %r14
jmp 0x349f
xorl %r14d, %r14d
cmpq $0x3, %r14
je 0x358a
movq -0xf0(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3570
callq 0x2240
movq -0xe8(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x3585
callq 0x2240
incq %r14
jmp 0x3555
xorl %r14d, %r14d
movslq -0x2c(%rbp), %rax
cmpq %rax, %r14
jge 0x35ad
movq -0x58(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x35a8
callq 0x2240
incq %r14
jmp 0x358d
xorl %r14d, %r14d
movslq -0x30(%rbp), %rax
cmpq %rax, %r14
jge 0x35d3
movq -0xf8(%rbp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x35ce
callq 0x2240
incq %r14
jmp 0x35b0
movq %rbx, %rdi
callq 0x2240
movq -0x60(%rbp), %rdi
callq 0x2240
movq -0x48(%rbp), %rdi
callq 0x2240
movq -0xa0(%rbp), %rdi
callq 0x2240
movq -0x98(%rbp), %rdi
callq 0x2240
movq -0x90(%rbp), %rdi
callq 0x2240
movq -0x88(%rbp), %rdi
callq 0x2240
movq -0x80(%rbp), %rdi
callq 0x2240
movq -0xe0(%rbp), %rdi
callq 0x2240
movq -0xd8(%rbp), %rdi
callq 0x2240
movq -0xd0(%rbp), %rdi
callq 0x2240
movq -0xc8(%rbp), %rdi
callq 0x2240
movq -0xc0(%rbp), %rdi
callq 0x2240
movq %r15, %rdi
callq 0x2240
movq -0x58(%rbp), %rdi
callq 0x2240
movq -0xf8(%rbp), %rdi
callq 0x2240
movq -0xf0(%rbp), %rdi
callq 0x2240
movq -0xe8(%rbp), %rdi
callq 0x2240
movl $0x0, -0x104(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x3852
movl -0x104(%rbp), %ebx
jmp 0x2586
callq 0x2150
movq %rax, %rbx
leaq -0x268(%rbp), %rdi
callq 0x3852
jmp 0x374d
movq %rax, %rbx
leaq -0x1c8(%rbp), %rdi
jmp 0x36e4
movq %rax, %rbx
leaq -0x1e0(%rbp), %rdi
callq 0x37c6
jmp 0x374d
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
movq %rax, %rbx
leaq -0x200(%rbp), %rdi
callq 0x2110
jmp 0x374d
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
jmp 0x374a
movq %rax, %rbx
leaq -0x1b0(%rbp), %rdi
callq 0x3852
leaq -0x220(%rbp), %rdi
callq 0x2110
movq %rbx, %rdi
callq 0x2340
movq %rax, %rbx
jmp 0x3759