// File: /workspace/github_cpp_makefile_star2_O3/sus304[P]ForRocket/src/solver/rocket_stage.cpp
// Function: forrocket::RocketStage::FlightSequence(forrocket::SequenceClock*, forrocket::EnvironmentWind*, std::array<double, 14ul>&)
void forrocket::RocketStage::FlightSequence(SequenceClock* master_clock, EnvironmentWind* wind, DynamicsBase::state& x0) {
    namespace odeint = boost::numeric::odeint;

    // Sterpper Select
    ////////////////////////////////////
    double eps_abs = 1.0e-12;
    double eps_rel = 1.0e-7;
    // 4th Order Runge-Kutta Method
    // odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;

    // 5th Order Runge-Kutta-Dormand-Prince Method : Controled : Dense output : Internal info
    using base_stepper_type = odeint::runge_kutta_dopri5<forrocket::DynamicsBase::state>;
    auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // 8th Order Runge-Kutta-Fehlberg Method : Controled
    // using base_stepper_type = odeint::runge_kutta_fehlberg78<forrocket::DynamicsBase::state>;
    // auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // Dynamics6dofAero dynamics_6dof_aero(&rocket, master_clock, wind);
    // Dynamics6dofProgramRate dynamics_6dof_programrate(&rocket, master_clock, wind);
    DynamicsBase* p_dynamics;
    p_dynamics = new Dynamics6dofAero(&rocket, master_clock, wind);

    double start, end;
    double time_step_on_launcher = 0.001;  // 1000 Hz
    double time_step_decent_parachute = 0.1;  // 10 Hz
    fdr.ReserveCapacity(static_cast<int>((time_end - time_start) / time_step) * 1.3);

    DynamicsBase::state x0_in_stage = x0;  // x0はソルバで次段のために共有するので内部用にコピー

    if (time_ignittion <= time_start) {
        // 計算開始と同時に点火する場合
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
        start = time_start;
    } else {
        // 点火が計算開始より後の場合
        // Flight start から engine ignittion まで
        SwitchDynamics(time_start, &p_dynamics, master_clock, wind);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, time_start, time_ignittion, time_step, std::ref(fdr)); // 点火までの慣性飛行計算
        start = time_ignittion;
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
    }
    // ここまでにIgnitionEngineが実行されている

    if (enable_launcher) {
        // ランチクリア時刻確定のためにコピー品で短時間回す
        Rocket rocket_on_launcher = rocket;
        SequenceClock clock_on_launcher = *master_clock; // copy
        DynamicsBase::state x0_on_launcher = x0;
        FlightDataRecorder fdr_on_launcher(&rocket_on_launcher);
        p_dynamics = new Dynamics3dofOnLauncher(&rocket_on_launcher, &clock_on_launcher);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_on_launcher, start, start+1.0, time_step_on_launcher, std::ref(fdr_on_launcher));
        
        # ifdef DEBUG_NO
        fdr_on_launcher.dump_csv("test_estimate_launcher.csv");
        # endif
        
        for (int i=0; i < fdr_on_launcher.countup_burn_time.size(); ++i) {
            double distance = (fdr_on_launcher.position[i].LLH(2) - fdr_on_launcher.position[0].LLH(2)) / sin(fdr_on_launcher.attitude[i].euler_angle(1));
            if (distance >= length_launcher_rail) {
                end = time_step_on_launcher * i;
                break;
            }
        }

        // ランチャ滑走の本ちゃん
        p_dynamics = new Dynamics3dofOnLauncher(&rocket, master_clock);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        // odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        start = start + end;
        #ifdef DEBUG
        fdr.dump_csv("debug_onlauncher_log.csv");
        #endif
    }
    // ここまでに慣性飛行からの点火もしくはランチクリアまでが実行されている
    
    if (enable_cutoff) {
        // engine cutoff まで 
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_cutoff, time_step, std::ref(fdr));
        start = time_cutoff;
        rocket.CutoffEngine();
    }
    // enable_cutoff=false の場合は質量0で自動cutoffされる（Engineクラス側）

    if (enable_despin) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_despin, time_step, std::ref(fdr));
        start = time_despin;
        rocket.DeSpin();
    }

    if (enable_fairing_jettson) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_jettson_fairing, time_step, std::ref(fdr));
        start = time_jettson_fairing;
        rocket.JettsonFairing(mass_fairing);
    }

    if (enable_sepation) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_separation, time_step, std::ref(fdr));
        start = time_separation;
        rocket.SeparateUpperStage(mass_upper_stage);
        x0 = x0_in_stage;  // 次段のために分離情報をコピー
    }

    if (!enable_parachute_open) {
        // 弾道で落ちるまで
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_end, time_step, std::ref(fdr));
    } else {
        // パラシュート開傘
        if (enable_apogee_parachute_open) {
            // 頂点時刻確定のためにコピー品で回す
            Rocket rocket_apogee_estimate = rocket;
            SequenceClock clock_apogee_estimate = *master_clock; // copy
            DynamicsBase::state x0_apogee_estimate = x0;
            FlightDataRecorder fdr_apogee_estimate(&rocket_apogee_estimate);
            if (enable_program_attitude) {
                p_dynamics = new Dynamics6dofProgramRate(&rocket, &clock_apogee_estimate, wind);
            } else {
                p_dynamics = new Dynamics6dofAero(&rocket, &clock_apogee_estimate, wind);
            }
            odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_apogee_estimate, start, time_end, time_step, std::ref(fdr_apogee_estimate));
            double max_alt = 0.0;
            for (int i=0; i < fdr_apogee_estimate.position.size(); ++i) {
                double alt = fdr_apogee_estimate.position[i].LLH(2);
                if (max_alt < alt) {
                    max_alt = alt;
                } else {
                    end = fdr_apogee_estimate.countup_time[i];
                    break;
                }
            }
        } else {
            end = time_open_parachute;
        }
        // 開傘までの慣性飛行本ちゃん
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, end, time_step, std::ref(fdr));
        start = end;

        // ここまでで頂点もしくは開傘時刻まで実行されている
        odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;
        rocket.OpenParachute();
        Dynamics3dofParachute dynamics_3dof_parachute(&rocket, master_clock, wind);

        if (exist_second_parachute) {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_open_second_parachute, time_step_decent_parachute, std::ref(fdr));
            rocket.OpenParachute();
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, time_open_second_parachute, time_end, time_step_decent_parachute, std::ref(fdr));
        } else {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_end, time_step_decent_parachute, std::ref(fdr));
        }
    }

    // fdr.dump_csv("flight_log_stage"+std::to_string(stage_number)+".csv");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1df8, %rsp           # imm = 0x1DF8
