// API
        public static Beatmap Phigros_to_Stager(PhigrosBeatmapData pMap)
        {
            if (pMap == null || pMap.judgeLineList == null || pMap.judgeLineList.Length == 0)
            {
                return(null);
            }
            var sMap = new Beatmap()
            {
                Tag         = "Phigros",
                Level       = 1,
                BPM         = (int)pMap.judgeLineList[0].bpm,
                Ratio       = 880f / 520f,
                CreatedTime = System.DateTime.Now.Ticks,
                Shift       = 0f,
                Stages      = { },
                Tracks      = { },
                Notes       = { },
                Timings     = { },
            };
            float spb = 60f / sMap.bpm;

            for (int index = 0; index < pMap.judgeLineList.Length; index++)
            {
                var jLine = pMap.judgeLineList[index];
                // Stages
                float time     = -1f;
                float duration = -1f;
                foreach (var d in jLine.judgeLineDisappearEvents)
                {
                    if (Mathf.Max(d.startTime, 0) >= d.endTime)
                    {
                        continue;
                    }
                    if (d.start == 1)
                    {
                        // Time
                        if (time < -0.5f)
                        {
                            time = GetRealTime(d.startTime, spb);
                        }
                        // Duration
                        duration = Mathf.Max(GetRealTime(d.endTime, spb) - time, duration);
                    }
                }
                sMap.Stages.Add(new Beatmap.Stage()
                {
                    Time      = time,
                    Duration  = duration > 0f ? duration : float.MaxValue,
                    Height    = 520f / 880f,
                    ItemType  = 0,
                    Rotation  = 0f,
                    Speed     = 1f,
                    Width     = 1f,
                    X         = 0f,
                    Y         = 0f,
                    Color     = 0,
                    Positions = GetStagePositions(jLine.judgeLineMoveEvents, -time, spb),
                    Rotations = GetStageRotations(jLine.judgeLineRotateEvents, -time, spb),
                    Colors    = GetStageColors(jLine.judgeLineDisappearEvents, -time, spb),
                    Widths    = { },
                    Heights   = { },
                });
                // Tracks
                sMap.Tracks.Add(new Beatmap.Track()
                {
                    StageIndex = index,
                    Angle      = 0f,
                    X          = 0.5f,
                    Time       = time,
                    Duration   = duration > 0f ? duration : float.MaxValue,
                    Color      = 0,
                    HasTray    = false,
                    ItemType   = 0,
                    Width      = 1f,
                    Speed      = 1f,
                    Widths     = { },
                    Xs         = { },
                    Angles     = { },
                    Colors     = { },
                });
                sMap.Tracks.Add(new Beatmap.Track()
                {
                    StageIndex = index,
                    Angle      = 180f,
                    X          = 0.5f,
                    Time       = time,
                    Duration   = duration > 0f ? duration : float.MaxValue,
                    Color      = 0,
                    HasTray    = false,
                    ItemType   = 0,
                    Width      = 1f,
                    Speed      = 1f,
                    Widths     = { },
                    Xs         = { },
                    Angles     = { },
                    Colors     = { },
                });
                // Notes
                foreach (var note in jLine.notesAbove)
                {
                    sMap.Notes.Add(new Beatmap.Note()
                    {
                        TrackIndex      = index * 2,
                        Time            = GetRealTime(note.time, spb),
                        X               = Util.Remap(-10f, 10f, 0f, 1f, note.positionX),
                        Duration        = note.type == (int)NoteType.Hold ? GetRealTime(note.holdTime, spb) : 0f,
                        Speed           = note.speed,
                        ClickSoundIndex = 0,
                        ItemType        = note.type - 1,
                        LinkedNoteIndex = -1,
                        Width           = 1f / 7f,
                        Z               = 0f,
                        SoundFxIndex    = 0,
                        SoundFxParamA   = 0,
                        SoundFxParamB   = 0,
                    });
                }
                foreach (var note in jLine.notesBelow)
                {
                    sMap.Notes.Add(new Beatmap.Note()
                    {
                        TrackIndex      = index * 2 + 1,
                        Time            = GetRealTime(note.time, spb),
                        X               = Util.Remap(-10f, 10f, 0f, 1f, note.positionX),
                        Duration        = note.type == (int)NoteType.Hold ? GetRealTime(note.holdTime, spb) : 0f,
                        Speed           = note.speed,
                        ClickSoundIndex = 0,
                        ItemType        = note.type - 1,
                        LinkedNoteIndex = -1,
                        Width           = 1f / 7f,
                        Z               = 0f,
                        SoundFxIndex    = 0,
                        SoundFxParamA   = 0,
                        SoundFxParamB   = 0,
                    });
                }
                // Timings
                foreach (var sEvent in jLine.speedEvents)
                {
                    sMap.Timings.Add(new Beatmap.Timing(Mathf.Max(sEvent.startTime / 100f, 0f), sEvent.value));
                }
            }
            return(sMap);
        }
        public static PhigrosBeatmapData Stager_to_Phigros(Beatmap sMap)
        {
            if (sMap == null)
            {
                return(null);
            }
            sMap.SortNotesByTime();

            var pMap = new PhigrosBeatmapData()
            {
                formatVersion = 1,
                offset        = 0f,
                numOfNotes    = sMap.Notes.Count,
                judgeLineList = new JudgelineData[sMap.Stages.Count],
            };
            float spb = 60f / sMap.BPM;

            for (int stageIndex = 0; stageIndex < sMap.Stages.Count; stageIndex++)
            {
                var   noteAbove   = new List <Note>();
                var   noteBelow   = new List <Note>();
                float maxNoteTime = 0f;
                foreach (var note in sMap.Notes)
                {
                    if (note.TrackIndex == stageIndex * 2)
                    {
                        // Above
                        noteAbove.Add(new Note()
                        {
                            type          = note.ItemType + 1,
                            time          = (int)(note.Time * 100),
                            holdTime      = (note.ItemType + 1) == (int)NoteType.Hold ? (int)(note.Duration * 100) : 0,
                            positionX     = Util.Remap(0f, 1f, -10f, 10f, note.X),
                            floorPosition = 25f / 8f * note.Time * spb,
                            speed         = 1f,
                        });
                    }
                    else if (note.TrackIndex == stageIndex * 2 + 1)
                    {
                        // Below
                        noteAbove.Add(new Note()
                        {
                            type          = note.ItemType + 1,
                            time          = (int)(note.Time * 100),
                            holdTime      = (note.ItemType + 1) == (int)NoteType.Hold ? (int)(note.Duration * 100) : 0,
                            positionX     = Util.Remap(0f, 1f, -10f, 10f, note.X),
                            floorPosition = 25f / 8f * note.Time * spb,
                            speed         = 1f,
                        });
                    }
                    maxNoteTime = Mathf.Max(maxNoteTime, note.Time + note.Duration);
                }
                var stage = sMap.Stages[stageIndex];
                pMap.judgeLineList[stageIndex] = new JudgelineData()
                {
                    bpm                      = sMap.BPM,
                    numOfNotes               = noteAbove.Count + noteBelow.Count,
                    numOfNotesAbove          = noteAbove.Count,
                    numOfNotesBelow          = noteBelow.Count,
                    notesAbove               = noteAbove.ToArray(),
                    notesBelow               = noteBelow.ToArray(),
                    judgeLineDisappearEvents = GetDisappears(stage.Colors, maxNoteTime, stage.Time),
                    judgeLineMoveEvents      = GetMoves(stage.Positions, maxNoteTime, stage.Time),
                    judgeLineRotateEvents    = GetRotations(stage.Rotations, maxNoteTime, stage.Time),
                    speedEvents              = new SpeedEvent[1] {
                        new SpeedEvent()
                        {
                            startTime = -1,
                            endTime   = (int)(maxNoteTime * 100),
                            value     = 1f,
                        }
                    },
                };
            }
            return(pMap);
        }