fix: support go install module path

This commit is contained in:
Bjarne Øverli
2026-07-05 13:59:18 +02:00
parent 5cf895eeb1
commit 8dad762349
114 changed files with 282 additions and 271 deletions
+8
View File
@@ -28,6 +28,14 @@ The formula pulls in all required runtime libraries automatically.
yay -S cliamp yay -S cliamp
``` ```
**Go**
```sh
go install github.com/bjarneo/cliamp@latest
```
Linux builds need ALSA development headers installed first. See [Building from source](#building-from-source).
**Pre-built binaries** **Pre-built binaries**
Download from [GitHub Releases](https://github.com/bjarneo/cliamp/releases/latest). Download from [GitHub Releases](https://github.com/bjarneo/cliamp/releases/latest).
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"os" "os"
"time" "time"
"cliamp/history" "github.com/bjarneo/cliamp/history"
) )
// HistoryShow prints recently played tracks, newest first. limit <= 0 prints all. // HistoryShow prints recently played tracks, newest first. limit <= 0 prints all.
+5 -5
View File
@@ -9,11 +9,11 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"cliamp/external/local" "github.com/bjarneo/cliamp/external/local"
"cliamp/internal/sshurl" "github.com/bjarneo/cliamp/internal/sshurl"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
// PlaylistList prints all playlists with their track counts. // PlaylistList prints all playlists with their track counts.
+6 -6
View File
@@ -25,12 +25,12 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2" "charm.land/lipgloss/v2"
"cliamp/external/emby" "github.com/bjarneo/cliamp/external/emby"
"cliamp/external/jellyfin" "github.com/bjarneo/cliamp/external/jellyfin"
"cliamp/external/navidrome" "github.com/bjarneo/cliamp/external/navidrome"
"cliamp/external/netease" "github.com/bjarneo/cliamp/external/netease"
"cliamp/external/plex" "github.com/bjarneo/cliamp/external/plex"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// Setup launches the interactive wizard. Returns nil on clean exit. // Setup launches the interactive wizard. Returns nil on clean exit.
+11 -11
View File
@@ -11,17 +11,17 @@ import (
cli "github.com/urfave/cli/v3" cli "github.com/urfave/cli/v3"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/cmd" "github.com/bjarneo/cliamp/cmd"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/external/qobuz" "github.com/bjarneo/cliamp/external/qobuz"
"cliamp/external/spotify" "github.com/bjarneo/cliamp/external/spotify"
"cliamp/ipc" "github.com/bjarneo/cliamp/ipc"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/pluginmgr" "github.com/bjarneo/cliamp/pluginmgr"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
"cliamp/upgrade" "github.com/bjarneo/cliamp/upgrade"
) )
func buildApp() *cli.Command { func buildApp() *cli.Command {
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"strings" "strings"
"time" "time"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// configPath returns the path to the config file. // configPath returns the path to the config file.
+9 -9
View File
@@ -11,15 +11,15 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/external/local" "github.com/bjarneo/cliamp/external/local"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/internal/resume" "github.com/bjarneo/cliamp/internal/resume"
"cliamp/ipc" "github.com/bjarneo/cliamp/ipc"
"cliamp/mediactl" "github.com/bjarneo/cliamp/mediactl"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/ui/model" "github.com/bjarneo/cliamp/ui/model"
) )
// runDaemon runs cliamp without a TUI: serves IPC against the shared // runDaemon runs cliamp without a TUI: serves IPC against the shared
+3 -2
View File
@@ -59,8 +59,9 @@ package jellyfin
import ( import (
"context" "context"
"cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/playlist"
"github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+1 -1
View File
@@ -2,7 +2,7 @@
// Emby server and exposes it as a playlist provider. // Emby server and exposes it as a playlist provider.
package emby package emby
import "cliamp/internal/embyapi" import "github.com/bjarneo/cliamp/internal/embyapi"
// Client and Track alias the shared embyapi types so the provider layer reads // Client and Track alias the shared embyapi types so the provider layer reads
// naturally and external callers keep using emby.Client. // naturally and external callers keep using emby.Client.
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
var ( var (
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
type roundTripFunc func(*http.Request) (*http.Response, error) type roundTripFunc func(*http.Request) (*http.Response, error)
+1 -1
View File
@@ -2,7 +2,7 @@
// to a Jellyfin server and exposes it as a playlist provider. // to a Jellyfin server and exposes it as a playlist provider.
package jellyfin package jellyfin
import "cliamp/internal/embyapi" import "github.com/bjarneo/cliamp/internal/embyapi"
// Client and Track alias the shared embyapi types so the provider layer reads // Client and Track alias the shared embyapi types so the provider layer reads
// naturally and external callers keep using jellyfin.Client. // naturally and external callers keep using jellyfin.Client.
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
var ( var (
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
type roundTripFunc func(*http.Request) (*http.Response, error) type roundTripFunc func(*http.Request) (*http.Response, error)
+6 -6
View File
@@ -15,12 +15,12 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/history" "github.com/bjarneo/cliamp/history"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/fuzzy" "github.com/bjarneo/cliamp/internal/fuzzy"
"cliamp/internal/tomlutil" "github.com/bjarneo/cliamp/internal/tomlutil"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"testing" "testing"
"time" "time"
"cliamp/history" "github.com/bjarneo/cliamp/history"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
func newTestProvider(t *testing.T) *Provider { func newTestProvider(t *testing.T) *Provider {
+3 -3
View File
@@ -17,9 +17,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+3 -3
View File
@@ -7,9 +7,9 @@ import (
"strings" "strings"
"testing" "testing"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// subsonicHandler serves fake Subsonic API responses for testing. // subsonicHandler serves fake Subsonic API responses for testing.
+3 -3
View File
@@ -17,9 +17,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
var ( var (
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strings" "strings"
"testing" "testing"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
func TestPlaylistsIncludesAccountListsAndCharts(t *testing.T) { func TestPlaylistsIncludesAccountListsAndCharts(t *testing.T) {
+3 -3
View File
@@ -6,9 +6,9 @@ import (
"slices" "slices"
"sync" "sync"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
"cliamp/config" "github.com/bjarneo/cliamp/config"
) )
// sectionsHandler returns a handler that serves a single music section. // sectionsHandler returns a handler that serves a single music section.
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// storedCreds holds persisted Qobuz credentials so the user only signs in once. // storedCreds holds persisted Qobuz credentials so the user only signs in once.
+3 -3
View File
@@ -9,9 +9,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+2 -2
View File
@@ -10,8 +10,8 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/internal/browser" "github.com/bjarneo/cliamp/internal/browser"
) )
// authURLObserver is invoked with the OAuth URL when interactive auth begins. // authURLObserver is invoked with the OAuth URL when interactive auth begins.
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/tomlutil" "github.com/bjarneo/cliamp/internal/tomlutil"
) )
const favoritesFile = "radio_favorites.toml" const favoritesFile = "radio_favorites.toml"
+4 -4
View File
@@ -14,10 +14,10 @@ import (
"strings" "strings"
"sync" "sync"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/tomlutil" "github.com/bjarneo/cliamp/internal/tomlutil"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+3 -3
View File
@@ -15,9 +15,9 @@ import (
"slices" "slices"
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
// Compile-time interface checks. // Compile-time interface checks.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"strings" "strings"
"testing" "testing"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
func TestNewFromConfig(t *testing.T) { func TestNewFromConfig(t *testing.T) {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// DefaultClientID is the librespot keymaster client_id, shared by spotify-player // DefaultClientID is the librespot keymaster client_id, shared by spotify-player
+3 -3
View File
@@ -22,9 +22,9 @@ import (
"github.com/devgianlu/go-librespot/audio" "github.com/devgianlu/go-librespot/audio"
"github.com/gopxl/beep/v2" "github.com/gopxl/beep/v2"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// Compile-time interface checks. // Compile-time interface checks.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// maxResponseBody limits JSON API responses to 10 MB. // maxResponseBody limits JSON API responses to 10 MB.
+3 -3
View File
@@ -18,9 +18,9 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/internal/browser" "github.com/bjarneo/cliamp/internal/browser"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
librespot "github.com/devgianlu/go-librespot" librespot "github.com/devgianlu/go-librespot"
librespotPlayer "github.com/devgianlu/go-librespot/player" librespotPlayer "github.com/devgianlu/go-librespot/player"
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"github.com/gopxl/beep/v2" "github.com/gopxl/beep/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
var errSpotifyUnavailable = errors.New("spotify: unavailable on Windows (go-librespot requires CGO)") var errSpotifyUnavailable = errors.New("spotify: unavailable on Windows (go-librespot requires CGO)")
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// cacheTTL is how long cached playlist/track data is considered fresh. // cacheTTL is how long cached playlist/track data is considered fresh.
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"sync" "sync"
"time" "time"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"google.golang.org/api/youtube/v3" "google.golang.org/api/youtube/v3"
) )
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"sync" "sync"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"google.golang.org/api/youtube/v3" "google.golang.org/api/youtube/v3"
) )
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
func TestRefreshInvalidatesAllCaches(t *testing.T) { func TestRefreshInvalidatesAllCaches(t *testing.T) {
+2 -2
View File
@@ -11,8 +11,8 @@ import (
"path/filepath" "path/filepath"
"sync" "sync"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/browser" "github.com/bjarneo/cliamp/internal/browser"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
+2 -3
View File
@@ -1,17 +1,17 @@
module cliamp module github.com/bjarneo/cliamp
go 1.26 go 1.26
require ( require (
charm.land/bubbletea/v2 v2.0.2 charm.land/bubbletea/v2 v2.0.2
charm.land/lipgloss/v2 v2.0.2 charm.land/lipgloss/v2 v2.0.2
github.com/charmbracelet/x/ansi v0.11.6
github.com/devgianlu/go-librespot v0.7.1 github.com/devgianlu/go-librespot v0.7.1
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8
github.com/godbus/dbus/v5 v5.2.2 github.com/godbus/dbus/v5 v5.2.2
github.com/gopxl/beep/v2 v2.1.1 github.com/gopxl/beep/v2 v2.1.1
github.com/jfreymuth/oggvorbis v1.0.5 github.com/jfreymuth/oggvorbis v1.0.5
github.com/kkdai/youtube/v2 v2.10.6 github.com/kkdai/youtube/v2 v2.10.6
github.com/madelynnblue/go-dsp v1.0.0
github.com/urfave/cli/v3 v3.8.0 github.com/urfave/cli/v3 v3.8.0
github.com/yuin/gopher-lua v1.1.2 github.com/yuin/gopher-lua v1.1.2
golang.org/x/oauth2 v0.36.0 golang.org/x/oauth2 v0.36.0
@@ -28,7 +28,6 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/colorprofile v0.4.3 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect
github.com/charmbracelet/x/ansi v0.11.6 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect
-2
View File
@@ -106,8 +106,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/madelynnblue/go-dsp v1.0.0 h1:ufzvSGl8IdjCA6BFVUx1cZW/aDiiXxDBWU1MpkrtAiM=
github.com/madelynnblue/go-dsp v1.0.0/go.mod h1:dpf07Rj/u3te6cW3KwRBAqlyjP4InXHhNaYVuY73hHU=
github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w=
github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mewkiz/flac v1.0.12 h1:5Y1BRlUebfiVXPmz7hDD7h3ceV2XNrGNMejNVjDpgPY= github.com/mewkiz/flac v1.0.12 h1:5Y1BRlUebfiVXPmz7hDD7h3ceV2XNrGNMejNVjDpgPY=
+3 -3
View File
@@ -20,9 +20,9 @@ import (
"sync" "sync"
"time" "time"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/tomlutil" "github.com/bjarneo/cliamp/internal/tomlutil"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// DefaultCap is the maximum number of entries kept on disk. Older entries are // DefaultCap is the maximum number of entries kept on disk. Older entries are
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"testing" "testing"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
func newTestStore(t *testing.T) *Store { func newTestStore(t *testing.T) *Store {
+2 -2
View File
@@ -18,8 +18,8 @@ import (
"sync" "sync"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
var defaultHTTPClient = &http.Client{Timeout: 30 * time.Second} var defaultHTTPClient = &http.Client{Timeout: 30 * time.Second}
+3 -3
View File
@@ -9,9 +9,9 @@ import (
"testing" "testing"
"time" "time"
"cliamp/internal/appmeta" "github.com/bjarneo/cliamp/internal/appmeta"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
type roundTripFunc func(*http.Request) (*http.Response, error) type roundTripFunc func(*http.Request) (*http.Response, error)
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"net/http" "net/http"
"strings" "strings"
"cliamp/internal/appmeta" "github.com/bjarneo/cliamp/internal/appmeta"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// dialect captures the handful of behaviors that differ between Emby and // dialect captures the handful of behaviors that differ between Emby and
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// State holds enough information to resume a previous playback session. // State holds enough information to resume a previous playback session.
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// DefaultSocketPath returns the default IPC socket path (~/.config/cliamp/cliamp.sock). // DefaultSocketPath returns the default IPC socket path (~/.config/cliamp/cliamp.sock).
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
// captureDispatcher records the last message sent via Send and optionally // captureDispatcher records the last message sent via Send and optionally
+2 -2
View File
@@ -13,8 +13,8 @@ import (
"sync" "sync"
"time" "time"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
// Dispatcher is how the server sends commands to the TUI. // Dispatcher is how the server sends commands to the TUI.
+1 -1
View File
@@ -10,7 +10,7 @@ import (
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
var ( var (
+1 -1
View File
@@ -9,7 +9,7 @@ import (
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// pluginStore is a per-plugin key/value store persisted as a single JSON file // pluginStore is a per-plugin key/value store persisted as a single JSON file
+1 -1
View File
@@ -14,7 +14,7 @@ import (
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
// Plugin represents a single loaded Lua plugin. // Plugin represents a single loaded Lua plugin.
+27 -27
View File
@@ -10,33 +10,33 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/external/emby" "github.com/bjarneo/cliamp/external/emby"
"cliamp/external/jellyfin" "github.com/bjarneo/cliamp/external/jellyfin"
"cliamp/external/local" "github.com/bjarneo/cliamp/external/local"
"cliamp/external/navidrome" "github.com/bjarneo/cliamp/external/navidrome"
"cliamp/external/netease" "github.com/bjarneo/cliamp/external/netease"
"cliamp/external/plex" "github.com/bjarneo/cliamp/external/plex"
"cliamp/external/qobuz" "github.com/bjarneo/cliamp/external/qobuz"
"cliamp/external/radio" "github.com/bjarneo/cliamp/external/radio"
"cliamp/external/radiometa" "github.com/bjarneo/cliamp/external/radiometa"
"cliamp/external/soundcloud" "github.com/bjarneo/cliamp/external/soundcloud"
"cliamp/external/spotify" "github.com/bjarneo/cliamp/external/spotify"
"cliamp/external/ytmusic" "github.com/bjarneo/cliamp/external/ytmusic"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/internal/appmeta" "github.com/bjarneo/cliamp/internal/appmeta"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/internal/resume" "github.com/bjarneo/cliamp/internal/resume"
"cliamp/ipc" "github.com/bjarneo/cliamp/ipc"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
"cliamp/mediactl" "github.com/bjarneo/cliamp/mediactl"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
"cliamp/ui/model" "github.com/bjarneo/cliamp/ui/model"
) )
// version is set at build time via -ldflags "-X main.version=vX.Y.Z". // version is set at build time via -ldflags "-X main.version=vX.Y.Z".
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
// trackPath returns a unique MPRIS track object path for a sequence number. // trackPath returns a unique MPRIS track object path for a sequence number.
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
func TestMakeMetadataMapsPlaybackTrackToMPRISFields(t *testing.T) { func TestMakeMetadataMapsPlaybackTrackToMPRISFields(t *testing.T) {
+1 -1
View File
@@ -181,7 +181,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
func Run(prog *tea.Program, svc *Service) (tea.Model, error) { func Run(prog *tea.Program, svc *Service) (tea.Model, error) {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
func TestDarwinCallbacksUseHandleRouting(t *testing.T) { func TestDarwinCallbacksUseHandleRouting(t *testing.T) {
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"github.com/godbus/dbus/v5/introspect" "github.com/godbus/dbus/v5/introspect"
"github.com/godbus/dbus/v5/prop" "github.com/godbus/dbus/v5/prop"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
func Run(prog *tea.Program, svc *Service) (tea.Model, error) { func Run(prog *tea.Program, svc *Service) (tea.Model, error) {
+1 -1
View File
@@ -7,7 +7,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
) )
func Run(prog *tea.Program, svc *Service) (tea.Model, error) { func Run(prog *tea.Program, svc *Service) (tea.Model, error) {
+2 -2
View File
@@ -11,7 +11,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/internal/sshurl" "github.com/bjarneo/cliamp/internal/sshurl"
"github.com/gopxl/beep/v2" "github.com/gopxl/beep/v2"
"github.com/gopxl/beep/v2/flac" "github.com/gopxl/beep/v2/flac"
@@ -19,7 +19,7 @@ import (
"github.com/gopxl/beep/v2/vorbis" "github.com/gopxl/beep/v2/vorbis"
"github.com/gopxl/beep/v2/wav" "github.com/gopxl/beep/v2/wav"
"cliamp/internal/httpclient" "github.com/bjarneo/cliamp/internal/httpclient"
) )
// SupportedExts is the set of file extensions the player can decode. // SupportedExts is the set of file extensions the player can decode.
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"github.com/dhowden/tag" "github.com/dhowden/tag"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
const ( const (
+2 -2
View File
@@ -13,8 +13,8 @@ import (
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
) )
var httpClient = &http.Client{Timeout: 30 * time.Second} var httpClient = &http.Client{Timeout: 30 * time.Second}
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"github.com/gopxl/beep/v2" "github.com/gopxl/beep/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// Searcher is implemented by providers that support searching for tracks. // Searcher is implemented by providers that support searching for tracks.
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// m3uEntry holds a single parsed M3U entry with optional EXTINF metadata. // m3uEntry holds a single parsed M3U entry with optional EXTINF metadata.
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// plsEntry holds a single parsed PLS entry. // plsEntry holds a single parsed PLS entry.
+2 -2
View File
@@ -24,8 +24,8 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"github.com/kkdai/youtube/v2" "github.com/kkdai/youtube/v2"
) )
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
var ( var (
+5
View File
@@ -1479,6 +1479,11 @@
<code><span class="prompt">$ </span>yay -S cliamp</code> <code><span class="prompt">$ </span>yay -S cliamp</code>
<span class="copied-msg">COPIED</span> <span class="copied-msg">COPIED</span>
</div> </div>
<div class="install-box" onclick="copyCmd(this,'go install github.com/bjarneo/cliamp@latest')">
<div class="install-platform">Go</div>
<code><span class="prompt">$ </span>go install github.com/bjarneo/cliamp@latest</code>
<span class="copied-msg">COPIED</span>
</div>
</div> </div>
<div class="install-note"> <div class="install-note">
Or build from source — <a href="https://github.com/bjarneo/cliamp">see the README</a>. Windows builds are available from Releases; when <code>HOME</code> is unset, config lives under <code>%APPDATA%\cliamp</code>. Or build from source — <a href="https://github.com/bjarneo/cliamp">see the README</a>. Windows builds are available from Releases; when <code>HOME</code> is unset, config lives under <code>%APPDATA%\cliamp</code>.
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"slices" "slices"
"strings" "strings"
"cliamp/internal/appdir" "github.com/bjarneo/cliamp/internal/appdir"
) )
//go:embed themes/*.toml //go:embed themes/*.toml
+6 -6
View File
@@ -6,12 +6,12 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/lyrics" "github.com/bjarneo/cliamp/lyrics"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
// — Message types used by tea.Cmd constructors — // — Message types used by tea.Cmd constructors —
+4 -4
View File
@@ -8,10 +8,10 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/fuzzy" "github.com/bjarneo/cliamp/internal/fuzzy"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
// fbEntry is a single item in the file browser listing. // fbEntry is a single item in the file browser listing.
+6 -6
View File
@@ -6,12 +6,12 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/history" "github.com/bjarneo/cliamp/history"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// applyThemeAll updates colors, spectrum styles, and model-specific styles. // applyThemeAll updates colors, spectrum styles, and model-specific styles.
+4 -4
View File
@@ -5,10 +5,10 @@ import (
"fmt" "fmt"
"strings" "strings"
"cliamp/lyrics" "github.com/bjarneo/cliamp/lyrics"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// Inline overlays render in the playlist region while the now-playing, // Inline overlays render in the playlist region while the now-playing,
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// — provider browser (nav) — // — provider browser (nav) —
+5 -5
View File
@@ -10,11 +10,11 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/history" "github.com/bjarneo/cliamp/history"
"cliamp/internal/fileutil" "github.com/bjarneo/cliamp/internal/fileutil"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// quit shuts down the player and signals the TUI to exit. // quit shuts down the player and signals the TUI to exit.
+2 -2
View File
@@ -3,8 +3,8 @@ package model
import ( import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// handleNavBrowserKey processes key presses while the provider browser is open. // handleNavBrowserKey processes key presses while the provider browser is open.
+1 -1
View File
@@ -3,7 +3,7 @@ package model
import ( import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// maybeLoadCatalogBatch triggers a catalog batch fetch when the cursor is near the // maybeLoadCatalogBatch triggers a catalog batch fetch when the cursor is near the
+1 -1
View File
@@ -3,7 +3,7 @@ package model
import ( import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// handleSpotSearchKey dispatches key presses to the active provider search screen. // handleSpotSearchKey dispatches key presses to the active provider search screen.
+1 -1
View File
@@ -3,7 +3,7 @@ package model
import ( import (
"strings" "strings"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// lyricsArtistTitle resolves the best artist and title for a lyrics lookup. // lyricsArtistTitle resolves the best artist and title for a lyrics lookup.
+7 -7
View File
@@ -4,13 +4,13 @@ package model
import ( import (
"time" "time"
"cliamp/history" "github.com/bjarneo/cliamp/history"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// ConfigSaver persists individual config key-value pairs. // ConfigSaver persists individual config key-value pairs.
+4 -4
View File
@@ -4,10 +4,10 @@ import (
"strings" "strings"
"time" "time"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// notifyAll sends the current playback state to both OS media controls and Lua plugins. // notifyAll sends the current playback state to both OS media controls and Lua plugins.
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"testing" "testing"
"time" "time"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
type fakeNotifier struct { type fakeNotifier struct {
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"charm.land/lipgloss/v2" "charm.land/lipgloss/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// newInlineOverlayModel builds a Model with a real player/playlist/visualizer // newInlineOverlayModel builds a Model with a real player/playlist/visualizer
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"cliamp/theme" "github.com/bjarneo/cliamp/theme"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// openThemePicker re-loads themes from disk (picking up new user files) // openThemePicker re-loads themes from disk (picking up new user files)
+1 -1
View File
@@ -5,7 +5,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
func TestHandlePasteRoutesToActiveInput(t *testing.T) { func TestHandlePasteRoutesToActiveInput(t *testing.T) {
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
func TestShouldReconnectOnUnpause(t *testing.T) { func TestShouldReconnectOnUnpause(t *testing.T) {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
const ytdlReconnectPauseThreshold = 45 * time.Second const ytdlReconnectPauseThreshold = 45 * time.Second
+1 -1
View File
@@ -1,6 +1,6 @@
package model package model
import "cliamp/playlist" import "github.com/bjarneo/cliamp/playlist"
func (m Model) currentPlaybackTrack() (playlist.Track, int) { func (m Model) currentPlaybackTrack() (playlist.Track, int) {
if m.playingTrackActive && (m.buffering || (m.player != nil && m.player.IsPlaying())) { if m.playingTrackActive && (m.buffering || (m.player != nil && m.player.IsPlaying())) {
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"time" "time"
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
type playbackFakeEngine struct { type playbackFakeEngine struct {
+1 -1
View File
@@ -1,7 +1,7 @@
package model package model
import ( import (
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
) )
// pluginEmitState is the last player/queue state emitted to plugins. It lets // pluginEmitState is the last player/queue state emitted to plugins. It lets
+2 -2
View File
@@ -3,8 +3,8 @@ package model
import ( import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/resolve" "github.com/bjarneo/cliamp/resolve"
) )
// PluginQueueMsg is sent by Lua plugins (cliamp.queue.*) to mutate the queue. // PluginQueueMsg is sent by Lua plugins (cliamp.queue.*) to mutate the queue.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
) )
// streamPreloadLeadTime is how far before the end of a stream we arm the // streamPreloadLeadTime is how far before the end of a stream we arm the
+2 -2
View File
@@ -5,8 +5,8 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// resetProviderNav resets provider navigation and search state to the top. // resetProviderNav resets provider navigation and search state to the top.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"charm.land/lipgloss/v2" "charm.land/lipgloss/v2"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// clampScroll keeps cursor inside [0, count) and adjusts scroll so that // clampScroll keeps cursor inside [0, count) and adjusts scroll so that
+1 -1
View File
@@ -3,7 +3,7 @@ package model
import ( import (
"sort" "sort"
"cliamp/internal/fuzzy" "github.com/bjarneo/cliamp/internal/fuzzy"
) )
// updateSearch filters the playlist by the current search query, ranking // updateSearch filters the playlist by the current search query, ranking
+2 -2
View File
@@ -5,8 +5,8 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/luaplugin" "github.com/bjarneo/cliamp/luaplugin"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
) )
// seekDebounceTicks is how many ticks to wait after the last seek keypress // seekDebounceTicks is how many ticks to wait after the last seek keypress
+2 -2
View File
@@ -1,8 +1,8 @@
package model package model
import ( import (
"cliamp/config" "github.com/bjarneo/cliamp/config"
"cliamp/ui" "github.com/bjarneo/cliamp/ui"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
+5 -5
View File
@@ -8,11 +8,11 @@ import (
"strings" "strings"
"time" "time"
"cliamp/applog" "github.com/bjarneo/cliamp/applog"
"cliamp/lyrics" "github.com/bjarneo/cliamp/lyrics"
"cliamp/player" "github.com/bjarneo/cliamp/player"
"cliamp/playlist" "github.com/bjarneo/cliamp/playlist"
"cliamp/provider" "github.com/bjarneo/cliamp/provider"
) )
// searchState holds state for the playlist search overlay. // searchState holds state for the playlist search overlay.
+2 -2
View File
@@ -6,8 +6,8 @@ import (
tea "charm.land/bubbletea/v2" tea "charm.land/bubbletea/v2"
"cliamp/internal/playback" "github.com/bjarneo/cliamp/internal/playback"
"cliamp/ipc" "github.com/bjarneo/cliamp/ipc"
) )
type fakeEngine struct { type fakeEngine struct {

Some files were not shown because too many files have changed in this diff Show More