VLC Music Player Python

👤 Sharing: AI
----------------------------------------------------------------
----------------------------requirement.txt---------------------
----------------------------------------------------------------
mutagen==1.47.0
tkinter-tooltip==2.1.0
python-vlc==3.0.20123 

----------------------------------------------------------------
---------------------------vlc_music_player.py------------------
----------------------------------------------------------------
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
import threading
import time
import json
import random
from mutagen.mp3 import MP3
from mutagen.m4a import M4A
from mutagen.id3 import ID3
import vlc

class VLCMusicPlayer:
    def __init__(self, root):
        self.root = root
        self.root.title("? VLC Müzik Oynatıcı")
        self.root.geometry("900x700")  # Pencereyi büyüttüm
        self.root.configure(bg='#2b2b2b')
        
        # VLC instance oluştur
        self.vlc_instance = vlc.Instance()
        self.player = self.vlc_instance.media_player_new()
        
        # Değişkenler
        self.current_song = ""
        self.song_list = []
        self.current_index = 0
        self.is_playing = False
        self.is_paused = False
        self.volume = 0.7
        self.song_length = 0
        self.current_time = 0
        self.shuffle_mode = False
        self.repeat_mode = 0  # 0: kapalı, 1: tek şarkı, 2: tüm liste
        self.original_playlist = []
        self.playback_speed = 1.0
        self.total_duration = 0
        
        # GUI oluşturma
        self.create_gui()
        
        # Zamanlayıcı
        self.update_timer()
        
    def create_gui(self):
        # Ana frame
        main_frame = tk.Frame(self.root, bg='#2b2b2b')
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # Üst panel - Başlık ve kontroller (daha kompakt)
        top_panel = tk.Frame(main_frame, bg='#2b2b2b')
        top_panel.pack(fill=tk.X, pady=(0, 10))
        
        # Sol taraf - Başlık
        title_frame = tk.Frame(top_panel, bg='#2b2b2b')
        title_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 20))
        
        title_label = tk.Label(title_frame, text="? VLC Müzik Oynatıcı", 
                              font=("Arial", 16, "bold"), 
                              fg='#ffffff', bg='#2b2b2b')
        title_label.pack(anchor=tk.W)
        
        # Sağ taraf - Mod kontrolleri
        mode_frame = tk.Frame(top_panel, bg='#2b2b2b')
        mode_frame.pack(side=tk.RIGHT, fill=tk.Y)
        
        # Karıştır butonu
        self.shuffle_button = tk.Button(mode_frame, text="?", 
                                       font=("Arial", 12), 
                                       command=self.toggle_shuffle,
                                       bg='#4a4a4a', fg='#ffffff',
                                       relief=tk.FLAT, padx=8, pady=5)
        self.shuffle_button.pack(side=tk.LEFT, padx=2)
        
        # Tekrarlama butonu
        self.repeat_button = tk.Button(mode_frame, text="?", 
                                      font=("Arial", 12), 
                                      command=self.toggle_repeat,
                                      bg='#4a4a4a', fg='#ffffff',
                                      relief=tk.FLAT, padx=8, pady=5)
        self.repeat_button.pack(side=tk.LEFT, padx=2)
        
        # Şarkı bilgisi frame (daha kompakt)
        song_info_frame = tk.Frame(main_frame, bg='#3b3b3b', relief=tk.RAISED, bd=2)
        song_info_frame.pack(fill=tk.X, pady=(0, 10))
        
        # Şarkı adı ve zaman bilgisi aynı hizada
        info_frame = tk.Frame(song_info_frame, bg='#3b3b3b')
        info_frame.pack(fill=tk.X, padx=15, pady=8)
        
        # Sol taraf - Şarkı adı
        self.song_name_label = tk.Label(info_frame, text="Şarkı seçilmedi", 
                                       font=("Arial", 11, "bold"), 
                                       fg='#ffffff', bg='#3b3b3b',
                                       anchor=tk.W)
        self.song_name_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # Sağ taraf - Zaman bilgisi
        time_frame = tk.Frame(info_frame, bg='#3b3b3b')
        time_frame.pack(side=tk.RIGHT)
        
        self.current_time_label = tk.Label(time_frame, text="00:00", 
                                          font=("Arial", 10), 
                                          fg='#cccccc', bg='#3b3b3b')
        self.current_time_label.pack(side=tk.LEFT, padx=(0, 5))
        
        separator_label = tk.Label(time_frame, text="/", 
                                  font=("Arial", 10), 
                                  fg='#666666', bg='#3b3b3b')
        separator_label.pack(side=tk.LEFT, padx=2)
        
        self.total_time_label = tk.Label(time_frame, text="00:00", 
                                        font=("Arial", 10), 
                                        fg='#cccccc', bg='#3b3b3b')
        self.total_time_label.pack(side=tk.LEFT, padx=(5, 0))
        
        # İlerleme çubuğu (modern tasarım)
        progress_frame = tk.Frame(main_frame, bg='#2b2b2b')
        progress_frame.pack(fill=tk.X, pady=(0, 10))
        
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Scale(progress_frame, from_=0, to=100, 
                                     orient=tk.HORIZONTAL, 
                                     variable=self.progress_var,
                                     command=self.seek_song,
                                     style='Modern.Horizontal.TScale')
        self.progress_bar.pack(fill=tk.X, padx=10)
        
        # Tıklama olayı ekle
        self.progress_bar.bind('<Button-1>', self.on_progress_click)
        
        # Modern stil tanımla
        style = ttk.Style()
        style.configure('Modern.Horizontal.TScale', 
                       background='#3b3b3b',
                       troughcolor='#4a4a4a',
                       sliderwidth=12,
                       sliderlength=20)
        
        # Kontrol butonları (daha kompakt)
        control_frame = tk.Frame(main_frame, bg='#2b2b2b')
        control_frame.pack(pady=(0, 10))
        
        # Sol taraf - Ses kontrolü
        volume_frame = tk.Frame(control_frame, bg='#2b2b2b')
        volume_frame.pack(side=tk.LEFT, padx=(0, 15))
        
        volume_label = tk.Label(volume_frame, text="?", 
                               font=("Arial", 10), 
                               fg='#ffffff', bg='#2b2b2b')
        volume_label.pack(side=tk.LEFT, padx=(0, 5))
        
        self.volume_var = tk.DoubleVar(value=self.volume * 100)
        self.volume_scale = ttk.Scale(volume_frame, from_=0, to=100, 
                                     orient=tk.HORIZONTAL, 
                                     variable=self.volume_var,
                                     command=self.change_volume,
                                     style='Volume.Horizontal.TScale',
                                     length=80)
        self.volume_scale.pack(side=tk.LEFT)
        
        # Ses seviyesi göstergesi
        self.volume_value_label = tk.Label(volume_frame, text="70%", 
                                          font=("Arial", 8), 
                                          fg='#cccccc', bg='#2b2b2b')
        self.volume_value_label.pack(side=tk.LEFT, padx=(5, 0))
        
        # Orta - Oynatma kontrolleri
        play_controls = tk.Frame(control_frame, bg='#2b2b2b')
        play_controls.pack(side=tk.LEFT)
        
        # Önceki buton
        self.prev_button = tk.Button(play_controls, text="⏮", 
                                    font=("Arial", 8), 
                                    command=self.previous_song,
                                    bg='#4a90e2', fg='#ffffff',
                                    relief=tk.FLAT, padx=4, pady=4)
        self.prev_button.pack(side=tk.LEFT, padx=5)
        
        # Oynat/Duraklat buton
        self.play_button = tk.Button(play_controls, text="▶", 
                                    font=("Arial", 8), 
                                    command=self.play_pause,
                                    bg='#4a90e2', fg='#ffffff',
                                    relief=tk.FLAT, padx=4, pady=4)
        self.play_button.pack(side=tk.LEFT, padx=5)
        
        # Durdur buton
        self.stop_button = tk.Button(play_controls, text="⏹", 
                                    font=("Arial", 8), 
                                    command=self.stop_song,
                                    bg='#4a90e2', fg='#ffffff',
                                    relief=tk.FLAT, padx=4, pady=4)
        self.stop_button.pack(side=tk.LEFT, padx=5)
        
        # Sonraki buton
        self.next_button = tk.Button(play_controls, text="⏭", 
                                    font=("Arial", 8), 
                                    command=self.next_song,
                                    bg='#4a90e2', fg='#ffffff',
                                    relief=tk.FLAT, padx=4, pady=4)
        self.next_button.pack(side=tk.LEFT, padx=5)
        
        # Sağ taraf - Dosya işlemleri
        file_controls = tk.Frame(control_frame, bg='#2b2b2b')
        file_controls.pack(side=tk.RIGHT)
        
        self.add_button = tk.Button(file_controls, text="?", 
                                   command=self.add_files,
                                   bg='#4a4a4a', fg='#ffffff',
                                   relief=tk.FLAT, padx=4, pady=4,
                                   font=("Arial", 6))
        self.add_button.pack(side=tk.LEFT, padx=3)
        
        self.folder_button = tk.Button(file_controls, text="?", 
                                      command=self.add_folder,
                                      bg='#4a4a4a', fg='#ffffff',
                                      relief=tk.FLAT, padx=4, pady=4,
                                      font=("Arial", 6))
        self.folder_button.pack(side=tk.LEFT, padx=3)
        
        self.clear_button = tk.Button(file_controls, text="?️Liste", 
                                     command=self.clear_playlist,
                                     bg='#4a4a4a', fg='#ffffff',
                                     relief=tk.FLAT, padx=4, pady=4,
                                     font=("Arial", 6))
        self.clear_button.pack(side=tk.LEFT, padx=3)
        
        # Ses stili tanımla
        style.configure('Volume.Horizontal.TScale', 
                       background='#3b3b3b',
                       troughcolor='#4a4a4a',
                       sliderwidth=8,
                       sliderlength=16)
        
        # Hız kontrolü (alt satır)
        speed_frame = tk.Frame(main_frame, bg='#2b2b2b')
        speed_frame.pack(pady=(0, 10))
        
        speed_label = tk.Label(speed_frame, text="⚡", 
                              font=("Arial", 10), 
                              fg='#ffffff', bg='#2b2b2b')
        speed_label.pack(side=tk.LEFT, padx=(0, 5))
        
        # Hız butonları (daha kompakt)
        speeds = [("1x", 1.0), ("1.25x", 1.25), ("1.5x", 1.5), ("1.75x", 1.75), ("2x", 2.0)]
        self.speed_buttons = {}
        
        for text, speed in speeds:
            btn = tk.Button(speed_frame, text=text, 
                           font=("Arial", 8), 
                           command=lambda s=speed: self.change_speed(s),
                           bg='#4a4a4a', fg='#ffffff',
                           relief=tk.FLAT, padx=4, pady=1,
                           width=3)
            btn.pack(side=tk.LEFT, padx=1)
            self.speed_buttons[speed] = btn
        
        # Varsayılan hızı seç
        self.speed_buttons[1.0].config(bg='#ff6b6b')
        

        
        # Çalma listesi (daha büyük alan)
        playlist_frame = tk.Frame(main_frame, bg='#2b2b2b')
        playlist_frame.pack(fill=tk.BOTH, expand=True)
        
        playlist_header = tk.Frame(playlist_frame, bg='#2b2b2b')
        playlist_header.pack(fill=tk.X, pady=(0, 5))
        
        playlist_label = tk.Label(playlist_header, text="? Çalma Listesi", 
                                 font=("Arial", 12, "bold"), 
                                 fg='#ffffff', bg='#2b2b2b')
        playlist_label.pack(side=tk.LEFT)
        
        # Toplam süre ve şarkı sayısı
        self.playlist_info_label = tk.Label(playlist_header, text="0 şarkı • 00:00", 
                                           font=("Arial", 10), 
                                           fg='#cccccc', bg='#2b2b2b')
        self.playlist_info_label.pack(side=tk.RIGHT)
        
        # Çalma listesi listbox
        listbox_frame = tk.Frame(playlist_frame, bg='#3b3b3b', relief=tk.SUNKEN, bd=2)
        listbox_frame.pack(fill=tk.BOTH, expand=True)
        
        self.playlist_box = tk.Listbox(listbox_frame, 
                                      bg='#3b3b3b', fg='#ffffff',
                                      selectbackground='#4a4a4a',
                                      font=("Arial", 10),
                                      selectmode=tk.SINGLE)
        self.playlist_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # Scrollbar
        scrollbar = tk.Scrollbar(listbox_frame, orient=tk.VERTICAL, 
                                command=self.playlist_box.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.playlist_box.config(yscrollcommand=scrollbar.set)
        
        # Çift tıklama ile oynatma
        self.playlist_box.bind('<Double-Button-1>', self.play_selected)
    
    def toggle_shuffle(self):
        """Karıştırma modunu aç/kapat"""
        self.shuffle_mode = not self.shuffle_mode
        if self.shuffle_mode:
            self.shuffle_button.config(bg='#ff6b6b')
            # Mevcut çalma listesini kaydet
            if not self.original_playlist:
                self.original_playlist = self.song_list.copy()
            # Listeyi karıştır
            shuffled_list = self.song_list.copy()
            random.shuffle(shuffled_list)
            self.song_list = shuffled_list
            self.update_playlist_display()
        else:
            self.shuffle_button.config(bg='#4a4a4a')
            # Orijinal listeyi geri yükle
            if self.original_playlist:
                self.song_list = self.original_playlist.copy()
                self.update_playlist_display()
    
    def toggle_repeat(self):
        """Tekrarlama modunu değiştir"""
        self.repeat_mode = (self.repeat_mode + 1) % 3
        if self.repeat_mode == 0:
            self.repeat_button.config(text="?", bg='#4a4a4a')
        elif self.repeat_mode == 1:
            self.repeat_button.config(text="?1", bg='#ff6b6b')
        else:
            self.repeat_button.config(text="?", bg='#ff6b6b')
    
    def change_speed(self, speed):
        """Oynatma hızını değiştir"""
        self.playback_speed = speed
        # Tüm hız butonlarını sıfırla
        for btn in self.speed_buttons.values():
            btn.config(bg='#4a4a4a')
        # Seçili hızı vurgula
        self.speed_buttons[speed].config(bg='#ff6b6b')
        
        # VLC'de hızı ayarla
        if self.is_playing:
            self.player.set_rate(speed)
    
    def update_playlist_display(self):
        """Çalma listesi görünümünü güncelle"""
        self.playlist_box.delete(0, tk.END)
        for song in self.song_list:
            self.playlist_box.insert(tk.END, os.path.basename(song))
        self.update_playlist_info()
    
    def update_playlist_info(self):
        """Çalma listesi bilgilerini güncelle"""
        count = len(self.song_list)
        total_time = self.format_time(self.total_duration)
        self.playlist_info_label.config(text=f"{count} şarkı • {total_time}")
    
    def calculate_total_duration(self):
        """Toplam süreyi hesapla"""
        total = 0
        for song in self.song_list:
            try:
                if song.lower().endswith('.mp3'):
                    audio = MP3(song)
                    total += audio.info.length
                elif song.lower().endswith('.m4a'):
                    audio = M4A(song)
                    total += audio.info.length
                else:
                    # VLC ile uzunluk al
                    media = self.vlc_instance.media_new(song)
                    media.parse()
                    duration = media.get_duration() / 1000.0
                    total += duration
            except Exception as e:
                # Hata durumunda VLC ile dene
                try:
                    media = self.vlc_instance.media_new(song)
                    media.parse()
                    duration = media.get_duration() / 1000.0
                    total += duration
                except:
                    pass
        self.total_duration = total
        self.update_playlist_info()
        
    def add_files(self):
        """Dosya ekleme"""
        files = filedialog.askopenfilenames(
            title="Müzik dosyalarını seçin",
            filetypes=[
                ("Müzik dosyaları", "*.mp3 *.m4a *.wav *.flac *.ogg"),
                ("MP3 dosyaları", "*.mp3"),
                ("M4A dosyaları", "*.m4a"),
                ("WAV dosyaları", "*.wav"),
                ("FLAC dosyaları", "*.flac"),
                ("OGG dosyaları", "*.ogg"),
                ("Tüm dosyalar", "*.*")
            ]
        )
        
        for file in files:
            if file not in self.song_list:
                self.song_list.append(file)
        
        self.update_playlist_display()
        self.calculate_total_duration()
        
        if self.song_list and not self.current_song:
            self.current_index = 0
            self.load_song()
    
    def add_folder(self):
        """Klasör ekleme"""
        folder = filedialog.askdirectory(title="Müzik klasörünü seçin")
        if folder:
            for root, dirs, files in os.walk(folder):
                for file in files:
                    if file.lower().endswith(('.mp3', '.m4a', '.wav', '.flac', '.ogg')):
                        file_path = os.path.join(root, file)
                        if file_path not in self.song_list:
                            self.song_list.append(file_path)
            
            self.update_playlist_display()
            self.calculate_total_duration()
            
            if self.song_list and not self.current_song:
                self.current_index = 0
                self.load_song()
    
    def clear_playlist(self):
        """Çalma listesini temizleme"""
        if messagebox.askyesno("Onay", "Çalma listesini temizlemek istediğinizden emin misiniz?"):
            self.stop_song()
            self.song_list.clear()
            self.original_playlist.clear()
            self.shuffle_mode = False
            self.shuffle_button.config(bg='#4a4a4a')
            self.update_playlist_display()
            self.total_duration = 0
            self.current_song = ""
            self.song_name_label.config(text="Şarkı seçilmedi")
            self.current_time_label.config(text="00:00")
            self.total_time_label.config(text="00:00")
            self.progress_var.set(0)
    
    def load_song(self):
        """Şarkı yükleme"""
        if self.song_list:
            self.current_song = self.song_list[self.current_index]
            self.song_name_label.config(text=os.path.basename(self.current_song))
            
            # Şarkı uzunluğunu al
            try:
                if self.current_song.lower().endswith('.mp3'):
                    audio = MP3(self.current_song)
                    self.song_length = audio.info.length
                elif self.current_song.lower().endswith('.m4a'):
                    audio = M4A(self.current_song)
                    self.song_length = audio.info.length
                else:
                    # VLC ile uzunluk al
                    media = self.vlc_instance.media_new(self.current_song)
                    media.parse()
                    self.song_length = media.get_duration() / 1000.0
                
                self.total_time_label.config(text=self.format_time(self.song_length))
            except Exception as e:
                # Hata durumunda VLC ile dene
                try:
                    media = self.vlc_instance.media_new(self.current_song)
                    media.parse()
                    self.song_length = media.get_duration() / 1000.0
                    self.total_time_label.config(text=self.format_time(self.song_length))
                except:
                    self.song_length = 0
                    self.total_time_label.config(text="00:00")
            
            # Çalma listesinde seçili öğeyi güncelle
            self.playlist_box.selection_clear(0, tk.END)
            self.playlist_box.selection_set(self.current_index)
            self.playlist_box.see(self.current_index)
    
    def play_pause(self):
        """Oynat/Duraklat"""
        if not self.current_song:
            if self.song_list:
                self.current_index = 0
                self.load_song()
                self.play_song()
            return
        
        if self.is_playing:
            if self.is_paused:
                self.resume_song()
            else:
                self.pause_song()
        else:
            self.play_song()
    
    def play_song(self):
        """Şarkı oynatma"""
        try:
            if self.current_song:
                # VLC ile media oluştur
                media = self.vlc_instance.media_new(self.current_song)
                self.player.set_media(media)
                self.player.play()
                self.player.audio_set_volume(int(self.volume * 100))
                self.player.set_rate(self.playback_speed)
                
                self.is_playing = True
                self.is_paused = False
                self.play_button.config(text="⏸")
                
                # İlerleme çubuğunu sıfırla
                self.progress_var.set(0)
                self.current_time = 0
                self.current_time_label.config(text="00:00")
                
        except Exception as e:
            messagebox.showerror("Hata", f"Şarkı oynatılamadı: {str(e)}")
    
    def pause_song(self):
        """Şarkı duraklatma"""
        self.player.pause()
        self.is_paused = True
        self.play_button.config(text="▶")
    
    def resume_song(self):
        """Şarkı devam ettirme"""
        self.player.pause()  # VLC'de pause/resume aynı fonksiyon
        self.is_paused = False
        self.play_button.config(text="⏸")
    
    def stop_song(self):
        """Şarkı durdurma"""
        self.player.stop()
        self.is_playing = False
        self.is_paused = False
        self.play_button.config(text="▶")
        self.current_time = 0
        self.progress_var.set(0)
        self.current_time_label.config(text="00:00")
    
    def next_song(self):
        """Sonraki şarkı"""
        if self.song_list:
            if self.repeat_mode == 1:  # Tek şarkı tekrarlama
                self.load_song()
                if self.is_playing:
                    self.play_song()
            else:
                self.current_index = (self.current_index + 1) % len(self.song_list)
                self.load_song()
                if self.is_playing:
                    self.play_song()
    
    def previous_song(self):
        """Önceki şarkı"""
        if self.song_list:
            self.current_index = (self.current_index - 1) % len(self.song_list)
            self.load_song()
            if self.is_playing:
                self.play_song()
    
    def play_selected(self, event):
        """Seçili şarkıyı oynatma"""
        selection = self.playlist_box.curselection()
        if selection:
            self.current_index = selection[0]
            self.load_song()
            self.play_song()
    
    def seek_song(self, value):
        """Şarkıda ilerleme (sürükleme ile)"""
        if self.current_song and self.song_length > 0:
            position = float(value) / 100.0 * self.song_length
            self.player.set_time(int(position * 1000))  # VLC milisaniye kullanır
            self.current_time = position
            self.current_time_label.config(text=self.format_time(self.current_time))
    
    def on_progress_click(self, event):
        """İlerleme çubuğuna tıklama ile ilerleme"""
        if self.current_song and self.song_length > 0:
            # Tıklanan pozisyonu hesapla
            widget_width = self.progress_bar.winfo_width()
            click_x = event.x
            percentage = (click_x / widget_width) * 100
            
            # Yüzdeyi sınırla
            percentage = max(0, min(100, percentage))
            
            # Pozisyonu hesapla ve uygula
            position = (percentage / 100.0) * self.song_length
            self.player.set_time(int(position * 1000))  # VLC milisaniye kullanır
            self.current_time = position
            self.current_time_label.config(text=self.format_time(self.current_time))
            
            # İlerleme çubuğunu güncelle
            self.progress_var.set(percentage)
    
    def change_volume(self, value):
        """Ses seviyesi değiştirme"""
        self.volume = float(value) / 100.0
        self.player.audio_set_volume(int(self.volume * 100))
        # Ses seviyesi göstergesini güncelle
        self.volume_value_label.config(text=f"{int(self.volume * 100)}%")
    
    def format_time(self, seconds):
        """Zamanı formatlama"""
        minutes = int(seconds // 60)
        seconds = int(seconds % 60)
        return f"{minutes:02d}:{seconds:02d}"
    
    def update_timer(self):
        """Zamanlayıcı güncelleme"""
        if self.is_playing and not self.is_paused:
            try:
                # VLC'den mevcut pozisyonu al
                current_pos = self.player.get_time() / 1000.0
                if current_pos >= 0:  # 0 dahil olmalı
                    self.current_time = current_pos
                    self.current_time_label.config(text=self.format_time(self.current_time))
                    
                    if self.song_length > 0:
                        progress = (self.current_time / self.song_length) * 100
                        # İlerleme çubuğunu güncelle (sadece oynatma sırasında)
                        if not self.is_paused:
                            self.progress_var.set(progress)
                        
                        # Şarkı bittiğinde sonrakine geç
                        if self.current_time >= self.song_length - 1:  # 1 saniye tolerans
                            if self.repeat_mode == 2:  # Liste tekrarlama
                                self.next_song()
                            elif self.repeat_mode == 1:  # Tek şarkı tekrarlama
                                self.play_song()
                            else:  # Tekrarlama kapalı
                                if self.current_index < len(self.song_list) - 1:
                                    self.next_song()
                                else:
                                    self.stop_song()
                            
            except Exception as e:
                # Hata durumunda sessizce devam et
                pass
        
        # Daha sık güncelleme (500ms)
        self.root.after(500, self.update_timer)

def main():
    root = tk.Tk()
    app = VLCMusicPlayer(root)
    root.mainloop()

if __name__ == "__main__":
    main() 
-------------------------------------------------------------------
----------------------------Built with Cursor----------------------
-------------------------------------------------------------------
👁️ Viewed: 76

Comments