#!/usr/bin/perl

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'TkPerlDir'};
#print "\nBaseDir: $BaseDir\n";
@INC = ("$BaseDir/lib", "$BaseDir/VNL", "d:/Programs/Perl/lib", @INC);
}

use strict;
#use warnings;
use File::Path;
use File::Basename;
use File::Find;

use Math::Matrix;
use Math::MatrixReal;

use Deps;
use Utils;
use JFile;

use MyApplication;
use Sci qw($a0);
use Sci::Algorism;
use Sci::GeneralFileFormat;

use Crystal::CIF;
use Crystal::Crystal;
use Crystal::SpaceGroup;
use Crystal::AtomType;
use Crystal::PHASE;
use Crystal::VESTA;
use Crystal::XCrySDen;

#===============================================
# デバッグ関係変数
#===============================================
#$PrintLevelが大きいほど、情報が詳しくなる
my $PrintLevel = 0;

#===============================================
# 文字コード関係変数
#===============================================
# sjis, euc, jis, noconv
my $PrintCharCode      = Deps::PrintCharCode();
my $OSCharCode         = Deps::OSCharCode();
my $FileSystemCharCode = Deps::FileSystemCharCode();

my $DirSep        = Deps::DirSep();
my $RegDirSep     = Deps::RegDirSep();
my $ProgramOldDir = ProgVars::ProgramOldDir();
my $PHASEDir      = ProgVars::PHASEDir();
my $PHASEPerlDir  = ProgVars::PHASEPerlDir();
my $PHASEPotDir   = ProgVars::PHASEPotDir();

#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyApplication;
exit if($App->Initialize() < 0);

#$App->SetLF("<br>\n");
#$App->SetPrintCharCode("sjis");
#$App->SetDebug($Debug);
$App->SetDeleteHTMLFlag(1);

#===============================================
# スクリプト大域変数
#===============================================
my $InitialDirectory = Deps::GetWorkingDirectory();
my %ParamHash;

#==========================================
# コマンドラインオプション読み込み
#==========================================
$App->AddArgument("--Action",
		"--Action=[ModifyFiles|MakeINCAR|ModifyPOSCAR|CheckRWIGS|"
		."MakeCIF|ConvCONTCAR|MakeVESTAFile|MakeXSFFile|MakeRelaxXSFFile|MakePhononXSFFile|"
		."MakeMergeEIGENVALSH|AddEIGENVAL|RepairEIGENVAL|"
		."MakeDOSCSV|ChangeDensityFileNames]", '');
$App->AddArgument("--UseConventionalCell", "--UseConventionalCell=[Yes|No] (Def:No)", "No");
$App->AddArgument("--Function",      "--Function=[scf|nscf|band|edensity|relax|vc-relax|md] (Def:scf)", "scf");
$App->AddArgument("--Functional",    "--Functional=[PWA_PBE|PAW_GGA|GGA|US_LDA] (Def:PAW_PBE)", "PAW_PBE");
$App->AddArgument("--UseDPP",        "--UseDPP=[0|1] (Def:1)", 1);
$App->AddArgument("--SpinPolarized", "--SpinPolarized=[No|Yes] (Def:No)", "No");
$App->AddArgument("--InverseOrder",  "--InverseOrder=[No|Yes] (Def:No)",  "No");
$App->AddArgument("--EnergyRange",   "--EnergyRange=val (Def: 1.0)", 1.0);
$App->AddArgument("--AllSeparated",  "--AllSeparated=[0|1] (Def: 1)", 1);
$App->AddArgument("--MinEnergy",       "--MinEnergy=-val (Def: -0.5)", -0.5);
$App->AddArgument("--MaxEnergy",       "--MaxEnergy=val (Def: 0.0)", 0.0);
$App->AddArgument("--nMesh",           "--nMesh=val (Def: 1000)", 1000);
$App->AddArgument("--RemoveExtention", "--RemoveExtention=[0|1] (Def: 0)", 0);
$App->AddArgument("--GammaOnly",       "--GammaOnly=[0|1] (Def: 0)", 0);
$App->AddArgument("--nKPoint",         "--nKPoint=val (Def: 9)", 9);
$App->AddArgument("--aKProduct",       "--aKProduct=val (Def: 2.0)", 2.0);
$App->AddArgument("--KPoints",         "--KPoints=[File|GXYZRM] (Def: File)", 'File');
$App->AddArgument("--Precision",       "--Precision=[High|Normal|Medium|Low] (Def: Normal)", "Normal");
$App->AddArgument("--PStress",         "--PStress=val (Def: 0)", '');
$App->AddArgument("--KeepSymmetry",    "--KeepSymmetry=[0-4] (Def: 0)", "0");
$App->AddArgument("--A",               "--A=val (Def: )", '');
$App->AddArgument("--a",               "--a=val (Def: )", '');
$App->AddArgument("--b",               "--b=val (Def: )", '');
$App->AddArgument("--c",               "--c=val (Def: )", '');
$App->AddArgument("--alpha",           "--alpha=val (Def: )", '');
$App->AddArgument("--beta",            "--beta =val (Def: )", '');
$App->AddArgument("--gamma",           "--gamma=val (Def: )", '');
$App->AddArgument("--Param:.*",        "--Param:Param=val", "");
$App->AddArgument("--DebugMode",       "--DebugMode: Set DebugMode", '');
exit 1 if($App->ReadArgs(1, "sjis", 0) != 1);
my $Args = $App->Args();
#my $form = new CGI;
#$Args->SetCGIForm($form);
#$Args->parseInput($WebCharCode);