movq %rcx, %r12
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r14
movw $0x100, 0x9f9(%rsp)     # imm = 0x100
movw $0x0, 0xd80(%rsp)
movaps 0xedc0(%rip), %xmm0     # 0x3d280
movups %xmm0, 0xd88(%rsp)
movapd 0xedc0(%rip), %xmm0     # 0x3d290
movupd %xmm0, 0xd98(%rsp)
movq $0x0, 0xda8(%rsp)
movl $0x0, 0xdb0(%rsp)
movb $0x1, 0xf78(%rsp)
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x10(%r14), %rbx
movq %rax, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq %r15, 0x598(%rsp)
movq %r15, %rcx
callq 0x23d84
movq %rbp, 0x5a0(%rsp)
leaq 0xe80(%r14), %rdi
movsd 0x11f8(%r14), %xmm0
subsd 0x1150(%r14), %xmm0
divsd 0x1200(%r14), %xmm0
cvttpd2dq %xmm0, %xmm0
cvtdq2pd %xmm0, %xmm0
mulsd 0xed74(%rip), %xmm0     # 0x3d2d0
cvttsd2si %xmm0, %esi
movq %rdi, 0x590(%rsp)
callq 0x1b824
leaq 0x5c0(%rsp), %rdi
movl $0xe, %ecx
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movsd 0x1150(%r14), %xmm0
ucomisd 0x1158(%r14), %xmm0
movq %r12, %r15
jae 0x2e63c
leaq 0x5a0(%rsp), %rbp
movq %r14, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbp), %rax
movsd 0x1150(%r14), %xmm0
movsd 0x1158(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x5c0(%rsp), %rsi
movq %rax, %rdi
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movsd 0x1158(%r14), %xmm0
movsd %xmm0, 0x5b8(%rsp)
leaq 0x18(%r13), %rsi
leaq 0x6f0(%rsp), %rbp
movq %rbp, %rdi
callq 0x1738e
movsd 0x38(%r13), %xmm0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x20d88
jmp 0x2e673
leaq 0x18(%r13), %rsi
leaq 0x70c(%rsp), %rbp
movq %rbp, %rdi
callq 0x1738e
movsd 0x38(%r13), %xmm0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x20d88
movsd 0x1150(%r14), %xmm0
movsd %xmm0, 0x5b8(%rsp)
cmpb $0x1, 0x1160(%r14)
movq %rbx, 0x5a8(%rsp)
jne 0x2e7f0
leaq 0xf80(%rsp), %rdi
movq %rbx, %rsi
callq 0x2f7c8
movq 0x10(%r13), %rax
leaq 0x648(%rsp), %rdi
movq %rax, -0x8(%rdi)
movupd (%r13), %xmm0
movapd %xmm0, -0x18(%rdi)
leaq 0x18(%r13), %rsi
callq 0x1738e
movupd 0x38(%r13), %xmm0
movupd %xmm0, 0x668(%rsp)
leaq 0x680(%rsp), %rdi
movl $0xe, %ecx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x728(%rsp), %rdi
leaq 0xf80(%rsp), %rsi
callq 0x1b7c4
movl $0x18, %edi
callq 0x5340
movq %rax, %rbp
leaq 0xf80(%rsp), %rsi
leaq 0x630(%rsp), %rdx
movq %rax, %rdi
callq 0x21788
movsd 0xbfff(%rip), %xmm1     # 0x3a720
movsd 0x5b8(%rsp), %xmm0
addsd %xmm0, %xmm1
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x680(%rsp), %rsi
movsd 0xeb87(%rip), %xmm2     # 0x3d2d8
leaq 0x728(%rsp), %rdx
movq %rbp, %rdi
callq 0x2fe5c
movq 0x750(%rsp), %rax
cmpq 0x748(%rsp), %rax
je 0x2e807
movl $0x8, %r12d
movl $0x40, %ebp
xorl %ebx, %ebx
movq 0x8d8(%rsp), %rax
movq 0x950(%rsp), %rcx
movsd (%rax,%rbp), %xmm0
subsd 0x40(%rax), %xmm0
movsd %xmm0, 0x588(%rsp)
movsd (%rcx,%r12), %xmm0
callq 0x50e0
movsd 0x588(%rsp), %xmm1
divsd %xmm0, %xmm1
ucomisd 0x1168(%r14), %xmm1
jae 0x2e809
incq %rbx
movq 0x750(%rsp), %rax
subq 0x748(%rsp), %rax
sarq $0x3, %rax
addq $0x40, %r12
addq $0x48, %rbp
cmpq %rbx, %rax
ja 0x2e784
jmp 0x2e821
movsd 0x5b8(%rsp), %xmm0
movsd %xmm0, 0x588(%rsp)
jmp 0x2e8e1
jmp 0x2e821
xorps %xmm0, %xmm0
cvtsi2sd %ebx, %xmm0
mulsd 0xeac0(%rip), %xmm0     # 0x3d2d8
movsd %xmm0, 0x5b0(%rsp)
movl $0x18, %edi
callq 0x5340
movq 0x5a8(%rsp), %rbx
movq %rax, %rbp
movq %rax, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x21788
movq %rbp, 0x5a0(%rsp)
leaq 0xdb8(%rsp), %rdx
movq (%rbp), %rax
leaq 0x5c0(%rsp), %rsi
movq %rbp, %rdi
movsd 0x5b8(%rsp), %xmm0
callq *(%rax)
leaq 0x9f8(%rsp), %rsi
movb $0x0, 0x580(%rsi)
movsd 0x5b8(%rsp), %xmm0
movapd %xmm0, %xmm1
addsd 0x5b0(%rsp), %xmm1
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x5c0(%rsp), %rsi
movsd 0xea2a(%rip), %xmm2     # 0x3d2d8
movq %rbp, %rdi
movsd %xmm1, 0x588(%rsp)
movq 0x590(%rsp), %rdx
callq 0x2fe5c
leaq 0x728(%rsp), %rdi
callq 0x2e016
leaq 0xf80(%rsp), %rdi
callq 0x2c480
cmpb $0x1, 0x1170(%r14)
jne 0x2e9ac
leaq 0x5a0(%rsp), %rbp
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbp, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbp), %rbp
leaq 0xdb8(%rsp), %rbx
movq (%rbp), %rax
leaq 0x5c0(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%rbx)
movq 0x5a8(%rsp), %rbx
movsd 0x1178(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbp, %rdi
movq %r12, %rsi
movsd 0x588(%rsp), %xmm0
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movsd 0x1178(%r14), %xmm0
movsd %xmm0, 0x588(%rsp)
movq %rbx, %rdi
callq 0x20dfa
cmpb $0x1, 0x11b0(%r14)
jne 0x2ea77
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbx), %rbx
leaq 0xdb8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5c0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11b8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5a8(%rsp), %rbx
movq %rbp, %rsi
movsd 0x588(%rsp), %xmm0
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movsd 0x11b8(%r14), %xmm0
movsd %xmm0, 0x588(%rsp)
movq %rbx, %rdi
callq 0x20e04
cmpb $0x1, 0x11c0(%r14)
jne 0x2eb4b
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbx), %rbx
leaq 0xdb8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5c0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11c8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5a8(%rsp), %rbx
movq %rbp, %rsi
movsd 0x588(%rsp), %xmm0
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movsd 0x11c8(%r14), %xmm0
movsd %xmm0, 0x588(%rsp)
movsd 0x11d0(%r14), %xmm0
movq %rbx, %rdi
callq 0x20e16
cmpb $0x1, 0x1198(%r14)
jne 0x2ec2d
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbx), %rbx
leaq 0xdb8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5c0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11a0(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5a8(%rsp), %rbx
movq %rbp, %rsi
movsd 0x588(%rsp), %xmm0
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movsd 0x11a0(%r14), %xmm0
movsd %xmm0, 0x588(%rsp)
movsd 0x11a8(%r14), %xmm0
movq %rbx, %rdi
callq 0x20e4c
movl $0xe, %ecx
movq %r15, %rdi
movq %rbp, %rsi
rep  movsq (%rsi), %es:(%rdi)
cmpb $0x0, 0x11d8(%r14)
je 0x2ecef
cmpb $0x1, 0x11d9(%r14)
jne 0x2ed8e
leaq 0xf80(%rsp), %rdi
movq %rbx, %rsi
callq 0x2f7c8
movq 0x10(%r13), %rax
leaq 0x648(%rsp), %rdi
movq %rax, -0x8(%rdi)
movupd (%r13), %xmm0
movapd %xmm0, -0x18(%rdi)
leaq 0x18(%r13), %rsi
callq 0x1738e
movupd 0x38(%r13), %xmm0
movupd %xmm0, 0x668(%rsp)
leaq 0x680(%rsp), %rdi
movl $0xe, %ecx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x728(%rsp), %rdi
leaq 0xf80(%rsp), %rsi
callq 0x1b7c4
cmpb $0x1, 0x1180(%r14)
jne 0x2eda5
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x630(%rsp), %rdx
movq %rax, %rdi
movq %rbx, %rsi
movq 0x598(%rsp), %rcx
callq 0x2526c
jmp 0x2edcd
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %rcx
callq 0x2e3c6
movq (%rbx), %rbx
leaq 0xdb8(%rsp), %r15
movq (%rbx), %rax
leaq 0x5c0(%rsp), %r12
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r15)
movsd 0x11f8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %r12, %rsi
movsd 0x588(%rsp), %xmm0
movq 0x590(%rsp), %rdx
callq 0x2fe5c
jmp 0x2f209
movsd 0x11e0(%r14), %xmm0
movsd %xmm0, 0x5b0(%rsp)
jmp 0x2eea0
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x630(%rsp), %rdx
movq %rax, %rdi
movq %rbx, %rsi
movq 0x598(%rsp), %rcx
callq 0x23d84
movq %rbp, 0x5a0(%rsp)
movsd 0x11f8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x680(%rsp), %rsi
leaq 0x728(%rsp), %rdx
movq %rbp, %rdi
movsd 0x588(%rsp), %xmm0
callq 0x2fe5c
movq 0x8d8(%rsp), %rax
movq 0x8e0(%rsp), %rdx
subq %rax, %rdx
je 0x2ee86
sarq $0x3, %rdx
movabsq $-0x71c71c71c71c71c7, %rcx # imm = 0x8E38E38E38E38E39
imulq %rdx, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
addq $0x40, %rax
xorpd %xmm0, %xmm0
xorl %edx, %edx
movapd %xmm0, %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2ee70
incq %rdx
addq $0x48, %rax
cmpq %rdx, %rcx
jne 0x2ee54
jmp 0x2ee86
movq 0x730(%rsp), %rax
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, 0x5b0(%rsp)
leaq 0x728(%rsp), %rdi
callq 0x2e016
leaq 0xf80(%rsp), %rdi
callq 0x2c480
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x588(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x598(%rsp), %r15
movq %r15, %rcx
callq 0x2e3c6
movq (%rbx), %rbx
leaq 0xdb8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5c0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x588(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x1200(%r14), %xmm2
leaq 0x9f8(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %rbp, %rsi
movsd 0x588(%rsp), %xmm0
movsd 0x5b0(%rsp), %xmm1
movq 0x590(%rsp), %rdx
callq 0x2fe5c
movq 0x5a8(%rsp), %rbx
movq %rbx, %rdi
callq 0x20e82
leaq 0x680(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x230f4
cmpb $0x1, 0x11e8(%r14)
jne 0x2f137
xorps %xmm0, %xmm0
leaq 0xf80(%rsp), %r12
movups %xmm0, 0xa8(%r12)
movq 0x18(%rbp), %rax
leaq 0x728(%rsp), %r13
movq %rax, 0x18(%r13)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%r13)
movsd 0x11f0(%r14), %xmm1
xorl %ebx, %ebx
movb %bl, 0x1(%r12)
movq %rbx, 0x78(%r12)
movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000
movq %rax, 0x80(%r12)
movsd 0xb757(%rip), %xmm0     # 0x3a728
movups %xmm0, 0x88(%r12)
movaps 0xe2bf(%rip), %xmm0     # 0x3d2a0
movups %xmm0, 0x98(%r12)
movaps 0xe29f(%rip), %xmm0     # 0x3d290
movups %xmm0, 0xb8(%r12)
movaps 0xe2af(%rip), %xmm0     # 0x3d2b0
movups %xmm0, 0xc8(%r12)
movaps 0xe2af(%rip), %xmm0     # 0x3d2c0
movups %xmm0, 0xd8(%r12)
movb %bl, 0xe8(%r12)
leaq 0x19927(%rip), %r15     # 0x48950
addq $0x10, %r15
movq %r15, (%r13)
leaq 0x5c0(%rsp), %rdx
movsd 0xe29f(%rip), %xmm2     # 0x3d2e0
movq %r12, %rdi
movq %r13, %rsi
movsd 0x5b0(%rsp), %xmm0
movq 0x590(%rsp), %rcx
callq 0x3132d
movq 0x5a8(%rsp), %rdi
callq 0x20e82
xorps %xmm0, %xmm0
movups %xmm0, 0xa8(%r12)
movq 0x18(%rbp), %rax
movq %rax, 0x18(%r13)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%r13)
movsd 0x11f0(%r14), %xmm0
movsd 0x11f8(%r14), %xmm1
movb %bl, 0x1(%r12)
movq %rbx, 0x78(%r12)
movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000
movq %rax, 0x80(%r12)
movsd 0xb66b(%rip), %xmm2     # 0x3a728
movups %xmm2, 0x88(%r12)
movaps 0xe1d3(%rip), %xmm2     # 0x3d2a0
movups %xmm2, 0x98(%r12)
movaps 0xe1b3(%rip), %xmm2     # 0x3d290
movups %xmm2, 0xb8(%r12)
movaps 0xe1c3(%rip), %xmm2     # 0x3d2b0
movups %xmm2, 0xc8(%r12)
movaps 0xe1c3(%rip), %xmm2     # 0x3d2c0
movups %xmm2, 0xd8(%r12)
movb %bl, 0xe8(%r12)
movq %r15, (%r13)
leaq 0xf80(%rsp), %rdi
leaq 0x728(%rsp), %rsi
leaq 0x5c0(%rsp), %rdx
movsd 0xe1ae(%rip), %xmm2     # 0x3d2e0
jmp 0x2f1fc
xorps %xmm0, %xmm0
leaq 0xf80(%rsp), %rdi
movups %xmm0, 0xa8(%rdi)
movq 0x18(%rbp), %rax
leaq 0x728(%rsp), %rsi
movq %rax, 0x18(%rsi)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%rsi)
movsd 0x11f8(%r14), %xmm1
xorl %eax, %eax
movb %al, 0x1(%rdi)
movq $0x0, 0x78(%rdi)
movabsq $0x3fe0000000000000, %rcx # imm = 0x3FE0000000000000
movq %rcx, 0x80(%rdi)
movsd 0xb598(%rip), %xmm0     # 0x3a728
movups %xmm0, 0x88(%rdi)
movaps 0xe102(%rip), %xmm0     # 0x3d2a0
movups %xmm0, 0x98(%rdi)
movaps 0xe0e4(%rip), %xmm0     # 0x3d290
movups %xmm0, 0xb8(%rdi)
movaps 0xe0f6(%rip), %xmm0     # 0x3d2b0
movups %xmm0, 0xc8(%rdi)
movaps 0xe0f8(%rip), %xmm0     # 0x3d2c0
movups %xmm0, 0xd8(%rdi)
movb %al, 0xe8(%rdi)
leaq 0x19774(%rip), %rax     # 0x48950
addq $0x10, %rax
movq %rax, (%rsi)
leaq 0x5c0(%rsp), %rdx
movsd 0xe0ed(%rip), %xmm2     # 0x3d2e0
movsd 0x5b0(%rsp), %xmm0
movq 0x590(%rsp), %rcx
callq 0x3132d
addq $0x1df8, %rsp           # imm = 0x1DF8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2f21d
movq %rax, %rbx
movl $0x20, %esi
jmp 0x2f237
jmp 0x2f243
jmp 0x2f243
jmp 0x2f25a
jmp 0x2f22f
movq %rax, %rbx
movl $0x18, %esi
movq %rbp, %rdi
callq 0x5350
jmp 0x2f25d
jmp 0x2f243
movq %rax, %rbx
jmp 0x2f26a
movq %rax, %rbx
movl $0x20, %esi
movq %rbp, %rdi
callq 0x5350
jmp 0x2f277
movq %rax, %rbx
leaq 0x728(%rsp), %rdi
callq 0x2e016
leaq 0xf80(%rsp), %rdi
callq 0x2c480
movq %rbx, %rdi
callq 0x55e0
nop