void Awake()
        {
            editPresenter = EditNotesPresenter.Instance;

            // Select by dragging
            this.UpdateAsObservable()
                .Where(_ => KeyInput.CtrlKey())
                .Where(_ => Input.GetMouseButtonDown(0))
                .Select(_ => Input.mousePosition)
                .SelectMany(startPos => this.UpdateAsObservable()
                    .TakeWhile(_ => !Input.GetMouseButtonUp(0))
                    .Where(_ => NoteCanvas.IsMouseOverNotesRegion.Value)
                    .Select(_ => Input.mousePosition)
                    .Select(currentPos => new Rect(startPos, currentPos - startPos)))
                .Do(rect => GLLineDrawer.Draw(ToLines(rect, selectionRectColor)))
                .Do(_ => { if (!Audio.IsPlaying.Value) Deselect(); })
                .SelectMany(rect => GetNotesWithin(rect))
                .Do(kv => selectedNoteObjects[kv.Key] = kv.Value)
                .Subscribe(kv => kv.Value.isSelected.Value = true);

            // All select by Ctrl-A
            this.UpdateAsObservable()
                .Where(_ => KeyInput.CtrlPlus(KeyCode.A))
                .SelectMany(_ => EditData.Notes.Values.ToList())
                .Do(noteObj => noteObj.isSelected.Value = true)
                .Subscribe(noteObj => selectedNoteObjects[noteObj.note.position] = noteObj);

            // Copy notes by Ctrl-C
            this.UpdateAsObservable()
                .Where(_ => KeyInput.CtrlPlus(KeyCode.C))
                .Subscribe(notes => CopyNotes(selectedNoteObjects.Values));

            // Cutting notes by Ctrl-X
            this.UpdateAsObservable()
                .Where(_ => KeyInput.CtrlPlus(KeyCode.X))
                .Select(_ => selectedNoteObjects.Values
                    .Where(noteObj => EditData.Notes.ContainsKey(noteObj.note.position)))
                .Do(notes => CopyNotes(notes))
                .Subscribe(notes => DeleteNotes(notes));

            // Deselect by mousedown
            this.UpdateAsObservable()
                .Where(_ => !NoteCanvas.IsMouseOverWaveformRegion.Value)
                .Where(_ => Input.GetMouseButtonDown(0))
                .Subscribe(_ => Deselect());

            // Delete selected notes by delete key
            this.UpdateAsObservable()
                .Where(_ => Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace))
                .Select(_ => selectedNoteObjects.Values
                    .Where(noteObj => EditData.Notes.ContainsKey(noteObj.note.position)).ToList())
                .Do(_ => selectedNoteObjects.Clear())
                .Subscribe(notes => DeleteNotes(notes));

            // Paste to next beat by Ctrl-V
            this.UpdateAsObservable()
                .Where(_ => KeyInput.CtrlPlus(KeyCode.V))
                .Where(_ => copiedNotes.Count > 0)
                .Select(_ => copiedNotes.OrderBy(note => note.position.ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value)))
                .Subscribe(sortedCopiedNotes =>
                {
                    var firstPos = sortedCopiedNotes.First().position;
                    var lastPos = sortedCopiedNotes.Last().position;
                    var beatDiff = 1 + lastPos.num / lastPos.LPB - firstPos.num / firstPos.LPB;

                    var validNotes = copiedNotes.Where(note => note.position.Add(0, note.position.LPB * beatDiff, 0).ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value) < Audio.Source.clip.samples)
                        .ToList();

                    copiedNotes.Clear();

                    validNotes.ToObservable()
                        .Select(note =>
                            note.type == NoteTypes.Single
                                ? new Note(note.position.Add(0, note.position.LPB * beatDiff, 0))
                                : new Note(
                                    note.position.Add(0, note.position.LPB * beatDiff, 0),
                                    note.type,
                                    note.next.Add(0, note.next.LPB * beatDiff, 0),
                                    note.prev.Add(0, note.prev.LPB * beatDiff, 0)
                                ))
                        .Do(note => copiedNotes.Add(note))
                        .Subscribe(note =>
                            (EditData.Notes.ContainsKey(note.position)
                                ? editPresenter.RequestForChangeNoteStatus
                                : editPresenter.RequestForAddNote)
                            .OnNext(note));

                    Deselect();

                    validNotes.Select(obj => obj.position.Add(0, obj.position.LPB * beatDiff, 0))
                        .ToObservable()
                        .DelayFrame(1)
                        .Select(pastedPosition => EditData.Notes[pastedPosition])
                        .Do(pastedObj => selectedNoteObjects[pastedObj.note.position] = pastedObj)
                        .Subscribe(pastedObj => pastedObj.isSelected.Value = true);
                });
        }
 void Awake()
 {
     editPresenter = EditNotesPresenter.Instance;
     Audio.OnLoad.First().Subscribe(_ => Init());
 }