my %ArgHash = $Args->GetArgHash();
foreach my $key (keys %ArgHash) {
#print "key: $key: $ArgHash{$key}\n";
	if($key =~ /^Param:(.*?)$/i) {
		$ParamHash{$1} = $ArgHash{$key};
#print "$1:  $ArgHash{$key}\n";
	}
}
$App->{pParamHash} = \%ParamHash;

#==========================================
# メイン関数スタート
#==========================================

my $PHASE = new PHASE;

#Utils::InitHTML("Research", $WebCharSet, "_self");

my $Debug = $Args->GetGetArg("DebugMode");
$App->SetDebug($Debug);
my $Action = $Args->GetGetArg("Action");

my $ret = 0;
if($Action =~ /MakePHASEFiles/i) {
	&MakePHASEFiles();
}
else {
	$App->print("Error: Invalid Action: [$Action]\n");
}

#Utils::EndHTML();

exit $ret;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================
sub MakePHASEFiles
{
	$App->print("\nMake PHASE Files from CIF File:\n");

	my $CIFFile = $Args->GetGetArg(0);
	if($CIFFile eq 'auto') {
		my @files = glob("*.cif");
		@files = glob("*.CIF") if(@files == 0);
		for(my $i = 0 ; $i < @files ; $i++) {
			next if($files[$i] =~ /-initial\.cif$/i or $files[$i] =~ /-final\.cif$/i);
			$CIFFile = $files[$i];
			last;
		}
		if($CIFFile eq 'auto') {
			for(my $i = 0 ; $i < @files ; $i++) {
				if($files[$i] =~ /-final\.cif$/i) {
					$CIFFile = $files[$i];
					last;
				}
			}
		}
		if($CIFFile eq 'auto') {
			$CIFFile = $files[0];
		}
	}

	my $WriteDir = $Args->GetGetArg(1);
	unless($WriteDir) {
		$App->print("File / Directory names should be specified.\n");
		$App->print("   Usage: PHASE.pl --Action=MakePHASEFiles CIFFile Work_Dir\n");
		return 0;
	}

	my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($CIFFile);

	my $Function   = ($Args->GetGetArg('Function'))?   $Args->GetGetArg('Function')   : 'scf';
	my $Functional = ($Args->GetGetArg('Functional'))? $Args->GetGetArg('Functional') : 'ggapbe';
	my $PPType     = ($Args->GetGetArg('PPType'))?     $Args->GetGetArg('PPType')     : 'auto';
	my $SampleName = $filebody;

	$App->print("  CIF file  : $CIFFile\n");
	$App->print("  Work dir  : $WriteDir\n");
	$App->print("  Function  : $Function\n");
	$App->print("  Functional: $Functional\n");
	$App->print("  PPType    : $PPType\n");
	if(!-d $WriteDir) {
		$App->print("  Error in PHASE.pl: [$WriteDir] is not a directory\n");
		exit;
	}

	my %FileNameList = $PHASE->GetDefaultFileNames($Function, $filebody);

	my $CIF = new CIF();
	unless($CIF->Read($CIFFile)) {
		$App->print("  Error: Can not read [$CIFFile].\n\n");
		return -1;
	}
	my $Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();
	$Crystal->SetOutputMode('expanded');

	my $FileNamesPath = 'file_names.data';
	if(!$PHASE->MakeFileNamesData($WriteDir, $FileNamesPath, \%FileNameList, $Functional, $PPType, $Crystal, 1)) {
		$App->print("  Error in PHASE.pl: Can not write to [$FileNamesPath].\n");
		exit;
	}

	if(!&MakeInputFile($WriteDir, $FileNameList{F_INP}, \%FileNameList, $SampleName, $Function, $Functional, $Crystal)) {
		$App->print("  Error in PHASE.pl: Can not write to [$FileNameList{F_INP}].\n");
		exit;
	}

	my $ControlInpPath = "Control.inp";
	if(!$PHASE->MakeControlInp($ControlInpPath, $Crystal)) {
		$App->print("  Error in PHASE.pl: Can not write to [$ControlInpPath].\n");
		exit;
	}
	my $KPointPath = 'kpoint.txt';
	if(!$PHASE->MakeKPointFile($KPointPath, $Crystal)) {
		$App->print("  Error in PHASE.pl: Can not write to [$ControlInpPath].\n");
		exit;
	}

	$App->print("\nMake PHASE Files from CIF File: finished\n");
}

sub MakeInputFile
{
	my ($WriteDir, $path, $pFileNameList, $SampleName, $Function, $Functional, $Crystal, $aKProduct) = @_;
	$aKProduct = $Args->GetGetArg('aKProduct') if(!defined $aKProduct and $Args->GetGetArg('aKProduct'));
	$path = Utils::MakePath($WriteDir, $path, '/', 0) if(defined $WriteDir);

	$App->print("\nMake PHASE Input File from CIF File [$path]\n");

	my ($nx, $ny, $nz) = (4, 4, 4);
	if(defined $aKProduct) {
		($nx, $ny, $nz) = $Crystal->AnalyzeaKProduct($aKProduct);
	}

	my $UseConventionalCell = $Args->GetGetArg("UseConventionalCell");
	if($UseConventionalCell eq '' or $UseConventionalCell eq 'No' or $UseConventionalCell eq '0') {
		$UseConventionalCell = 'No';
	}
	else {
		$UseConventionalCell = 'Yes';
	}
	my $LatticeSystem = ($Args->GetGetArg("LatticeSystem"))? $Args->GetGetArg("LatticeSystem") : 'auto';

	my $SpinPolarized = $Args->GetGetArg("SpinPolarized");
	if($SpinPolarized and $SpinPolarized ne 'No') {
		$SpinPolarized = 'Yes';
	}
	else {
		$SpinPolarized = 'No';
	}

	$Crystal->ExpandCoordinates();
	$Crystal->SetOutputMode('expanded');

	my $SPG        = $Crystal->GetCSpaceGroup();
	my $SPGName    = $SPG->SPGName();
	my ($CellType) = ($SPGName =~ /^\s*(.)/);

	if($LatticeSystem eq 'auto') {
		$LatticeSystem = $PHASE->GetPHASELatticeSystemName($Crystal);
	}
	$App->print("  UseConventionalCell: $UseConventionalCell\n");
	$App->print("  LatticeSystem      : $LatticeSystem\n");
	$App->print("  SpinPolarized      : $SpinPolarized\n");

#Primitive Cellをつくる
#print "UCC: $UseConventionalCell\n";
	my ($ax,$ay,$az,$bx,$by,$bz,$cx,$cy,$cz);
	if($UseConventionalCell ne 'Yes' and $SPGName =~ /^\s*[FIABC]/i) {
		my $PrimCrystal = $Crystal->GetPrimitiveCell(1);
		my $PrimCIFFile = Deps::MakePath($WriteDir, "${SampleName}-Primitive.cif");
		print "Convert to Primitive Cell.\n";
		print "  CIF File: $PrimCIFFile\n";
		print "  SpaceGroup: $SPGName\n";
		my $PrimCIF = new CIF;
		$PrimCIF->CreateCIFFileFromCCrystal($PrimCrystal, $PrimCIFFile, 0, "unix");

		($ax,$ay,$az,$bx,$by,$bz,$cx,$cy,$cz) = $Crystal->PrimitiveLatticeVectors(1);
		$Crystal = $PrimCrystal;
		$CellType = "$CellType-Primitive";
	}
	else {
		print "Use Convensinal cell\n";
		($ax,$ay,$az,$bx,$by,$bz,$cx,$cy,$cz) = $Crystal->LatticeVectorsByOutputMode(1);
	}

	my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(1);
	my @AtomTypeList                  = $Crystal->GetCAtomTypeList();
	my $nAtomType                     = @AtomTypeList;
	my @ExpandedAtomSiteList          = $Crystal->GetCExpandedAtomSiteListByOutputMode();
	my $nTotalExpandedAtomSite        = @ExpandedAtomSiteList;
	my ($IsMatched, @ReducedAtomSiteList) = $Crystal->GetCReducedAtomSiteListByTranslation();
	if($IsMatched) {
		@ExpandedAtomSiteList   = @ReducedAtomSiteList;
		$nTotalExpandedAtomSite = @ExpandedAtomSiteList;
	}
	else {
print "Error: Bravais Lattice ($LatticeSystem) does not match with the ion coordinates.\n";
		exit;
	}
	my $HasInversion;
	($HasInversion, @ReducedAtomSiteList) = $Crystal->GetCReducedAtomSiteListByInversion(\@ExpandedAtomSiteList);

	my (@nVEL, @Z);
	my %iAtom;
	for(my $i = 0 ; $i < @AtomTypeList ; $i++) {
		my $atom      = $AtomTypeList[$i];
		my $atomname  = $atom->AtomNameOnly();
		$iAtom{$atomname} = $i;

		my $i1 = $i+1;
		my $key = "F_POT($i1)";
		my $PotPath = ($WriteDir ne '')? 
				Utils::MakePath($WriteDir, $pFileNameList->{$key}, '/', 0) : $pFileNameList->{$key};
		my $pHash = $PHASE->ReadPPDataToHash($PotPath);
		$nVEL[$i] = $pHash->{nVEL};
		$Z[$i]    = $pHash->{Z};
#print "$i: $nVEL[$i]\n";
	}
	my $nTotalVEL = 0;
	for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $atomname  = $atom->AtomNameOnly();
		my $iAtom     = $iAtom{$atomname};
		$nTotalVEL += $nVEL[$iAtom];
print "iSite=$i: $atomname ($iAtom): $nVEL[$iAtom]: tot=$nTotalVEL\n";
	}
	my $nBAND = int($nTotalVEL * 0.6 + 0.99);
	$nBAND = int($nTotalVEL * 0.5 + 4.1) if($nBAND - $nTotalVEL/2 < 4);

	print "  Making PHASE input file [$path]...\n";
	print "    Cell type   : $CellType\n";
	print "    n(Valence e): $nTotalVEL\n";
	print "    nBAND       : $nBAND\n";

	if(!open(OUT, ">$path")) {
		$App->print("  Error: Can not write to [$path].\n");
		return undef;
	}

	print OUT<<EOT;
Control{
!        condition = fixed_charge
        cpumax = 3600 sec  ! maximum cpu time
}

accuracy{
        cutoff_wf =   9.00  rydberg
        cutoff_cd =  36.00  rydberg
        num_bands = $nBAND
        ksampling{
!           method = file
           method = mesh ! {mesh|file|directin|gamma}
EOT
	print OUT "           mesh{  nx = $nx, ny =  $ny, nz =  $nz   }\n";
	print OUT "        }\n";
	print OUT "        xctype = $Functional\n";
	print OUT<<EOT;
        scf_convergence{
!                delta_total_energy = 1.e-12  hartree
                delta_total_energy = 1.e-6  hartree
                succession         = 3   !default value = 3
        }
        force_convergence{
                max_force = 0.1e-3
        }
        smearing{
!                method = gamma
!                method = parabolic ! {parabolic|tetrahedral}
!                width  = 0.001 hartree
                method = tetrahedral
        }
        initial_wavefunctions = matrix_diagon
                !{random_numbers|matrix_diagion}
                matrix_diagon{
                       cutoff_wf = 3.00  rydberg
                }
        initial_charge_density = Gauss
        ek_convergence{
                num_max_iteration = 200
                sw_eval_eig_diff  = on
                delta_eigenvalue  = 1.e-5 hartree
                succession        = 2
        }
EOT
	print OUT "}\n";
	print OUT "\n";
	print OUT "structure{\n";

	if($UseConventionalCell == 1 or $UseConventionalCell eq 'Yes') {
		print OUT "        unit_cell_type = Bravais\n";
    }
    else {
		print OUT "        unit_cell_type = primitive\n";
    }

my $SpecifyByVector = (($UseConventionalCell == 1 or $UseConventionalCell eq 'Yes') and $LatticeSystem ne '')? 1 : 0;
#print "s: $SpecifyByVector [$UseConventionalCell][$LatticeSystem]\n";
	print OUT "        unit_cell{\n";
	print OUT "                #units bohr\n";
	if($SpecifyByVector) {
		printf OUT "                a = %8.4f, b = %8.4f, c = %8.4f\n", $a, $b, $c;
		printf OUT "                alpha = %8.3f, beta = %8.3f, gamma = %8.3f\n", $alpha, $beta, $gamma;
		printf OUT "!               a_vector =  %10.6f   %10.6f   %10.6f\n", $ax, $ay, $az;
		printf OUT "!               b_vector =  %10.6f   %10.6f   %10.6f\n", $bx, $by, $bz;
		printf OUT "!               c_vector =  %10.6f   %10.6f   %10.6f\n", $cx, $cy, $cz;
	}
	else {
		printf OUT "!               a = %8.4f, b = %8.4f, c = %8.4f\n", $a, $b, $c;
		printf OUT "!               alpha = %8.3f, beta = %8.3f, gamma = %8.3f\n", $alpha, $beta, $gamma;
		printf OUT "                a_vector =  %10.6f   %10.6f   %10.6f\n", $ax, $ay, $az;
		printf OUT "                b_vector =  %10.6f   %10.6f   %10.6f\n", $bx, $by, $bz;
		printf OUT "                c_vector =  %10.6f   %10.6f   %10.6f\n", $cx, $cy, $cz;
	}
	print OUT "        }\n";

if($SpecifyByVector) {
if(0) {
	if($UseConventionalCell == 1 or $UseConventionalCell eq 'Yes') {
		print OUT "        symmetry{\n";
		print OUT "                crystal_structure = $LatticeSystem\n";
		print OUT "                sw_inversion = $HasInversion\n";
		print OUT "        }\n";
	}
	else {
		print OUT "        symmetry{\n";
		print OUT "                crystal_structure = primitive\n";
		print OUT "                sw_inversion = $HasInversion\n";
		print OUT "        }\n";
	}
}
	if(($UseConventionalCell == 1 or $UseConventionalCell eq 'Yes') and $LatticeSystem ne '') {
		print OUT "    symmetry{\n";
		print OUT "         method = automatic\n";
		print OUT "         tspace{\n";
		print OUT "              lattice_system = $LatticeSystem\n";
		print OUT "         }\n";
		print OUT "         sw_inversion = $HasInversion\n";
		print OUT "    }\n";
	}
	else {
		print OUT "        symmetry{\n";
		print OUT "                crystal_structure = $LatticeSystem\n";
		print OUT "                sw_inversion = $HasInversion\n";
		print OUT "        }\n";
	}
}

	print OUT "\n";
	if($SpinPolarized eq 'Yes' or $SpinPolarized eq '1') {
		print OUT "        magnetic_state = ferro\n";
	}
	else {
		print OUT "        magnetic_state = para\n";
	}
	print OUT<<EOT;

        atom_list{
                coordinate_system = internal ! {cartesian|internal}
                atoms{
                #default weight = 1, mobile = no, thermo_group = 1
                #tag  rx       ry         rz     element mobile weight thermo_group
EOT
#	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
#	my $nTotalExpandedAtomSite = @ExpandedAtomSiteList;
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $atomname  = $atom->AtomNameOnly();
		my $charge    = $atom->Charge();
		my ($x,$y,$z) = $atom->Position(1);
		my $occupancy = $atom->Occupancy();

		printf OUT "          %10.6f  %10.6f  %10.6f   %2s   %s\n", $x, $y, $z, $atomname, '';
	}

	print OUT<<EOT;
	    }
    }
    element_list{
                 #units atomic_mass
                 #tag element  atomicnumber mass
EOT

	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atom         = $AtomTypeList[$i];
		my $name         = $atom->AtomNameOnly();
#		my $AtomicNumber = $AtomTypeList[$i]->AtomicNumber();
		my $mass         = $AtomTypeList[$i]->AtomicMass();
		printf OUT "                          %2s       %3d       %f\n", $name, $Z[$i], $mass;
	}
	print OUT "    }\n";
	print OUT "}\n";

	print OUT<<EOT;

wavefunction_solver{
        solvers{
            #tag    sol    till_n  dts  dte   itr   var  prec cmix submat
                    lm+MSD    5    0.2   *     *     *    on   1   on
                    RMM2P    -1    1.0   *     *     *    on   1   on
        }

        line_minimization{
             dt_lower_critical = 0.5
             dt_upper_critical = 5.0
        }

        rmm{
             imGSrmm  = 1
             rr_Critical_Value    = 1.e-15
             edelta_change_to_rmm = 1.0e-5
        }
}

charge_mixing{
        mixing_methods{
        #tag no   method   rmxs   rmxe   itr  var    prec istr  nbmix  update
              1  broyden2  0.90   0.90   10  linear  on    10    5    RENEW
              2  linear    0.90   0.90   10  linear  on
!             1   simple   0.90   0.95   40  linear  on
!             1  broyden2  0.30   0.30   10     *     on    10    5    RENEW
        }

        charge_preconditioning{
                amix =  0.90
                bmix = -1.00
        }
}

Phonon{
        sw_phonon            = off
        sw_calc_force        = off
        displacement         = 0.1
        sw_vibrational_modes = off
}

Postprocessing{
        dos{
                method             = tetrahedoral
                sw_dos             = off
                deltaE             = 1.e-4 hartree
                deviation_Gaussian = 1.e-5
                nwd_window_width   = 10
        }
        charge{
                sw_charge_rspace = on
                filetype         = cube  !{cube|density_only}
                title            = "This is a title line for the bulk Si"
        }
        wannier{
                sw_wannier    = off
                eps_grad      = 1.d-3
                dt            = 1.d-4
                max_iteration = 1000
                filetype      = cube
        }
}

!structure_evolution{
!!        method = temperature_control
!        method = velocity_verlet 
!        dt = 100 
!        gdiis{
!            gdiis_box_size    = 5 
!            gdiis_update      = RENEW 
!            c_forc2gdiis      = 0.0050 
!            c_iteration2GDIIS = 3 
!        }
!        temperature_control{
!            num_thermostat       = 1 
!            set_initial_velocity = on 
!            thermostat{
!                #tag temp qmass
!                      300 4000
!                }
!        }
!}

printoutlevel{
        base        = 0
        timing      = 0
        solver      = 1
        evdff       = 1
        rmm         = 0
        snl         = 0
        gdiis       = 1
        eigenvalue  = 1
        spg         = 1
        kp          = 1
        pulay       = 0
        matdiagon   = 0
        vlhxcq      = 0
        totalcharge = 1
        submat      = 0
        strcfctr    = 0
}
EOT

	close(OUT);

	$App->print("\nMake PHASE Input File from CIF File [$path]: finished\n");

	return 1;
}
