From d687542b1feb28ef443c84e26a9189a8cd676a4c Mon Sep 17 00:00:00 2001 From: Michael Whyte Date: Wed, 13 May 2026 21:44:34 +0100 Subject: [PATCH 1/4] feat: Shazam-based track identification Adds an `i` keybinding that captures ~12s of audio from the playing stream, fingerprints it locally in pure Go, and queries Shazam's recognition endpoint. Results appear in a modal with title/artist/album and an `o` shortcut to open the canonical Shazam page in the default browser. Completely free, no API key required. The fingerprinting algorithm is vendored from lukechampine/barbershop (MIT, attribution preserved in pkg/identifier/shazam/LICENSE) and runs against the same `amp.shazam.com/discovery` endpoint Shazam's mobile client uses. Audio is captured via a parallel HTTP read of the stream URL, MP3-decoded with hajimehoshi/go-mp3, frame-synced to recover from mid-stream connects, downmixed to mono and resampled to 16 kHz before fingerprinting. Includes `cmd/test-shazam` for diagnosing streams from the CLI. Pipeline is MP3-only; AAC/Ogg streams short-circuit with a friendly error. Co-Authored-By: Claude Opus 4.7 --- .gitignore | 1 + cmd/test-shazam/main.go | 113 ++ go.mod | 4 + go.sum | 14 +- pkg/identifier/capture.go | 258 +++ pkg/identifier/identifier.go | 66 + pkg/identifier/shazam/LICENSE | 21 + pkg/identifier/shazam/api.go | 326 ++++ pkg/identifier/shazam/hanning.go | 2055 +++++++++++++++++++++++ pkg/identifier/shazam/signature.go | 242 +++ pkg/identifier/shazam/signature_test.go | 50 + pkg/ui/identify.go | 214 +++ pkg/ui/keys.go | 103 +- pkg/ui/layout.go | 2 +- pkg/ui/model.go | 33 + 15 files changed, 3456 insertions(+), 46 deletions(-) create mode 100644 cmd/test-shazam/main.go create mode 100644 pkg/identifier/capture.go create mode 100644 pkg/identifier/identifier.go create mode 100644 pkg/identifier/shazam/LICENSE create mode 100644 pkg/identifier/shazam/api.go create mode 100644 pkg/identifier/shazam/hanning.go create mode 100644 pkg/identifier/shazam/signature.go create mode 100644 pkg/identifier/shazam/signature_test.go create mode 100644 pkg/ui/identify.go diff --git a/.gitignore b/.gitignore index 9865b47..79ec360 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ go.work # Build artifacts /rig +/test-shazam /dist/ /build/ diff --git a/cmd/test-shazam/main.go b/cmd/test-shazam/main.go new file mode 100644 index 0000000..42e766e --- /dev/null +++ b/cmd/test-shazam/main.go @@ -0,0 +1,113 @@ +// Command test-shazam taps a live radio stream URL, fingerprints ~12 seconds +// of audio, and asks Shazam to identify the track. It exists so the +// identification pipeline can be smoke-tested end-to-end without booting the +// TUI. +// +// Usage: +// +// go run ./cmd/test-shazam [duration_seconds] +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "strconv" + "time" + + "github.com/mrwhyte/rig/pkg/identifier" + "github.com/mrwhyte/rig/pkg/identifier/shazam" +) + +func main() { + os.Exit(run()) +} + +func run() int { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s [duration_seconds]\n", os.Args[0]) + flag.PrintDefaults() + } + flag.Parse() + + if flag.NArg() < 1 { + flag.Usage() + return 2 + } + + streamURL := flag.Arg(0) + duration := identifier.DefaultSampleSeconds * time.Second + if flag.NArg() >= 2 { + secs, err := strconv.Atoi(flag.Arg(1)) + if err != nil || secs <= 0 { + fmt.Fprintf(os.Stderr, "invalid duration_seconds: %q\n", flag.Arg(1)) + return 2 + } + duration = time.Duration(secs) * time.Second + } + + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + + // Generous overall timeout: capture + network round-trip + Shazam rate limiter. + ctx, cancelTimeout := context.WithTimeout(ctx, duration+30*time.Second) + defer cancelTimeout() + + fmt.Fprintf(os.Stderr, "tapping %s for %s...\n", streamURL, duration) + + captureStart := time.Now() + samples, sampleRate, err := identifier.CaptureMonoSamples(ctx, streamURL, duration) + if err != nil { + fmt.Fprintf(os.Stderr, "capture error: %v\n", err) + return 1 + } + captureWall := time.Since(captureStart) + audioSeconds := float64(len(samples)) / float64(sampleRate) + fmt.Fprintf( + os.Stderr, + "captured %d samples at %d Hz (%.2fs of audio, wall time %s)\n", + len(samples), sampleRate, audioSeconds, captureWall.Round(time.Millisecond), + ) + if audioSeconds < float64(duration/time.Second)*0.9 { + fmt.Fprintf(os.Stderr, "warning: captured less audio than requested — stream may have closed early\n") + } + + resampled := identifier.Resample(samples, sampleRate, identifier.FingerprintSampleRate) + fmt.Fprintf( + os.Stderr, + "resampled to %d samples at %d Hz\n", + len(resampled), identifier.FingerprintSampleRate, + ) + + identifyStart := time.Now() + sig := shazam.ComputeSignature(identifier.FingerprintSampleRate, resampled) + result, err := shazam.Identify(ctx, sig) + if err != nil { + fmt.Fprintf(os.Stderr, "identify error: %v\n", err) + return 1 + } + fmt.Fprintf(os.Stderr, "shazam round trip %s\n", time.Since(identifyStart).Round(time.Millisecond)) + + if !result.Found { + fmt.Fprintln(os.Stderr, "no match") + return 1 + } + + fmt.Printf("Title: %s\n", result.Title) + fmt.Printf("Artist: %s\n", result.Artist) + if result.Album != "" { + fmt.Printf("Album: %s\n", result.Album) + } + if result.Year != "" { + fmt.Printf("Year: %s\n", result.Year) + } + if u := result.ShazamURL(); u != "" { + fmt.Printf("Shazam: %s\n", u) + } + if result.AppleID != "" { + fmt.Printf("AppleID: %s\n", result.AppleID) + } + return 0 +} diff --git a/go.mod b/go.mod index b49f3de..279d5a1 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,11 @@ require ( charm.land/bubbles/v2 v2.0.0 charm.land/bubbletea/v2 v2.0.1 charm.land/lipgloss/v2 v2.0.0 + github.com/google/uuid v1.6.0 + github.com/hajimehoshi/go-mp3 v0.3.4 github.com/sahilm/fuzzy v0.1.1 + golang.org/x/time v0.15.0 + gonum.org/v1/gonum v0.17.0 ) require ( diff --git a/go.sum b/go.sum index 1a90ac9..45a12e3 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ charm.land/bubbles/v2 v2.0.0 h1:tE3eK/pHjmtrDiRdoC9uGNLgpopOd8fjhEe31B/ai5s= charm.land/bubbles/v2 v2.0.0/go.mod h1:rCHoleP2XhU8um45NTuOWBPNVHxnkXKTiZqcclL/qOI= -charm.land/bubbletea/v2 v2.0.0 h1:p0d6CtWyJXJ9GfzMpUUqbP/XUUhhlk06+vCKWmox1wQ= -charm.land/bubbletea/v2 v2.0.0/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= charm.land/bubbletea/v2 v2.0.1 h1:B8e9zzK7x9JJ+XvHGF4xnYu9Xa0E0y0MyggY6dbaCfQ= charm.land/bubbletea/v2 v2.0.1/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo= @@ -14,8 +12,6 @@ github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA= -github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98= github.com/charmbracelet/ultraviolet v0.0.0-20260303162955-0b88c25f3fff h1:uY7A6hTokHPJBHfq7rj9Y/wm+IAjOghZTxKfVW6QLvw= github.com/charmbracelet/ultraviolet v0.0.0-20260303162955-0b88c25f3fff/go.mod h1:E6/0abq9uG2SnM8IbLB9Y5SW09uIgfaFETk8aRzgXUQ= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= @@ -32,6 +28,11 @@ github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSE github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68= +github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo= +github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= @@ -50,5 +51,10 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= diff --git a/pkg/identifier/capture.go b/pkg/identifier/capture.go new file mode 100644 index 0000000..d35638c --- /dev/null +++ b/pkg/identifier/capture.go @@ -0,0 +1,258 @@ +package identifier + +import ( + "bufio" + "context" + "encoding/binary" + "errors" + "fmt" + "io" + "mime" + "net/http" + "strings" + "time" + + "github.com/hajimehoshi/go-mp3" +) + +// ErrUnsupportedCodec is returned when the stream's Content-Type indicates an +// audio codec other than MP3. Track identification currently only supports +// MP3 streams; AAC and other codecs would need a different decoder. +var ErrUnsupportedCodec = errors.New("unsupported audio codec") + +// streamReadBufBytes is the size of the chunk we read at a time from the +// decoder. go-mp3 emits 16-bit stereo little-endian PCM (4 bytes per frame), +// so 4096 is exactly 1024 frames per read. +const streamReadBufBytes = 4096 + +// CaptureMonoSamples opens streamURL, decodes the next `duration` worth of +// MP3 audio, downmixes to mono and returns the samples normalised to [-1, 1] +// alongside the decoder's native sample rate. +// +// The samples are NOT resampled here; if you intend to feed them to +// shazam.ComputeSignature, run them through Resample first so the rate +// matches what Shazam's matcher expects (FingerprintSampleRate). +func CaptureMonoSamples(ctx context.Context, streamURL string, duration time.Duration) (samples []float64, sampleRate int, err error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, streamURL, http.NoBody) + if err != nil { + return nil, 0, fmt.Errorf("build request: %w", err) + } + // Ask the server not to interleave ICY metadata into the audio stream — + // most respect this and it keeps the MP3 frame boundaries clean. + req.Header.Set("Icy-MetaData", "0") + req.Header.Set("User-Agent", "rig/identifier") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, 0, fmt.Errorf("open stream: %w", err) + } + defer func() { _ = resp.Body.Close() }() + + if resp.StatusCode != http.StatusOK { + return nil, 0, fmt.Errorf("stream returned %s", resp.Status) + } + + // Reject obvious non-MP3 codecs up front so the user gets a clear + // "unsupported codec" error instead of a confusing "EOF" from go-mp3. + if ct := resp.Header.Get("Content-Type"); ct != "" && !isMP3ContentType(ct) { + return nil, 0, fmt.Errorf("%w: %s (only MP3 is supported)", ErrUnsupportedCodec, ct) + } + + // Live Shoutcast/Icecast streams hand us bytes mid-frame on connect, + // which makes go-mp3 fail with errors like "is_pos was too big". Wrap + // the body in a reader that scans forward to the first valid MP3 frame + // header before passing data through. + synced, err := newMP3SyncReader(resp.Body) + if err != nil { + return nil, 0, fmt.Errorf("sync mp3 stream: %w", err) + } + + dec, err := mp3.NewDecoder(synced) + if err != nil { + // Errors from mp3.NewDecoder almost always mean the stream is not + // an MP3 we can handle — wrong codec (AAC/Ogg), MPEG Layer I/II, + // or unrecognisable bytes after our sync scan. Surface them all as + // ErrUnsupportedCodec so the UI shows a clean message rather than + // a technical decoder error string. + return nil, 0, fmt.Errorf("%w: %s", ErrUnsupportedCodec, err.Error()) + } + + sampleRate = dec.SampleRate() + if sampleRate <= 0 || sampleRate > 192000 { + return nil, 0, fmt.Errorf("implausible stream sample rate: %d Hz", sampleRate) + } + + framesNeeded := int(duration.Seconds() * float64(sampleRate)) + samples = make([]float64, 0, framesNeeded) + + buf := make([]byte, streamReadBufBytes) + for len(samples) < framesNeeded { + n, readErr := dec.Read(buf) + if n > 0 { + n -= n % 4 // align to whole stereo frames + for i := 0; i+3 < n; i += 4 { + left := int16(binary.LittleEndian.Uint16(buf[i : i+2])) //nolint:gosec // G115: PCM frames are intentionally signed + right := int16(binary.LittleEndian.Uint16(buf[i+2 : i+4])) //nolint:gosec // G115: PCM frames are intentionally signed + samples = append(samples, (float64(left)+float64(right))/2/32768) + } + } + if readErr != nil { + if errors.Is(readErr, io.EOF) { + break + } + return nil, 0, fmt.Errorf("read mp3: %w", readErr) + } + } + + if len(samples) > framesNeeded { + samples = samples[:framesNeeded] + } + if len(samples) == 0 { + return nil, 0, errors.New("no audio decoded") + } + + return samples, sampleRate, nil +} + +// FingerprintSampleRate is the rate Shazam's matcher is tuned for. Feeding +// the algorithm at higher rates (e.g. 44100 Hz directly) is technically valid +// per the signature wire format, but produces sparse peaks in Shazam's +// 250-5500 Hz bands and fails to match real-world tracks. Resampling to +// 16 kHz before fingerprinting is what every working Shazam client does. +const FingerprintSampleRate = 16000 + +// Resample converts audio samples from srcRate to dstRate. For downsampling +// it averages over the source window to apply a crude anti-aliasing low-pass +// filter; for upsampling it uses linear interpolation. Quality is adequate +// for audio fingerprinting, where peak topology matters more than fidelity. +// +// If srcRate == dstRate, the input slice is returned unchanged. +func Resample(in []float64, srcRate, dstRate int) []float64 { + if srcRate == dstRate || len(in) == 0 { + return in + } + ratio := float64(srcRate) / float64(dstRate) + outLen := int(float64(len(in)) / ratio) + if outLen <= 0 { + return nil + } + out := make([]float64, outLen) + + if ratio > 1 { + // Downsampling: boxcar-averaged decimation. + window := int(ratio + 0.5) + if window < 2 { + window = 2 + } + for i := range out { + srcStart := int(float64(i) * ratio) + if srcStart >= len(in) { + break + } + srcEnd := srcStart + window + if srcEnd > len(in) { + srcEnd = len(in) + } + sum := 0.0 + for j := srcStart; j < srcEnd; j++ { + sum += in[j] + } + out[i] = sum / float64(srcEnd-srcStart) + } + return out + } + + // Upsampling: linear interpolation. + for i := range out { + srcF := float64(i) * ratio + srcI := int(srcF) + frac := srcF - float64(srcI) + switch { + case srcI+1 < len(in): + out[i] = in[srcI]*(1-frac) + in[srcI+1]*frac + case srcI < len(in): + out[i] = in[srcI] + } + } + return out +} + +// mp3SyncScanLimit is how many bytes we'll scan from the start of a stream +// looking for the first valid MP3 frame header before giving up. +const mp3SyncScanLimit = 1 << 16 // 64 KiB + +// mp3SyncReader wraps an io.Reader and skips past any leading bytes that +// don't begin a valid MP3 frame header. Used to recover from connecting to +// a live Shoutcast/Icecast stream mid-frame. +type mp3SyncReader struct { + br *bufio.Reader +} + +// isMP3ContentType reports whether the HTTP Content-Type advertises an MP3 +// stream. Servers vary in exact spelling (audio/mpeg, audio/mp3, audio/MPA). +func isMP3ContentType(ct string) bool { + mt, _, err := mime.ParseMediaType(ct) + if err != nil { + mt = strings.ToLower(strings.TrimSpace(ct)) + } + switch mt { + case "audio/mpeg", "audio/mp3", "audio/x-mpeg", "audio/mpa", "audio/mpa-robust": + return true + } + return false +} + +// isValidMP3Header returns true if h looks like a real MP3 frame header. +// Loose sync (byte 0 == 0xFF, byte 1 top 3 bits set) gets a lot of false +// positives in ICY metadata and ID3 tags; we additionally reject the +// reserved version, reserved layer, "bad" bitrate index, and reserved +// sample-rate index, which never appear in real audio. +func isValidMP3Header(h []byte) bool { + if len(h) < 3 { + return false + } + if h[0] != 0xFF { + return false + } + if h[1]&0xE0 != 0xE0 { + return false + } + if h[1]&0x18 == 0x08 { // version bits == 01: reserved + return false + } + if h[1]&0x06 == 0x00 { // layer bits == 00: reserved + return false + } + if h[2]&0xF0 == 0xF0 { // bitrate index == 1111: bad + return false + } + if h[2]&0x0C == 0x0C { // sample-rate index == 11: reserved + return false + } + return true +} + +// newMP3SyncReader scans bytes from r until it finds an MP3 frame header +// that passes isValidMP3Header, then returns a reader positioned at that +// byte. Bytes are inspected via Peek so they stay buffered for the decoder. +func newMP3SyncReader(r io.Reader) (*mp3SyncReader, error) { + br := bufio.NewReaderSize(r, 4096) + for scanned := 0; scanned < mp3SyncScanLimit; scanned++ { + head, err := br.Peek(3) + if err != nil { + return nil, fmt.Errorf("peek while seeking sync: %w", err) + } + if isValidMP3Header(head) { + return &mp3SyncReader{br: br}, nil + } + if _, err := br.ReadByte(); err != nil { + return nil, fmt.Errorf("discard while seeking sync: %w", err) + } + } + return nil, fmt.Errorf("no MP3 sync in first %d bytes", mp3SyncScanLimit) +} + +// Read implements io.Reader by delegating to the buffered reader. +func (s *mp3SyncReader) Read(p []byte) (int, error) { + return s.br.Read(p) +} diff --git a/pkg/identifier/identifier.go b/pkg/identifier/identifier.go new file mode 100644 index 0000000..9f335d0 --- /dev/null +++ b/pkg/identifier/identifier.go @@ -0,0 +1,66 @@ +// Package identifier identifies tracks playing on internet radio streams by +// tapping the stream's audio, computing a Shazam fingerprint locally, and +// querying Shazam's recognition endpoint. +package identifier + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/mrwhyte/rig/pkg/identifier/shazam" +) + +// DefaultSampleSeconds is the amount of audio captured for one recognition +// attempt. Shazam typically resolves a track from 8-12 seconds of audio. +const DefaultSampleSeconds = 12 + +// Track is what a successful identification returns to a caller. +type Track struct { + Title string + Artist string + Album string + Year string + ShazamURL string // canonical Shazam track URL, empty if Shazam returned no key + AppleID string // Apple Music track ID, empty if absent +} + +// ErrNoMatch is returned when Shazam responds successfully but cannot identify +// the audio (silence, talk, an unrecognised song). +var ErrNoMatch = errors.New("no shazam match") + +// IdentifyStream captures DefaultSampleSeconds of audio from streamURL, +// fingerprints it, and asks Shazam to identify the track. It returns +// ErrNoMatch if Shazam responds with no matches. +func IdentifyStream(ctx context.Context, streamURL string) (*Track, error) { + return IdentifyStreamFor(ctx, streamURL, DefaultSampleSeconds*time.Second) +} + +// IdentifyStreamFor is the variant of IdentifyStream that lets the caller pick +// the capture duration. Shorter durations are faster but less accurate. +func IdentifyStreamFor(ctx context.Context, streamURL string, duration time.Duration) (*Track, error) { + samples, sampleRate, err := CaptureMonoSamples(ctx, streamURL, duration) + if err != nil { + return nil, fmt.Errorf("capture: %w", err) + } + + resampled := Resample(samples, sampleRate, FingerprintSampleRate) + sig := shazam.ComputeSignature(FingerprintSampleRate, resampled) + result, err := shazam.Identify(ctx, sig) + if err != nil { + return nil, fmt.Errorf("identify: %w", err) + } + if !result.Found { + return nil, ErrNoMatch + } + + return &Track{ + Title: result.Title, + Artist: result.Artist, + Album: result.Album, + Year: result.Year, + ShazamURL: result.ShazamURL(), + AppleID: result.AppleID, + }, nil +} diff --git a/pkg/identifier/shazam/LICENSE b/pkg/identifier/shazam/LICENSE new file mode 100644 index 0000000..0887c7c --- /dev/null +++ b/pkg/identifier/shazam/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024 Luke Champine + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/pkg/identifier/shazam/api.go b/pkg/identifier/shazam/api.go new file mode 100644 index 0000000..786227b --- /dev/null +++ b/pkg/identifier/shazam/api.go @@ -0,0 +1,326 @@ +// This file is vendored from https://github.com/lukechampine/barbershop +// Original copyright (c) 2024 Luke Champine, MIT licensed (see LICENSE). +// +// Modifications for rig: +// - Identify now takes a context.Context for cancellation. +// - Result exposes the Shazam track Key so callers can build a Shazam URL. +// - Replaced math/rand with math/rand/v2 for the user-agent picker. +// - Replaced goto-based retry with a bounded loop. +// - Added http.NewRequestWithContext and explicit error handling throughout. + +package shazam + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "math/rand/v2" + "net/http" + "os" + "strings" + "time" + + "github.com/google/uuid" + "golang.org/x/time/rate" +) + +// debugEnabled returns true when RIG_SHAZAM_DEBUG=1 in the environment. When +// enabled, postSignature dumps the raw request body and response body to +// stderr so we can diagnose why Shazam is returning no matches. +func debugEnabled() bool { + return os.Getenv("RIG_SHAZAM_DEBUG") == "1" +} + +// Shared rate limiter so we don't hammer Shazam and earn a ban. +var throttle = rate.NewLimiter(rate.Every(3*time.Second), 1) + +// Result contains the outcome of attempting to identify a song. +type Result struct { + Found bool + Artist string + Title string + Album string + Year string + AppleID string + Key string // Shazam track key, used to build https://www.shazam.com/track/ +} + +// ShazamURL returns the canonical Shazam track URL, or an empty string if the +// result does not carry a track key. +func (r Result) ShazamURL() string { + if r.Key == "" { + return "" + } + return "https://www.shazam.com/track/" + r.Key +} + +const ( + endpointHost = "amp.shazam.com" + endpointPath = "/discovery/v5/en/US/android/-/tag" + endpointQuery = "?sync=true&webv3=true&sampling=true&connected=&shazamapiversion=v3&sharehub=true&video=v3" +) + +// Identify sends the given signature to Shazam and returns the recognised +// track, or a Result with Found == false if no match was made. +func Identify(ctx context.Context, sig Signature) (Result, error) { + body, err := buildRequestBody(sig) + if err != nil { + return Result{}, fmt.Errorf("build request body: %w", err) + } + + reqURL := fmt.Sprintf( + "http://%s%s/%s/%s%s", + endpointHost, + endpointPath, + strings.ToUpper(uuid.NewString()), + uuid.NewString(), + endpointQuery, + ) + + respData, err := postSignature(ctx, reqURL, body) + if err != nil { + return Result{}, err + } + if len(respData.Matches) == 0 { + return Result{Found: false}, nil + } + + album, year := "", "" + for _, section := range respData.Track.Sections { + for _, meta := range section.Metadata { + switch meta.Title { + case "Album": + album = meta.Text + case "Released", "Sortie": + year = meta.Text + } + } + } + appleID := "" + for _, action := range respData.Track.Hub.Actions { + if action.Name == "apple" && action.ID != "" { + appleID = action.ID + break + } + } + + return Result{ + Found: true, + Artist: respData.Track.Subtitle, + Title: respData.Track.Title, + Album: album, + Year: year, + AppleID: appleID, + Key: respData.Track.Key, + }, nil +} + +func buildRequestBody(sig Signature) ([]byte, error) { + now := time.Now().UnixMilli() + payload := map[string]any{ + "geolocation": map[string]any{ + "altitude": 300, + "latitude": 45, + "longitude": 2, + }, + "signature": map[string]any{ + "samplems": sig.numSamples / sig.sampleRate * 1000, + "timestamp": now, + "uri": "data:audio/vnd.shazam.sig;base64," + base64.StdEncoding.EncodeToString(sig.encode()), + }, + "timestamp": now, + "timezone": "Europe/Berlin", + } + return json.Marshal(payload) +} + +type shazamResponse struct { + Matches []struct { + ID string + Offset float64 + TimeSkew float64 + FrequencySkew float64 + } + Track struct { + Title string + Subtitle string + Key string + Hub struct { + Actions []struct { + Name string + ID string + } + } + Sections []struct { + Type string + Metadata []struct { + Title string + Text string + } + } + } +} + +const maxRetries = 3 + +func postSignature(ctx context.Context, reqURL string, body []byte) (*shazamResponse, error) { + debug := debugEnabled() + if debug { + fmt.Fprintf(os.Stderr, "[shazam] POST %s\n", reqURL) + fmt.Fprintf(os.Stderr, "[shazam] request body: %s\n", string(body)) + } + + var lastErr error + for attempt := 0; attempt < maxRetries; attempt++ { + if err := throttle.Wait(ctx); err != nil { + return nil, fmt.Errorf("throttle: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, bytes.NewReader(body)) + if err != nil { + return nil, fmt.Errorf("build request: %w", err) + } + ua := pickUserAgent() + req.Header.Set("User-Agent", ua) + req.Header.Set("Content-Language", "en_US") + req.Header.Set("Content-Type", "application/json") + if debug { + fmt.Fprintf(os.Stderr, "[shazam] User-Agent: %s\n", ua) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, fmt.Errorf("do request: %w", err) + } + + respBody, readErr := io.ReadAll(resp.Body) + _ = resp.Body.Close() + if debug { + fmt.Fprintf(os.Stderr, "[shazam] response status: %s\n", resp.Status) + fmt.Fprintf(os.Stderr, "[shazam] response body (%d bytes): %s\n", len(respBody), string(respBody)) + } + if readErr != nil { + return nil, fmt.Errorf("read response: %w", readErr) + } + + switch resp.StatusCode { + case http.StatusOK: + var out shazamResponse + if err := json.Unmarshal(respBody, &out); err != nil { + return nil, fmt.Errorf("decode response: %w", err) + } + return &out, nil + case http.StatusTooManyRequests: + lastErr = fmt.Errorf("rate limited by shazam") + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(3 * time.Second): + } + default: + return nil, fmt.Errorf("bad status: %s (%s)", resp.Status, string(respBody)) + } + } + return nil, lastErr +} + +func pickUserAgent() string { + // Picking a UA string is not a security-sensitive decision; math/rand/v2 is fine. + return userAgents[rand.IntN(len(userAgents))] //nolint:gosec // G404: non-crypto use +} + +// userAgents is a pool of Android Dalvik user agents used to look like a +// regular mobile Shazam client. Picked at random per request. +var userAgents = []string{ + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; VS980 4G Build/LRX22G)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-T210 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-P905V Build/LMY47X)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; Vodafone Smart Tab 4G Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-G360H Build/KTU84P)", + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; SM-S920L Build/LRX22G)", + "Dalvik/2.1.0 (Linux; U; Android 5.0; Fire Pro Build/LRX21M)", + "Dalvik/2.1.0 (Linux; U; Android 5.0; SM-N9005 Build/LRX21V)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G920F Build/MMB29K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G7102 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.0; SM-G900F Build/LRX21T)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G928F Build/MMB29K)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-J500FN Build/LMY48B)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; Coolpad 3320A Build/LMY47V)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-J110F Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SAMSUNG-SGH-I747 Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SAMSUNG-SM-T337A Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.3; SGH-T999 Build/JSS15J)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; D6603 Build/23.5.A.0.570)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-J700H Build/LMY48B)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; HTC6600LVW Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-N910G Build/LMY47X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-N910T Build/LMY47X)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; C6903 Build/14.4.A.0.157)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.2; GT-I9105P Build/JDQ39)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-I9192 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G531H Build/LMY48B)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; LGMS345 Build/LMY47V)", + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; HTC One Build/LRX22G)", + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; LG-D800 Build/LRX22G)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-T113 Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.2; AndyWin Build/JDQ39E)", + "Dalvik/2.1.0 (Linux; U; Android 5.0; Lenovo A7000-a Build/LRX21M)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; LGL16C Build/KOT49I.L16CV11a)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-I9500 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; SM-A700FD Build/LRX22G)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G130HN Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-N9005 Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.1.2; LG-E975T Build/JZO54K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; E1 Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-N5100 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-A310F Build/LMY47X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-J105H Build/LMY47V)", + "Dalvik/1.6.0 (Linux; U; Android 4.3; GT-I9305T Build/JSS15J)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; android Build/JDQ39)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.1; HS-U970 Build/JOP40D)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-T561 Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.2; GT-P3110 Build/JDQ39)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G925T Build/MMB29K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; HUAWEI Y221-U22 Build/HUAWEIY221-U22)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G530T1 Build/LMY47X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G920I Build/LMY47X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; Vodafone Smart ultra 6 Build/LMY47V)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; XT1080 Build/SU6-7.7)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; ASUS MeMO Pad 7 Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G800F Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-N7100 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G925I Build/MMB29K)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; A0001 Build/MMB29X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1; XT1045 Build/LPB23.13-61)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; LGMS330 Build/LMY47V)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; Z970 Build/KTU84P)", + "Dalvik/2.1.0 (Linux; U; Android 5.0; SM-N900P Build/LRX21V)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; T1-701u Build/HuaweiMediaPad)", + "Dalvik/2.1.0 (Linux; U; Android 5.1; HTCD100LVWPP Build/LMY47O)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G935R4 Build/MMB29M)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G930V Build/MMB29M)", + "Dalvik/2.1.0 (Linux; U; Android 5.0.2; ZTE Blade Q Lux Build/LRX22G)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; GT-I9060I Build/KTU84P)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; LGUS992 Build/MMB29M)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G900P Build/MMB29M)", + "Dalvik/1.6.0 (Linux; U; Android 4.1.2; SGH-T999L Build/JZO54K)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-N910V Build/LMY47X)", + "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-P601 Build/LMY47X)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.2; GT-S7272 Build/JDQ39)", + "Dalvik/1.6.0 (Linux; U; Android 4.3; SAMSUNG-SGH-I747 Build/JSS15J)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G930F Build/MMB29K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; HTC_PO582 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 6.0; HUAWEI MT7-TL10 Build/HuaweiMT7-TL10)", + "Dalvik/2.1.0 (Linux; U; Android 6.0; LG-H811 Build/MRA58K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-N7505 Build/KOT49H)", + "Dalvik/2.1.0 (Linux; U; Android 6.0; LG-H815 Build/MRA58K)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.2; LenovoA3300-HV Build/KOT49H)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-G360G Build/KTU84P)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; GT-I9300I Build/KTU84P)", + "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-J700T Build/MMB29K)", + "Dalvik/1.6.0 (Linux; U; Android 4.2.2; SM-T217S Build/JDQ39)", + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SAMSUNG-SM-N900A Build/KTU84P)", +} diff --git a/pkg/identifier/shazam/hanning.go b/pkg/identifier/shazam/hanning.go new file mode 100644 index 0000000..f31b7f3 --- /dev/null +++ b/pkg/identifier/shazam/hanning.go @@ -0,0 +1,2055 @@ +// This file is vendored from https://github.com/lukechampine/barbershop +// Original copyright (c) 2024 Luke Champine, MIT licensed (see LICENSE). + +package shazam + +var hanningMultipliers = [2048]float64{ + 0.0000023508, + 0.0000094032, + 0.000021157, + 0.000037612, + 0.000058769, + 0.000084626, + 0.00011518, + 0.00015044, + 0.0001904, + 0.00023506, + 0.00028442, + 0.00033848, + 0.00039723, + 0.00046069, + 0.00052884, + 0.00060168, + 0.00067923, + 0.00076147, + 0.0008484, + 0.00094003, + 0.0010363, + 0.0011374, + 0.0012431, + 0.0013535, + 0.0014685, + 0.0015883, + 0.0017128, + 0.0018419, + 0.0019757, + 0.0021142, + 0.0022574, + 0.0024053, + 0.0025578, + 0.0027151, + 0.002877, + 0.0030435, + 0.0032148, + 0.0033907, + 0.0035713, + 0.0037566, + 0.0039465, + 0.0041411, + 0.0043403, + 0.0045443, + 0.0047528, + 0.0049661, + 0.0051839, + 0.0054065, + 0.0056337, + 0.0058655, + 0.006102, + 0.0063431, + 0.0065889, + 0.0068393, + 0.0070943, + 0.007354, + 0.0076183, + 0.0078873, + 0.0081608, + 0.008439, + 0.0087219, + 0.0090093, + 0.0093013, + 0.009598, + 0.0098993, + 0.010205, + 0.010516, + 0.010831, + 0.01115, + 0.011475, + 0.011804, + 0.012137, + 0.012475, + 0.012818, + 0.013165, + 0.013517, + 0.013873, + 0.014234, + 0.0146, + 0.01497, + 0.015344, + 0.015724, + 0.016107, + 0.016496, + 0.016889, + 0.017286, + 0.017688, + 0.018094, + 0.018505, + 0.018921, + 0.019341, + 0.019766, + 0.020195, + 0.020628, + 0.021066, + 0.021509, + 0.021956, + 0.022408, + 0.022864, + 0.023324, + 0.023789, + 0.024259, + 0.024733, + 0.025211, + 0.025694, + 0.026182, + 0.026674, + 0.02717, + 0.027671, + 0.028176, + 0.028686, + 0.0292, + 0.029718, + 0.030241, + 0.030768, + 0.0313, + 0.031836, + 0.032377, + 0.032922, + 0.033471, + 0.034025, + 0.034583, + 0.035146, + 0.035712, + 0.036284, + 0.036859, + 0.037439, + 0.038024, + 0.038612, + 0.039205, + 0.039803, + 0.040404, + 0.04101, + 0.04162, + 0.042235, + 0.042854, + 0.043477, + 0.044105, + 0.044736, + 0.045372, + 0.046013, + 0.046657, + 0.047306, + 0.047959, + 0.048617, + 0.049278, + 0.049944, + 0.050614, + 0.051288, + 0.051967, + 0.05265, + 0.053337, + 0.054028, + 0.054723, + 0.055423, + 0.056126, + 0.056834, + 0.057546, + 0.058263, + 0.058983, + 0.059707, + 0.060436, + 0.061169, + 0.061906, + 0.062647, + 0.063392, + 0.064141, + 0.064895, + 0.065652, + 0.066413, + 0.067179, + 0.067949, + 0.068722, + 0.0695, + 0.070282, + 0.071068, + 0.071858, + 0.072652, + 0.07345, + 0.074252, + 0.075058, + 0.075868, + 0.076682, + 0.0775, + 0.078321, + 0.079147, + 0.079977, + 0.080811, + 0.081649, + 0.08249, + 0.083336, + 0.084185, + 0.085039, + 0.085896, + 0.086757, + 0.087622, + 0.088491, + 0.089364, + 0.090241, + 0.091121, + 0.092006, + 0.092894, + 0.093786, + 0.094682, + 0.095582, + 0.096485, + 0.097392, + 0.098303, + 0.099218, + 0.10014, + 0.10106, + 0.10199, + 0.10292, + 0.10385, + 0.10479, + 0.10573, + 0.10667, + 0.10762, + 0.10857, + 0.10953, + 0.11049, + 0.11145, + 0.11242, + 0.11339, + 0.11436, + 0.11534, + 0.11632, + 0.11731, + 0.1183, + 0.11929, + 0.12028, + 0.12128, + 0.12228, + 0.12329, + 0.1243, + 0.12531, + 0.12633, + 0.12735, + 0.12838, + 0.1294, + 0.13043, + 0.13147, + 0.13251, + 0.13355, + 0.13459, + 0.13564, + 0.13669, + 0.13775, + 0.13881, + 0.13987, + 0.14093, + 0.142, + 0.14307, + 0.14415, + 0.14523, + 0.14631, + 0.1474, + 0.14849, + 0.14958, + 0.15067, + 0.15177, + 0.15287, + 0.15398, + 0.15509, + 0.1562, + 0.15731, + 0.15843, + 0.15955, + 0.16068, + 0.1618, + 0.16294, + 0.16407, + 0.16521, + 0.16635, + 0.16749, + 0.16864, + 0.16979, + 0.17094, + 0.1721, + 0.17325, + 0.17442, + 0.17558, + 0.17675, + 0.17792, + 0.1791, + 0.18027, + 0.18145, + 0.18264, + 0.18382, + 0.18501, + 0.1862, + 0.1874, + 0.1886, + 0.1898, + 0.191, + 0.19221, + 0.19342, + 0.19463, + 0.19585, + 0.19707, + 0.19829, + 0.19951, + 0.20074, + 0.20197, + 0.2032, + 0.20444, + 0.20567, + 0.20691, + 0.20816, + 0.2094, + 0.21065, + 0.2119, + 0.21316, + 0.21442, + 0.21568, + 0.21694, + 0.2182, + 0.21947, + 0.22074, + 0.22202, + 0.22329, + 0.22457, + 0.22585, + 0.22713, + 0.22842, + 0.22971, + 0.231, + 0.23229, + 0.23359, + 0.23489, + 0.23619, + 0.23749, + 0.2388, + 0.24011, + 0.24142, + 0.24273, + 0.24405, + 0.24537, + 0.24669, + 0.24801, + 0.24934, + 0.25066, + 0.25199, + 0.25333, + 0.25466, + 0.256, + 0.25734, + 0.25868, + 0.26002, + 0.26137, + 0.26272, + 0.26407, + 0.26542, + 0.26678, + 0.26813, + 0.26949, + 0.27086, + 0.27222, + 0.27359, + 0.27495, + 0.27632, + 0.2777, + 0.27907, + 0.28045, + 0.28183, + 0.28321, + 0.28459, + 0.28597, + 0.28736, + 0.28875, + 0.29014, + 0.29153, + 0.29293, + 0.29432, + 0.29572, + 0.29712, + 0.29852, + 0.29993, + 0.30133, + 0.30274, + 0.30415, + 0.30556, + 0.30698, + 0.30839, + 0.30981, + 0.31123, + 0.31265, + 0.31407, + 0.3155, + 0.31692, + 0.31835, + 0.31978, + 0.32121, + 0.32264, + 0.32408, + 0.32551, + 0.32695, + 0.32839, + 0.32983, + 0.33127, + 0.33272, + 0.33416, + 0.33561, + 0.33706, + 0.33851, + 0.33996, + 0.34141, + 0.34287, + 0.34433, + 0.34578, + 0.34724, + 0.3487, + 0.35017, + 0.35163, + 0.35309, + 0.35456, + 0.35603, + 0.3575, + 0.35897, + 0.36044, + 0.36191, + 0.36339, + 0.36486, + 0.36634, + 0.36782, + 0.3693, + 0.37078, + 0.37226, + 0.37374, + 0.37522, + 0.37671, + 0.3782, + 0.37968, + 0.38117, + 0.38266, + 0.38415, + 0.38565, + 0.38714, + 0.38863, + 0.39013, + 0.39162, + 0.39312, + 0.39462, + 0.39612, + 0.39762, + 0.39912, + 0.40062, + 0.40213, + 0.40363, + 0.40513, + 0.40664, + 0.40815, + 0.40965, + 0.41116, + 0.41267, + 0.41418, + 0.41569, + 0.41721, + 0.41872, + 0.42023, + 0.42174, + 0.42326, + 0.42478, + 0.42629, + 0.42781, + 0.42933, + 0.43084, + 0.43236, + 0.43388, + 0.4354, + 0.43692, + 0.43844, + 0.43997, + 0.44149, + 0.44301, + 0.44453, + 0.44606, + 0.44758, + 0.44911, + 0.45063, + 0.45216, + 0.45369, + 0.45521, + 0.45674, + 0.45827, + 0.4598, + 0.46132, + 0.46285, + 0.46438, + 0.46591, + 0.46744, + 0.46897, + 0.4705, + 0.47203, + 0.47356, + 0.4751, + 0.47663, + 0.47816, + 0.47969, + 0.48122, + 0.48275, + 0.48429, + 0.48582, + 0.48735, + 0.48888, + 0.49042, + 0.49195, + 0.49348, + 0.49502, + 0.49655, + 0.49808, + 0.49962, + 0.50115, + 0.50268, + 0.50422, + 0.50575, + 0.50728, + 0.50882, + 0.51035, + 0.51188, + 0.51341, + 0.51495, + 0.51648, + 0.51801, + 0.51954, + 0.52108, + 0.52261, + 0.52414, + 0.52567, + 0.5272, + 0.52873, + 0.53026, + 0.53179, + 0.53332, + 0.53485, + 0.53638, + 0.53791, + 0.53944, + 0.54097, + 0.5425, + 0.54402, + 0.54555, + 0.54708, + 0.5486, + 0.55013, + 0.55165, + 0.55318, + 0.5547, + 0.55623, + 0.55775, + 0.55927, + 0.5608, + 0.56232, + 0.56384, + 0.56536, + 0.56688, + 0.5684, + 0.56992, + 0.57143, + 0.57295, + 0.57447, + 0.57598, + 0.5775, + 0.57901, + 0.58053, + 0.58204, + 0.58355, + 0.58506, + 0.58657, + 0.58808, + 0.58959, + 0.5911, + 0.59261, + 0.59411, + 0.59562, + 0.59712, + 0.59863, + 0.60013, + 0.60163, + 0.60313, + 0.60463, + 0.60613, + 0.60763, + 0.60912, + 0.61062, + 0.61211, + 0.61361, + 0.6151, + 0.61659, + 0.61808, + 0.61957, + 0.62106, + 0.62255, + 0.62403, + 0.62552, + 0.627, + 0.62848, + 0.62996, + 0.63144, + 0.63292, + 0.6344, + 0.63588, + 0.63735, + 0.63883, + 0.6403, + 0.64177, + 0.64324, + 0.64471, + 0.64617, + 0.64764, + 0.6491, + 0.65057, + 0.65203, + 0.65349, + 0.65495, + 0.6564, + 0.65786, + 0.65931, + 0.66077, + 0.66222, + 0.66367, + 0.66511, + 0.66656, + 0.668, + 0.66945, + 0.67089, + 0.67233, + 0.67377, + 0.67521, + 0.67664, + 0.67807, + 0.67951, + 0.68094, + 0.68236, + 0.68379, + 0.68522, + 0.68664, + 0.68806, + 0.68948, + 0.6909, + 0.69232, + 0.69373, + 0.69514, + 0.69655, + 0.69796, + 0.69937, + 0.70077, + 0.70218, + 0.70358, + 0.70498, + 0.70638, + 0.70777, + 0.70916, + 0.71056, + 0.71195, + 0.71333, + 0.71472, + 0.7161, + 0.71748, + 0.71886, + 0.72024, + 0.72162, + 0.72299, + 0.72436, + 0.72573, + 0.7271, + 0.72846, + 0.72983, + 0.73119, + 0.73254, + 0.7339, + 0.73525, + 0.73661, + 0.73796, + 0.7393, + 0.74065, + 0.74199, + 0.74333, + 0.74467, + 0.74601, + 0.74734, + 0.74867, + 0.75, + 0.75133, + 0.75265, + 0.75397, + 0.75529, + 0.75661, + 0.75792, + 0.75924, + 0.76055, + 0.76185, + 0.76316, + 0.76446, + 0.76576, + 0.76706, + 0.76835, + 0.76965, + 0.77094, + 0.77222, + 0.77351, + 0.77479, + 0.77607, + 0.77735, + 0.77862, + 0.77989, + 0.78116, + 0.78243, + 0.78369, + 0.78495, + 0.78621, + 0.78747, + 0.78872, + 0.78997, + 0.79122, + 0.79246, + 0.79371, + 0.79495, + 0.79618, + 0.79742, + 0.79865, + 0.79988, + 0.8011, + 0.80232, + 0.80354, + 0.80476, + 0.80597, + 0.80719, + 0.80839, + 0.8096, + 0.8108, + 0.812, + 0.8132, + 0.81439, + 0.81558, + 0.81677, + 0.81796, + 0.81914, + 0.82032, + 0.82149, + 0.82266, + 0.82383, + 0.825, + 0.82616, + 0.82732, + 0.82848, + 0.82964, + 0.83079, + 0.83194, + 0.83308, + 0.83422, + 0.83536, + 0.8365, + 0.83763, + 0.83876, + 0.83989, + 0.84101, + 0.84213, + 0.84324, + 0.84436, + 0.84547, + 0.84657, + 0.84768, + 0.84878, + 0.84988, + 0.85097, + 0.85206, + 0.85315, + 0.85423, + 0.85531, + 0.85639, + 0.85746, + 0.85853, + 0.8596, + 0.86066, + 0.86172, + 0.86278, + 0.86383, + 0.86488, + 0.86593, + 0.86697, + 0.86801, + 0.86905, + 0.87008, + 0.87111, + 0.87214, + 0.87316, + 0.87418, + 0.87519, + 0.8762, + 0.87721, + 0.87822, + 0.87922, + 0.88022, + 0.88121, + 0.8822, + 0.88319, + 0.88417, + 0.88515, + 0.88613, + 0.8871, + 0.88807, + 0.88903, + 0.88999, + 0.89095, + 0.8919, + 0.89285, + 0.8938, + 0.89474, + 0.89568, + 0.89662, + 0.89755, + 0.89848, + 0.8994, + 0.90032, + 0.90124, + 0.90215, + 0.90306, + 0.90397, + 0.90487, + 0.90577, + 0.90666, + 0.90755, + 0.90844, + 0.90932, + 0.9102, + 0.91107, + 0.91194, + 0.91281, + 0.91367, + 0.91453, + 0.91539, + 0.91624, + 0.91709, + 0.91793, + 0.91877, + 0.91961, + 0.92044, + 0.92127, + 0.92209, + 0.92291, + 0.92373, + 0.92454, + 0.92535, + 0.92615, + 0.92695, + 0.92775, + 0.92854, + 0.92933, + 0.93011, + 0.93089, + 0.93166, + 0.93244, + 0.9332, + 0.93397, + 0.93473, + 0.93548, + 0.93623, + 0.93698, + 0.93772, + 0.93846, + 0.9392, + 0.93993, + 0.94066, + 0.94138, + 0.9421, + 0.94281, + 0.94352, + 0.94423, + 0.94493, + 0.94563, + 0.94632, + 0.94701, + 0.94769, + 0.94837, + 0.94905, + 0.94972, + 0.95039, + 0.95105, + 0.95171, + 0.95237, + 0.95302, + 0.95367, + 0.95431, + 0.95495, + 0.95558, + 0.95621, + 0.95684, + 0.95746, + 0.95807, + 0.95869, + 0.95929, + 0.9599, + 0.9605, + 0.96109, + 0.96168, + 0.96227, + 0.96285, + 0.96343, + 0.964, + 0.96457, + 0.96514, + 0.9657, + 0.96625, + 0.9668, + 0.96735, + 0.96789, + 0.96843, + 0.96897, + 0.9695, + 0.97002, + 0.97054, + 0.97106, + 0.97157, + 0.97208, + 0.97258, + 0.97308, + 0.97357, + 0.97406, + 0.97455, + 0.97503, + 0.9755, + 0.97598, + 0.97644, + 0.97691, + 0.97736, + 0.97782, + 0.97827, + 0.97871, + 0.97915, + 0.97959, + 0.98002, + 0.98045, + 0.98087, + 0.98129, + 0.9817, + 0.98211, + 0.98251, + 0.98291, + 0.98331, + 0.9837, + 0.98409, + 0.98447, + 0.98484, + 0.98522, + 0.98558, + 0.98595, + 0.98631, + 0.98666, + 0.98701, + 0.98735, + 0.98769, + 0.98803, + 0.98836, + 0.98869, + 0.98901, + 0.98933, + 0.98964, + 0.98995, + 0.99025, + 0.99055, + 0.99085, + 0.99114, + 0.99142, + 0.9917, + 0.99198, + 0.99225, + 0.99251, + 0.99278, + 0.99303, + 0.99329, + 0.99353, + 0.99378, + 0.99402, + 0.99425, + 0.99448, + 0.99471, + 0.99493, + 0.99514, + 0.99535, + 0.99556, + 0.99576, + 0.99596, + 0.99615, + 0.99634, + 0.99652, + 0.9967, + 0.99687, + 0.99704, + 0.9972, + 0.99736, + 0.99752, + 0.99767, + 0.99781, + 0.99796, + 0.99809, + 0.99822, + 0.99835, + 0.99847, + 0.99859, + 0.9987, + 0.99881, + 0.99891, + 0.99901, + 0.99911, + 0.9992, + 0.99928, + 0.99936, + 0.99944, + 0.99951, + 0.99957, + 0.99963, + 0.99969, + 0.99974, + 0.99979, + 0.99983, + 0.99987, + 0.9999, + 0.99993, + 0.99995, + 0.99997, + 0.99999, + 0.99999, + 1.0, + 1.0, + 0.99999, + 0.99999, + 0.99997, + 0.99995, + 0.99993, + 0.9999, + 0.99987, + 0.99983, + 0.99979, + 0.99974, + 0.99969, + 0.99963, + 0.99957, + 0.99951, + 0.99944, + 0.99936, + 0.99928, + 0.9992, + 0.99911, + 0.99901, + 0.99891, + 0.99881, + 0.9987, + 0.99859, + 0.99847, + 0.99835, + 0.99822, + 0.99809, + 0.99796, + 0.99781, + 0.99767, + 0.99752, + 0.99736, + 0.9972, + 0.99704, + 0.99687, + 0.9967, + 0.99652, + 0.99634, + 0.99615, + 0.99596, + 0.99576, + 0.99556, + 0.99535, + 0.99514, + 0.99493, + 0.99471, + 0.99448, + 0.99425, + 0.99402, + 0.99378, + 0.99353, + 0.99329, + 0.99303, + 0.99278, + 0.99251, + 0.99225, + 0.99198, + 0.9917, + 0.99142, + 0.99114, + 0.99085, + 0.99055, + 0.99025, + 0.98995, + 0.98964, + 0.98933, + 0.98901, + 0.98869, + 0.98836, + 0.98803, + 0.98769, + 0.98735, + 0.98701, + 0.98666, + 0.98631, + 0.98595, + 0.98558, + 0.98522, + 0.98484, + 0.98447, + 0.98409, + 0.9837, + 0.98331, + 0.98291, + 0.98251, + 0.98211, + 0.9817, + 0.98129, + 0.98087, + 0.98045, + 0.98002, + 0.97959, + 0.97915, + 0.97871, + 0.97827, + 0.97782, + 0.97736, + 0.97691, + 0.97644, + 0.97598, + 0.9755, + 0.97503, + 0.97455, + 0.97406, + 0.97357, + 0.97308, + 0.97258, + 0.97208, + 0.97157, + 0.97106, + 0.97054, + 0.97002, + 0.9695, + 0.96897, + 0.96843, + 0.96789, + 0.96735, + 0.9668, + 0.96625, + 0.9657, + 0.96514, + 0.96457, + 0.964, + 0.96343, + 0.96285, + 0.96227, + 0.96168, + 0.96109, + 0.9605, + 0.9599, + 0.95929, + 0.95869, + 0.95807, + 0.95746, + 0.95684, + 0.95621, + 0.95558, + 0.95495, + 0.95431, + 0.95367, + 0.95302, + 0.95237, + 0.95171, + 0.95105, + 0.95039, + 0.94972, + 0.94905, + 0.94837, + 0.94769, + 0.94701, + 0.94632, + 0.94563, + 0.94493, + 0.94423, + 0.94352, + 0.94281, + 0.9421, + 0.94138, + 0.94066, + 0.93993, + 0.9392, + 0.93846, + 0.93772, + 0.93698, + 0.93623, + 0.93548, + 0.93473, + 0.93397, + 0.9332, + 0.93244, + 0.93166, + 0.93089, + 0.93011, + 0.92933, + 0.92854, + 0.92775, + 0.92695, + 0.92615, + 0.92535, + 0.92454, + 0.92373, + 0.92291, + 0.92209, + 0.92127, + 0.92044, + 0.91961, + 0.91877, + 0.91793, + 0.91709, + 0.91624, + 0.91539, + 0.91453, + 0.91367, + 0.91281, + 0.91194, + 0.91107, + 0.9102, + 0.90932, + 0.90844, + 0.90755, + 0.90666, + 0.90577, + 0.90487, + 0.90397, + 0.90306, + 0.90215, + 0.90124, + 0.90032, + 0.8994, + 0.89848, + 0.89755, + 0.89662, + 0.89568, + 0.89474, + 0.8938, + 0.89285, + 0.8919, + 0.89095, + 0.88999, + 0.88903, + 0.88807, + 0.8871, + 0.88613, + 0.88515, + 0.88417, + 0.88319, + 0.8822, + 0.88121, + 0.88022, + 0.87922, + 0.87822, + 0.87721, + 0.8762, + 0.87519, + 0.87418, + 0.87316, + 0.87214, + 0.87111, + 0.87008, + 0.86905, + 0.86801, + 0.86697, + 0.86593, + 0.86488, + 0.86383, + 0.86278, + 0.86172, + 0.86066, + 0.8596, + 0.85853, + 0.85746, + 0.85639, + 0.85531, + 0.85423, + 0.85315, + 0.85206, + 0.85097, + 0.84988, + 0.84878, + 0.84768, + 0.84657, + 0.84547, + 0.84436, + 0.84324, + 0.84213, + 0.84101, + 0.83989, + 0.83876, + 0.83763, + 0.8365, + 0.83536, + 0.83422, + 0.83308, + 0.83194, + 0.83079, + 0.82964, + 0.82848, + 0.82732, + 0.82616, + 0.825, + 0.82383, + 0.82266, + 0.82149, + 0.82032, + 0.81914, + 0.81796, + 0.81677, + 0.81558, + 0.81439, + 0.8132, + 0.812, + 0.8108, + 0.8096, + 0.80839, + 0.80719, + 0.80597, + 0.80476, + 0.80354, + 0.80232, + 0.8011, + 0.79988, + 0.79865, + 0.79742, + 0.79618, + 0.79495, + 0.79371, + 0.79246, + 0.79122, + 0.78997, + 0.78872, + 0.78747, + 0.78621, + 0.78495, + 0.78369, + 0.78243, + 0.78116, + 0.77989, + 0.77862, + 0.77735, + 0.77607, + 0.77479, + 0.77351, + 0.77222, + 0.77094, + 0.76965, + 0.76835, + 0.76706, + 0.76576, + 0.76446, + 0.76316, + 0.76185, + 0.76055, + 0.75924, + 0.75792, + 0.75661, + 0.75529, + 0.75397, + 0.75265, + 0.75133, + 0.75, + 0.74867, + 0.74734, + 0.74601, + 0.74467, + 0.74333, + 0.74199, + 0.74065, + 0.7393, + 0.73796, + 0.73661, + 0.73525, + 0.7339, + 0.73254, + 0.73119, + 0.72983, + 0.72846, + 0.7271, + 0.72573, + 0.72436, + 0.72299, + 0.72162, + 0.72024, + 0.71886, + 0.71748, + 0.7161, + 0.71472, + 0.71333, + 0.71195, + 0.71056, + 0.70916, + 0.70777, + 0.70638, + 0.70498, + 0.70358, + 0.70218, + 0.70077, + 0.69937, + 0.69796, + 0.69655, + 0.69514, + 0.69373, + 0.69232, + 0.6909, + 0.68948, + 0.68806, + 0.68664, + 0.68522, + 0.68379, + 0.68236, + 0.68094, + 0.67951, + 0.67807, + 0.67664, + 0.67521, + 0.67377, + 0.67233, + 0.67089, + 0.66945, + 0.668, + 0.66656, + 0.66511, + 0.66367, + 0.66222, + 0.66077, + 0.65931, + 0.65786, + 0.6564, + 0.65495, + 0.65349, + 0.65203, + 0.65057, + 0.6491, + 0.64764, + 0.64617, + 0.64471, + 0.64324, + 0.64177, + 0.6403, + 0.63883, + 0.63735, + 0.63588, + 0.6344, + 0.63292, + 0.63144, + 0.62996, + 0.62848, + 0.627, + 0.62552, + 0.62403, + 0.62255, + 0.62106, + 0.61957, + 0.61808, + 0.61659, + 0.6151, + 0.61361, + 0.61211, + 0.61062, + 0.60912, + 0.60763, + 0.60613, + 0.60463, + 0.60313, + 0.60163, + 0.60013, + 0.59863, + 0.59712, + 0.59562, + 0.59411, + 0.59261, + 0.5911, + 0.58959, + 0.58808, + 0.58657, + 0.58506, + 0.58355, + 0.58204, + 0.58053, + 0.57901, + 0.5775, + 0.57598, + 0.57447, + 0.57295, + 0.57143, + 0.56992, + 0.5684, + 0.56688, + 0.56536, + 0.56384, + 0.56232, + 0.5608, + 0.55927, + 0.55775, + 0.55623, + 0.5547, + 0.55318, + 0.55165, + 0.55013, + 0.5486, + 0.54708, + 0.54555, + 0.54402, + 0.5425, + 0.54097, + 0.53944, + 0.53791, + 0.53638, + 0.53485, + 0.53332, + 0.53179, + 0.53026, + 0.52873, + 0.5272, + 0.52567, + 0.52414, + 0.52261, + 0.52108, + 0.51954, + 0.51801, + 0.51648, + 0.51495, + 0.51341, + 0.51188, + 0.51035, + 0.50882, + 0.50728, + 0.50575, + 0.50422, + 0.50268, + 0.50115, + 0.49962, + 0.49808, + 0.49655, + 0.49502, + 0.49348, + 0.49195, + 0.49042, + 0.48888, + 0.48735, + 0.48582, + 0.48429, + 0.48275, + 0.48122, + 0.47969, + 0.47816, + 0.47663, + 0.4751, + 0.47356, + 0.47203, + 0.4705, + 0.46897, + 0.46744, + 0.46591, + 0.46438, + 0.46285, + 0.46132, + 0.4598, + 0.45827, + 0.45674, + 0.45521, + 0.45369, + 0.45216, + 0.45063, + 0.44911, + 0.44758, + 0.44606, + 0.44453, + 0.44301, + 0.44149, + 0.43997, + 0.43844, + 0.43692, + 0.4354, + 0.43388, + 0.43236, + 0.43084, + 0.42933, + 0.42781, + 0.42629, + 0.42478, + 0.42326, + 0.42174, + 0.42023, + 0.41872, + 0.41721, + 0.41569, + 0.41418, + 0.41267, + 0.41116, + 0.40965, + 0.40815, + 0.40664, + 0.40513, + 0.40363, + 0.40213, + 0.40062, + 0.39912, + 0.39762, + 0.39612, + 0.39462, + 0.39312, + 0.39162, + 0.39013, + 0.38863, + 0.38714, + 0.38565, + 0.38415, + 0.38266, + 0.38117, + 0.37968, + 0.3782, + 0.37671, + 0.37522, + 0.37374, + 0.37226, + 0.37078, + 0.3693, + 0.36782, + 0.36634, + 0.36486, + 0.36339, + 0.36191, + 0.36044, + 0.35897, + 0.3575, + 0.35603, + 0.35456, + 0.35309, + 0.35163, + 0.35017, + 0.3487, + 0.34724, + 0.34578, + 0.34433, + 0.34287, + 0.34141, + 0.33996, + 0.33851, + 0.33706, + 0.33561, + 0.33416, + 0.33272, + 0.33127, + 0.32983, + 0.32839, + 0.32695, + 0.32551, + 0.32408, + 0.32264, + 0.32121, + 0.31978, + 0.31835, + 0.31692, + 0.3155, + 0.31407, + 0.31265, + 0.31123, + 0.30981, + 0.30839, + 0.30698, + 0.30556, + 0.30415, + 0.30274, + 0.30133, + 0.29993, + 0.29852, + 0.29712, + 0.29572, + 0.29432, + 0.29293, + 0.29153, + 0.29014, + 0.28875, + 0.28736, + 0.28597, + 0.28459, + 0.28321, + 0.28183, + 0.28045, + 0.27907, + 0.2777, + 0.27632, + 0.27495, + 0.27359, + 0.27222, + 0.27086, + 0.26949, + 0.26813, + 0.26678, + 0.26542, + 0.26407, + 0.26272, + 0.26137, + 0.26002, + 0.25868, + 0.25734, + 0.256, + 0.25466, + 0.25333, + 0.25199, + 0.25066, + 0.24934, + 0.24801, + 0.24669, + 0.24537, + 0.24405, + 0.24273, + 0.24142, + 0.24011, + 0.2388, + 0.23749, + 0.23619, + 0.23489, + 0.23359, + 0.23229, + 0.231, + 0.22971, + 0.22842, + 0.22713, + 0.22585, + 0.22457, + 0.22329, + 0.22202, + 0.22074, + 0.21947, + 0.2182, + 0.21694, + 0.21568, + 0.21442, + 0.21316, + 0.2119, + 0.21065, + 0.2094, + 0.20816, + 0.20691, + 0.20567, + 0.20444, + 0.2032, + 0.20197, + 0.20074, + 0.19951, + 0.19829, + 0.19707, + 0.19585, + 0.19463, + 0.19342, + 0.19221, + 0.191, + 0.1898, + 0.1886, + 0.1874, + 0.1862, + 0.18501, + 0.18382, + 0.18264, + 0.18145, + 0.18027, + 0.1791, + 0.17792, + 0.17675, + 0.17558, + 0.17442, + 0.17325, + 0.1721, + 0.17094, + 0.16979, + 0.16864, + 0.16749, + 0.16635, + 0.16521, + 0.16407, + 0.16294, + 0.1618, + 0.16068, + 0.15955, + 0.15843, + 0.15731, + 0.1562, + 0.15509, + 0.15398, + 0.15287, + 0.15177, + 0.15067, + 0.14958, + 0.14849, + 0.1474, + 0.14631, + 0.14523, + 0.14415, + 0.14307, + 0.142, + 0.14093, + 0.13987, + 0.13881, + 0.13775, + 0.13669, + 0.13564, + 0.13459, + 0.13355, + 0.13251, + 0.13147, + 0.13043, + 0.1294, + 0.12838, + 0.12735, + 0.12633, + 0.12531, + 0.1243, + 0.12329, + 0.12228, + 0.12128, + 0.12028, + 0.11929, + 0.1183, + 0.11731, + 0.11632, + 0.11534, + 0.11436, + 0.11339, + 0.11242, + 0.11145, + 0.11049, + 0.10953, + 0.10857, + 0.10762, + 0.10667, + 0.10573, + 0.10479, + 0.10385, + 0.10292, + 0.10199, + 0.10106, + 0.10014, + 0.099218, + 0.098303, + 0.097392, + 0.096485, + 0.095582, + 0.094682, + 0.093786, + 0.092894, + 0.092006, + 0.091121, + 0.090241, + 0.089364, + 0.088491, + 0.087622, + 0.086757, + 0.085896, + 0.085039, + 0.084185, + 0.083336, + 0.08249, + 0.081649, + 0.080811, + 0.079977, + 0.079147, + 0.078321, + 0.0775, + 0.076682, + 0.075868, + 0.075058, + 0.074252, + 0.07345, + 0.072652, + 0.071858, + 0.071068, + 0.070282, + 0.0695, + 0.068722, + 0.067949, + 0.067179, + 0.066413, + 0.065652, + 0.064895, + 0.064141, + 0.063392, + 0.062647, + 0.061906, + 0.061169, + 0.060436, + 0.059707, + 0.058983, + 0.058263, + 0.057546, + 0.056834, + 0.056126, + 0.055423, + 0.054723, + 0.054028, + 0.053337, + 0.05265, + 0.051967, + 0.051288, + 0.050614, + 0.049944, + 0.049278, + 0.048617, + 0.047959, + 0.047306, + 0.046657, + 0.046013, + 0.045372, + 0.044736, + 0.044105, + 0.043477, + 0.042854, + 0.042235, + 0.04162, + 0.04101, + 0.040404, + 0.039803, + 0.039205, + 0.038612, + 0.038024, + 0.037439, + 0.036859, + 0.036284, + 0.035712, + 0.035146, + 0.034583, + 0.034025, + 0.033471, + 0.032922, + 0.032377, + 0.031836, + 0.0313, + 0.030768, + 0.030241, + 0.029718, + 0.0292, + 0.028686, + 0.028176, + 0.027671, + 0.02717, + 0.026674, + 0.026182, + 0.025694, + 0.025211, + 0.024733, + 0.024259, + 0.023789, + 0.023324, + 0.022864, + 0.022408, + 0.021956, + 0.021509, + 0.021066, + 0.020628, + 0.020195, + 0.019766, + 0.019341, + 0.018921, + 0.018505, + 0.018094, + 0.017688, + 0.017286, + 0.016889, + 0.016496, + 0.016107, + 0.015724, + 0.015344, + 0.01497, + 0.0146, + 0.014234, + 0.013873, + 0.013517, + 0.013165, + 0.012818, + 0.012475, + 0.012137, + 0.011804, + 0.011475, + 0.01115, + 0.010831, + 0.010516, + 0.010205, + 0.0098993, + 0.009598, + 0.0093013, + 0.0090093, + 0.0087219, + 0.008439, + 0.0081608, + 0.0078873, + 0.0076183, + 0.007354, + 0.0070943, + 0.0068393, + 0.0065889, + 0.0063431, + 0.006102, + 0.0058655, + 0.0056337, + 0.0054065, + 0.0051839, + 0.0049661, + 0.0047528, + 0.0045443, + 0.0043403, + 0.0041411, + 0.0039465, + 0.0037566, + 0.0035713, + 0.0033907, + 0.0032148, + 0.0030435, + 0.002877, + 0.0027151, + 0.0025578, + 0.0024053, + 0.0022574, + 0.0021142, + 0.0019757, + 0.0018419, + 0.0017128, + 0.0015883, + 0.0014685, + 0.0013535, + 0.0012431, + 0.0011374, + 0.0010363, + 0.00094003, + 0.0008484, + 0.00076147, + 0.00067923, + 0.00060168, + 0.00052884, + 0.00046069, + 0.00039723, + 0.00033848, + 0.00028442, + 0.00023506, + 0.0001904, + 0.00015044, + 0.00011518, + 0.000084626, + 0.000058769, + 0.000037612, + 0.000021157, + 0.0000094032, + 0.0000023508, +} diff --git a/pkg/identifier/shazam/signature.go b/pkg/identifier/shazam/signature.go new file mode 100644 index 0000000..d6df60a --- /dev/null +++ b/pkg/identifier/shazam/signature.go @@ -0,0 +1,242 @@ +// This file is vendored from https://github.com/lukechampine/barbershop +// Original copyright (c) 2024 Luke Champine, MIT licensed (see LICENSE). +// +// Modifications for rig: +// - Dropped the optional CollectSample helper that depended on faiface/beep. +// - Dropped the unused Signature.decode round-trip method. +// - Added explicit error handling on binary writes where required by linters. + +package shazam + +import ( + "bytes" + "encoding/binary" + "hash/crc32" + "math" + + "gonum.org/v1/gonum/dsp/fourier" +) + +func convertSampleRate(x int) int { + return map[int]int{ + 1: 8000, + 2: 11025, + 3: 16000, + 4: 32000, + 5: 44100, + + 8000: 1, + 11025: 2, + 16000: 3, + 32000: 4, + 44100: 5, + }[x] +} + +type frequencyPeak struct { + pass int + magnitude int + bin int +} + +// A Signature is a unique fingerprint of an audio sample. +type Signature struct { + sampleRate int + numSamples int + peaksByBand [5][]frequencyPeak +} + +// encode serialises the signature into Shazam's wire format. +// Writes to bytes.Buffer never fail, so binary.Write errors are intentionally +// ignored. Integer truncations on this path are deliberate bit packing for +// Shazam's wire format, so gosec G115 is suppressed throughout. +// +//nolint:gosec // G115: intentional bit packing for Shazam wire format +func (s Signature) encode() []byte { + var buf []byte + write := func(u uint32) { + var b [4]byte + binary.LittleEndian.PutUint32(b[:], u) + buf = append(buf, b[:]...) + } + + // header + write(0xcafe2580) + write(0) // checksum + write(0) // length + write(0x94119c00) + write(0) + write(0) + write(0) + write(uint32(convertSampleRate(s.sampleRate)) << 27) + write(0) + write(0) + write(uint32(s.numSamples) + uint32(float64(s.sampleRate)*0.24)) + write(0x007c0000) + write(uint32(0x40000000)) + write(0) // length2 + + // peaks + for band, peaks := range s.peaksByBand { + if len(peaks) == 0 { + continue + } + var peakBuf bytes.Buffer + pass := 0 + for _, peak := range peaks { + if peak.pass-pass >= 255 { + peakBuf.WriteByte(0xFF) + _ = binary.Write(&peakBuf, binary.LittleEndian, uint32(peak.pass)) + pass = peak.pass + } + _ = binary.Write(&peakBuf, binary.LittleEndian, uint8(peak.pass-pass)) + _ = binary.Write(&peakBuf, binary.LittleEndian, uint16(peak.magnitude)) + _ = binary.Write(&peakBuf, binary.LittleEndian, uint16(peak.bin)) + pass = peak.pass + } + write(uint32(0x60030040 + band)) + write(uint32(peakBuf.Len())) + for peakBuf.Len()%4 != 0 { + peakBuf.WriteByte(0x00) + } + buf = append(buf, peakBuf.Bytes()...) + } + + binary.LittleEndian.PutUint32(buf[8:12], uint32(len(buf[48:]))) + binary.LittleEndian.PutUint32(buf[52:56], uint32(len(buf[48:]))) + binary.LittleEndian.PutUint32(buf[4:8], crc32.ChecksumIEEE(buf[8:])) + return buf +} + +type ring[T any] struct { + buf []T + index int +} + +func (r ring[T]) mod(i int) int { + for i < 0 { + i += len(r.buf) + } + return i % len(r.buf) +} + +func (r ring[T]) At(i int) *T { + return &r.buf[r.mod(r.index+i)] +} + +func (r ring[T]) Append(x ...T) ring[T] { + for len(x) > 0 { + n := copy(r.buf[r.index:], x) + x = x[n:] + r.index = (r.index + n) % len(r.buf) + } + return r +} + +func (r ring[T]) Slice(s []T, offset int) { + offset = r.mod(offset + r.index) + for len(s) > 0 { + n := copy(s, r.buf[offset:]) + s = s[n:] + offset = (offset + n) % len(r.buf) + } +} + +func newRing[T any](size int) ring[T] { + return ring[T]{buf: make([]T, size)} +} + +// ComputeSignature computes the audio signature of the provided mono samples +// at the given sample rate. The sample rate must be one of 8000, 11025, 16000, +// 32000, or 44100 Hz. +func ComputeSignature(sampleRate int, samples []float64) Signature { + maxNeighbor := func(spreadOutputs ring[[1025]float64], i int) (neighbor float64) { + for _, off := range []int{-10, -7, -4, -3, 1, 2, 5, 8} { + neighbor = max(neighbor, spreadOutputs.At(-49)[(i+off)]) + } + for _, off := range []int{-53, -45, 165, 172, 179, 186, 193, 200, 214, 221, 228, 235, 242, 249} { + neighbor = max(neighbor, spreadOutputs.At(off)[i-1]) + } + return neighbor + } + normalizePeak := func(x float64) float64 { + return math.Log(max(x, 1.0/64))*1477.3 + 6144 + } + peakBand := func(bin int) (int, bool) { + hz := (bin * sampleRate) / (2 * 1024 * 64) + band, ok := map[bool]int{ + 250 <= hz && hz < 520: 0, + 520 <= hz && hz < 1450: 1, + 1450 <= hz && hz < 3500: 2, + 3500 <= hz && hz <= 5500: 3, + }[true] + return band, ok + } + + fft := fourier.NewFFT(2048) + samplesRing := newRing[float64](2048) + fftOutputs := newRing[[1025]float64](256) + spreadOutputs := newRing[[1025]float64](256) + var peaksByBand [5][]frequencyPeak + for i := 0; i*128+128 < len(samples); i++ { + samplesRing = samplesRing.Append(samples[i*128:][:128]...) + + // Perform FFT. + reorderedSamples := make([]float64, 2048) + samplesRing.Slice(reorderedSamples, 0) + for j, m := range &hanningMultipliers { + reorderedSamples[j] = math.Round(reorderedSamples[j]*1024*64) * m + } + var outputs [1025]float64 + for k, c := range fft.Coefficients(nil, reorderedSamples) { + outputs[k] = max((real(c)*real(c)+imag(c)*imag(c))/(1<<17), 0.0000000001) + } + fftOutputs = fftOutputs.Append(outputs) + + // Spread peaks, both in the frequency domain... + for j := 0; j < len(outputs)-2; j++ { + outputs[j] = max(outputs[j], outputs[j+1], outputs[j+2]) + } + spreadOutputs = spreadOutputs.Append(outputs) + // ... and in the time domain. + for _, off := range []int{-2, -4, -7} { + prev := spreadOutputs.At(off) + for j := range prev { + prev[j] = max(prev[j], outputs[j]) + } + } + + // Accumulate samples until we have enough... + if i < 45 { + continue + } + // ...then recognise peaks. + fftOutput := fftOutputs.At(-46) + for bin := 10; bin < 1015; bin++ { + // Ensure that this is a frequency- and time-domain local maximum. + if fftOutput[bin] <= maxNeighbor(spreadOutputs, bin) { + continue + } + // Normalise and compute frequency band. + before := normalizePeak(fftOutput[bin-1]) + peak := normalizePeak(fftOutput[bin]) + after := normalizePeak(fftOutput[bin+1]) + variation := int((32 * (after - before)) / (2*peak - after - before)) + peakBin := bin*64 + variation + band, ok := peakBand(peakBin) + if !ok { + continue + } + peaksByBand[band] = append(peaksByBand[band], frequencyPeak{ + pass: i - 45, + magnitude: int(peak), + bin: peakBin, + }) + } + } + return Signature{ + sampleRate: sampleRate, + numSamples: len(samples), + peaksByBand: peaksByBand, + } +} diff --git a/pkg/identifier/shazam/signature_test.go b/pkg/identifier/shazam/signature_test.go new file mode 100644 index 0000000..c28fc8d --- /dev/null +++ b/pkg/identifier/shazam/signature_test.go @@ -0,0 +1,50 @@ +// This file is vendored from https://github.com/lukechampine/barbershop +// Original copyright (c) 2024 Luke Champine, MIT licensed (see LICENSE). + +package shazam + +import ( + "crypto/sha256" + "fmt" + "math" + "testing" +) + +func TestSignature(t *testing.T) { + samples := make([]float64, 128) + sig := ComputeSignature(16000, samples) + h := sha256.Sum256(sig.encode()) + if fmt.Sprintf("%x", h) != "4ae7d1ae7a4787a7d6cda559db6e17026f60369b3485b762759b7a07ff24fab9" { + t.Fatalf("bad signature: %x", h) + } + + samples = make([]float64, 1024) + for i := range samples { + samples[i] = float64(i) + } + sig = ComputeSignature(16000, samples) + h = sha256.Sum256(sig.encode()) + if fmt.Sprintf("%x", h) != "073022772a4bc617a855adfb6265316f23ae6a25045e670e0904a2b11f132a75" { + t.Fatalf("bad signature: %x", h) + } + + samples = make([]float64, 16*1024) + for i := range samples { + samples[i] = math.Sin(float64(i) * 2 * math.Pi / 256) + } + sig = ComputeSignature(16000, samples) + h = sha256.Sum256(sig.encode()) + if fmt.Sprintf("%x", h) != "c8c055411ec845f6d57b27baf7fc5735fdaf51f2a6026dd12f09d0eb17652c02" { + t.Fatalf("bad signature: %x", h) + } + + samples = make([]float64, 7*1024+55) + for i := range samples { + samples[i] = math.Cos(float64(i+12) * math.E) + } + sig = ComputeSignature(16000, samples) + h = sha256.Sum256(sig.encode()) + if fmt.Sprintf("%x", h) != "e399475137268c73d7e6665479358370c0979f7d2c3860f71b1e035105b3a1d8" { + t.Fatalf("bad signature: %x", h) + } +} diff --git a/pkg/ui/identify.go b/pkg/ui/identify.go new file mode 100644 index 0000000..2c99b5b --- /dev/null +++ b/pkg/ui/identify.go @@ -0,0 +1,214 @@ +package ui + +import ( + "context" + "errors" + "fmt" + "net/url" + "os/exec" + "runtime" + "strings" + "time" + + tea "charm.land/bubbletea/v2" + "charm.land/lipgloss/v2" + + "github.com/mrwhyte/rig/pkg/identifier" +) + +// identifyDuration is how much audio we capture for one recognition attempt. +// Long enough for reliable matches, short enough not to bore the user. +const identifyDuration = 12 * time.Second + +// identifyOverallTimeout caps the full operation including network latency +// and the Shazam rate limiter window. +const identifyOverallTimeout = 45 * time.Second + +// identifyResultMsg carries the result of an identification attempt. +type identifyResultMsg struct { + track *identifier.Track + err error +} + +// isIdentifying reports whether the identify modal is in its loading state, +// i.e. an identification is in flight and we haven't received a result yet. +func (m *Model) isIdentifying() bool { + return m.showIdentifyModal && m.identifyTrack == nil && m.identifyErr == nil +} + +// startIdentify launches the async identification command. The capture, +// fingerprint, and Shazam round-trip all happen inside the returned tea.Cmd +// so the UI stays responsive. The created context is stored on the model so +// Esc/Enter can abort the in-flight goroutine instead of leaking it. +func (m *Model) startIdentify() tea.Cmd { + if m.playing == nil { + return nil + } + streamURL := m.playing.URLResolved + ctx, cancel := context.WithTimeout(context.Background(), identifyOverallTimeout) + m.identifyCancel = cancel + return func() tea.Msg { + track, err := identifier.IdentifyStreamFor(ctx, streamURL, identifyDuration) + return identifyResultMsg{track: track, err: err} + } +} + +// openURL opens rawURL in the user's default browser. The scheme is +// validated to be http/https before exec'ing anything. +func openURL(rawURL string) error { + parsed, err := url.Parse(rawURL) + if err != nil { + return fmt.Errorf("parse url: %w", err) + } + if parsed.Scheme != "http" && parsed.Scheme != "https" { + return fmt.Errorf("unsupported url scheme: %q", parsed.Scheme) + } + + ctx := context.Background() + var cmd *exec.Cmd + switch runtime.GOOS { + case "darwin": + cmd = exec.CommandContext(ctx, "open", rawURL) //nolint:gosec // G204: URL scheme validated above + case "linux": + cmd = exec.CommandContext(ctx, "xdg-open", rawURL) //nolint:gosec // G204: URL scheme validated above + case "windows": + cmd = exec.CommandContext(ctx, "cmd", "/c", "start", rawURL) //nolint:gosec // G204: URL scheme validated above + default: + return fmt.Errorf("unsupported OS: %s", runtime.GOOS) + } + return cmd.Start() +} + +// handleIdentifyModalInput handles keyboard input while the identify modal +// is showing — whether the spinner is running or a result is on screen. +func (m *Model) handleIdentifyModalInput(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { + switch msg.String() { + case keyCtrlC: + m.stopPlayback() + return m, tea.Quit + + case keyEsc, keyEnter: + m.resetIdentifyState() + return m, nil + + case keyOpen: + if m.identifyTrack != nil && m.identifyTrack.ShazamURL != "" { + if err := openURL(m.identifyTrack.ShazamURL); err != nil { + m.identifyErr = fmt.Errorf("open url: %w", err) + } + } + return m, nil + } + return m, nil +} + +// resetIdentifyState clears identify-related state and cancels any in-flight +// goroutine. The cancellation propagates to the HTTP request, the MP3 +// decoder, and the Shazam rate limiter, so dismissed identifications stop +// consuming network and memory immediately. +func (m *Model) resetIdentifyState() { + if m.identifyCancel != nil { + m.identifyCancel() + m.identifyCancel = nil + } + m.showIdentifyModal = false + m.identifyTrack = nil + m.identifyErr = nil +} + +// renderIdentifyModal renders a centred modal showing either the spinner +// (while identifying) or the result (after completion). +func (m *Model) renderIdentifyModal() string { + const modalWidth = 56 + const modalHeight = 11 + + title := lipgloss.NewStyle(). + Bold(true). + Foreground(colorTitle). + Padding(0, 1). + Render("♪ Identify Track") + + var content string + switch { + case m.isIdentifying(): + content = m.renderIdentifySpinner() + case m.identifyErr != nil: + content = m.renderIdentifyError() + case m.identifyTrack != nil: + content = m.renderIdentifyResult() + default: + content = "\n (nothing to display)\n" + } + + panel := lipgloss.JoinVertical(lipgloss.Left, title, content) + + modal := lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(colorAccent). + Padding(1, 2). + Width(modalWidth). + Height(modalHeight). + Render(panel) + + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, modal) +} + +func (m *Model) renderIdentifySpinner() string { + return fmt.Sprintf( + "\n %s %s\n\n %s\n", + lipgloss.NewStyle().Foreground(colorAccent).Render(m.identifySpinner.View()), + lipgloss.NewStyle().Foreground(colorTitle).Render("Listening..."), + lipgloss.NewStyle(). + Foreground(colorMuted). + Render("This takes about 12-15 seconds. esc to cancel."), + ) +} + +func (m *Model) renderIdentifyError() string { + // For codec mismatches we deliberately hide the technical decoder + // string ("only layer3 ... want 1 got 3" etc) and just show the + // friendly headline. + if errors.Is(m.identifyErr, identifier.ErrUnsupportedCodec) { + return fmt.Sprintf( + "\n %s\n\n %s", + lipgloss.NewStyle().Foreground(colorWarning).Render("Sorry, only MP3 streams are currently supported"), + lipgloss.NewStyle().Foreground(colorDim).Render("enter/esc to close"), + ) + } + + headline := "Couldn't identify the track" + if errors.Is(m.identifyErr, identifier.ErrNoMatch) { + headline = "No match found" + } + return fmt.Sprintf( + "\n %s\n\n %s\n\n %s", + lipgloss.NewStyle().Foreground(colorWarning).Render(headline), + lipgloss.NewStyle().Foreground(colorMuted).Render(m.identifyErr.Error()), + lipgloss.NewStyle().Foreground(colorDim).Render("enter/esc to close"), + ) +} + +func (m *Model) renderIdentifyResult() string { + t := m.identifyTrack + var b strings.Builder + b.WriteString("\n ") + b.WriteString(lipgloss.NewStyle().Bold(true).Foreground(colorTitle).Render(t.Title)) + b.WriteString("\n ") + b.WriteString(lipgloss.NewStyle().Foreground(colorAccent).Render(t.Artist)) + if t.Album != "" { + b.WriteString("\n ") + b.WriteString(lipgloss.NewStyle().Foreground(colorMuted).Render(t.Album)) + if t.Year != "" { + b.WriteString(lipgloss.NewStyle().Foreground(colorDim).Render(" · " + t.Year)) + } + } + b.WriteString("\n\n ") + if t.ShazamURL != "" { + b.WriteString(lipgloss.NewStyle(). + Foreground(colorDim). + Render("press o to open in Shazam · enter/esc to close")) + } else { + b.WriteString(lipgloss.NewStyle().Foreground(colorDim).Render("enter/esc to close")) + } + return b.String() +} diff --git a/pkg/ui/keys.go b/pkg/ui/keys.go index 4aa5d09..61a068c 100644 --- a/pkg/ui/keys.go +++ b/pkg/ui/keys.go @@ -18,6 +18,7 @@ const ( keyCtrlC = "ctrl+c" keyEnter = "enter" keyEsc = "esc" + keyOpen = "o" ) // handleKeyPress handles keyboard input. @@ -31,6 +32,11 @@ func (m *Model) handleKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { return m.handleTimerModalInput(msg) } + // If the identify modal is open, route keys through it. + if m.showIdentifyModal { + return m.handleIdentifyModalInput(msg) + } + // If editing a filter, handle input differently if m.editingFilter != FilterNone { return m.handleFilterInput(msg) @@ -62,47 +68,7 @@ func (m *Model) handleKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { return m, nil case "space": - // Toggle play/pause, or play selected station - switch { - case m.isPlaying && m.playing != nil: - // Currently playing - pause it - if err := m.player.Pause(); err == nil { - m.isPlaying = false - if m.sleepTimerActive { - m.sleepTimerPaused = true - elapsed := time.Since(m.sleepTimerStart) - m.sleepTimerRemaining = m.sleepTimerDuration - elapsed - } - } - return m, nil - case !m.isPlaying && m.playing != nil: - // Paused - resume it - if err := m.player.Resume(); err == nil { - m.isPlaying = true - if m.sleepTimerActive && m.sleepTimerPaused { - m.sleepTimerPaused = false - m.sleepTimerDuration = m.sleepTimerRemaining - m.sleepTimerStart = time.Now() - waveCmd := m.waveTick() - sleepCmd := m.sleepTimerTick() - return m, tea.Batch(waveCmd, sleepCmd) - } - cmd := m.waveTick() - return m, cmd - } - return m, nil - case m.focusedSection == SectionStationList && len(m.stations) > 0: - // No station playing and in station list - play selected station - // Get the actual selected item from the filtered list - if item := m.stationList.SelectedItem(); item != nil { - if stationItem, ok := item.(StationItem); ok { - return m, func() tea.Msg { - return playStationMsg{&stationItem.station} - } - } - } - } - return m, nil + return m.handleSpaceKey() case "s": // Stop playback @@ -144,6 +110,15 @@ func (m *Model) handleKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { } return m, m.timerInput.Focus() + case "i": + // Identify the currently playing track via Shazam. + if m.playing == nil { + return m, nil + } + m.resetIdentifyState() + m.showIdentifyModal = true + return m, tea.Batch(m.startIdentify(), m.identifySpinner.Tick) + case "f": // Toggle favorite for selected station if m.focusedSection == SectionStationList && len(m.stations) > 0 { @@ -578,3 +553,49 @@ func (m *Model) handleThemeModalInput(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) return m, nil } + +// handleSpaceKey handles the space-bar shortcut: toggle play/pause when a +// station is loaded, or play the selected station when nothing is loaded. +func (m *Model) handleSpaceKey() (tea.Model, tea.Cmd) { + switch { + case m.isPlaying && m.playing != nil: + // Currently playing - pause it. + if err := m.player.Pause(); err == nil { + m.isPlaying = false + if m.sleepTimerActive { + m.sleepTimerPaused = true + elapsed := time.Since(m.sleepTimerStart) + m.sleepTimerRemaining = m.sleepTimerDuration - elapsed + } + } + return m, nil + + case !m.isPlaying && m.playing != nil: + // Paused - resume it. + if err := m.player.Resume(); err == nil { + m.isPlaying = true + if m.sleepTimerActive && m.sleepTimerPaused { + m.sleepTimerPaused = false + m.sleepTimerDuration = m.sleepTimerRemaining + m.sleepTimerStart = time.Now() + waveCmd := m.waveTick() + sleepCmd := m.sleepTimerTick() + return m, tea.Batch(waveCmd, sleepCmd) + } + cmd := m.waveTick() + return m, cmd + } + return m, nil + + case m.focusedSection == SectionStationList && len(m.stations) > 0: + // No station playing and in station list - play selected station. + if item := m.stationList.SelectedItem(); item != nil { + if stationItem, ok := item.(StationItem); ok { + return m, func() tea.Msg { + return playStationMsg{&stationItem.station} + } + } + } + } + return m, nil +} diff --git a/pkg/ui/layout.go b/pkg/ui/layout.go index 1075f87..93e327d 100644 --- a/pkg/ui/layout.go +++ b/pkg/ui/layout.go @@ -89,7 +89,7 @@ func (m *Model) renderFooter() string { shortcuts = "↑↓/jk: select • enter: edit • c: clear" } - help := fmt.Sprintf("tab: switch sections [%s] • %s • space: pause • +/-: volume • t: sleep timer • ctrl+t: theme • ctrl+c: quit", + help := fmt.Sprintf("tab: switch sections [%s] • %s • space: pause • +/-: volume • i: identify • t: sleep timer • ctrl+t: theme • ctrl+c: quit", m.focusedSection.String(), shortcuts, ) diff --git a/pkg/ui/model.go b/pkg/ui/model.go index 8352548..1872995 100644 --- a/pkg/ui/model.go +++ b/pkg/ui/model.go @@ -1,6 +1,7 @@ package ui import ( + "context" "fmt" "os" "strings" @@ -8,11 +9,13 @@ import ( "charm.land/bubbles/v2/list" "charm.land/bubbles/v2/progress" + "charm.land/bubbles/v2/spinner" "charm.land/bubbles/v2/textinput" tea "charm.land/bubbletea/v2" "github.com/mrwhyte/rig/pkg/config" "github.com/mrwhyte/rig/pkg/favorites" + "github.com/mrwhyte/rig/pkg/identifier" "github.com/mrwhyte/rig/pkg/player" "github.com/mrwhyte/rig/pkg/radiobrowser" "github.com/mrwhyte/rig/pkg/sponsors" @@ -117,6 +120,12 @@ type Model struct { liveSponsors []sponsors.Sponsor // Live sponsors loaded from Gist/cache sponsorScrollOffset int // Top of visible window into the virtual scroll list + // Track identification (Shazam) + showIdentifyModal bool + identifyTrack *identifier.Track + identifyErr error + identifySpinner spinner.Model + identifyCancel context.CancelFunc } // NewModel creates a new application model. @@ -158,6 +167,8 @@ func NewModel() (*Model, error) { ) volumeBar.EmptyColor = colorBorder + identifySpinner := spinner.New(spinner.WithSpinner(spinner.MiniDot)) + m := &Model{ view: ViewLoading, apiClient: apiClient, @@ -173,6 +184,7 @@ func NewModel() (*Model, error) { favManager: favManager, timerInput: timerInput, volumeBar: volumeBar, + identifySpinner: identifySpinner, } return m, nil @@ -601,6 +613,25 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.volumeBar = newBar return m, cmd + case identifyResultMsg: + // Ignore the result if the user dismissed the modal mid-flight. + if !m.showIdentifyModal { + return m, nil + } + m.identifyTrack = msg.track + m.identifyErr = msg.err + return m, nil + + case spinner.TickMsg: + // Only keep ticking while the identification spinner should be + // visible. Other spinner instances are ignored by ID inside Update. + if !m.isIdentifying() { + return m, nil + } + var cmd tea.Cmd + m.identifySpinner, cmd = m.identifySpinner.Update(msg) + return m, cmd + case waveTickMsg: if m.isPlaying { m.waveFrame++ @@ -637,6 +668,8 @@ func (m *Model) View() tea.View { content = m.renderTimerModal() case m.showThemeModal: content = m.renderThemeModal() + case m.showIdentifyModal: + content = m.renderIdentifyModal() default: switch m.view { case ViewLoading: From 79a8fb70308c1e45dac118d72c4cba1febb4ab11 Mon Sep 17 00:00:00 2001 From: Michael Whyte Date: Wed, 13 May 2026 21:53:17 +0100 Subject: [PATCH 2/4] fix: extract mpv IPC literals to constants for goconst lint golangci-lint v2.12.2 (latest, used by CI) tightened goconst's duplication detection and flags "command" (5 uses) and "set_property" (3 uses) in pkg/player/player.go. Local lint at v2.11.4 didn't. Extracts both into named constants alongside the rest of the mpv IPC protocol layer. Co-Authored-By: Claude Opus 4.7 --- pkg/player/player.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pkg/player/player.go b/pkg/player/player.go index fa0e3d7..90a526d 100644 --- a/pkg/player/player.go +++ b/pkg/player/player.go @@ -14,6 +14,12 @@ import ( "time" ) +// MPV IPC protocol literals. +const ( + mpvCmdKey = "command" + mpvCmdSetProperty = "set_property" +) + // State represents the current player state. type State int @@ -147,7 +153,7 @@ func (p *MPVPlayer) Pause() error { } if err := p.sendCommand(map[string]interface{}{ - "command": []interface{}{"set_property", "pause", true}, + mpvCmdKey: []interface{}{mpvCmdSetProperty, "pause", true}, }); err != nil { return err } @@ -166,7 +172,7 @@ func (p *MPVPlayer) Resume() error { } if err := p.sendCommand(map[string]interface{}{ - "command": []interface{}{"set_property", "pause", false}, + mpvCmdKey: []interface{}{mpvCmdSetProperty, "pause", false}, }); err != nil { return err } @@ -192,7 +198,7 @@ func (p *MPVPlayer) stopLocked() { // Send quit command _ = p.sendCommand(map[string]interface{}{ - "command": []interface{}{"quit"}, + mpvCmdKey: []interface{}{"quit"}, }) // Kill process if still running @@ -224,7 +230,7 @@ func (p *MPVPlayer) SetVolume(volume int) error { if p.state == StatePlaying || p.state == StatePaused { if err := p.sendCommand(map[string]interface{}{ - "command": []interface{}{"set_property", "volume", volume}, + mpvCmdKey: []interface{}{mpvCmdSetProperty, "volume", volume}, }); err != nil { return err } @@ -317,7 +323,7 @@ func (p *MPVPlayer) getProperty(property string) (interface{}, error) { // Send command cmd := map[string]interface{}{ - "command": []interface{}{"get_property", property}, + mpvCmdKey: []interface{}{"get_property", property}, "request_id": 1, } encoder := json.NewEncoder(conn) From 7eace5d0ab451e3344e403f27af449de7103008e Mon Sep 17 00:00:00 2001 From: Michael Whyte Date: Wed, 13 May 2026 21:56:09 +0100 Subject: [PATCH 3/4] ci: pin golangci-lint to v2.12.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `version: latest` makes CI fail unpredictably whenever golangci-lint ships a release with stricter defaults — exactly what happened on PR #1 (v2.12.2 added new goconst occurrences). Pin to v2.12.2 (the current latest, matching local installs via brew) so version bumps are deliberate, surfaced as PRs. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/lint.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a765a42..6238d01 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -34,7 +34,9 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v7 with: - version: latest + # Pinned to avoid CI surprises when new lint releases tighten + # checks. Bump deliberately, not silently. + version: v2.12.2 vet: name: Go Vet & Build From 1db3138689101c33988c99d3a6a27c367c7a903f Mon Sep 17 00:00:00 2001 From: Michael Whyte Date: Wed, 13 May 2026 22:20:48 +0100 Subject: [PATCH 4/4] docs: highlight track identification on README and website - README: new feature bullet, dedicated section with gif, and i/o keyboard shortcuts in the controls table - Website: new feature card and showcase entry on docs/index.html - New asset: docs/assets/identify.gif (recorded via asciinema, .cast preserved alongside the other showcase casts) Ordered after Favourites in both surfaces to match the existing showcase flow. Co-Authored-By: Claude Opus 4.7 --- README.md | 8 ++++++ docs/assets/identify.cast | 54 ++++++++++++++++++++++++++++++++++++++ docs/assets/identify.gif | Bin 0 -> 144042 bytes docs/index.html | 17 ++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 docs/assets/identify.cast create mode 100644 docs/assets/identify.gif diff --git a/README.md b/README.md index cb6cc57..291e071 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ No accounts. No ads. Just radio. - 🎨 Beautiful terminal UI with multiple themes - ⌨️ Keyboard-driven interface for fast navigation - ⭐ Save your favourite stations +- 🎤 Identify the playing track with one keypress — Shazam-style, no API key required - 🎵 Now playing display with station metadata ### Search and play @@ -37,6 +38,11 @@ No accounts. No ads. Just radio. ![Managing favourites](docs/assets/favourites.gif) +### Identify the playing track +Press `i` while a station is playing. rig taps the audio, fingerprints it locally in pure Go, and asks Shazam to identify it. Press `o` to open the track on shazam.com. + +![Identifying a track in the terminal](docs/assets/identify.gif) + ## Installation @@ -85,6 +91,8 @@ rig | `Space` | Pause/Resume | | `+` / `-` | Volume up/down | | `s` | Search stations | +| `i` | Identify the playing track | +| `o` | Open identified track on shazam.com | | `?` | Help | | `q` | Quit | diff --git a/docs/assets/identify.cast b/docs/assets/identify.cast new file mode 100644 index 0000000..27a90af --- /dev/null +++ b/docs/assets/identify.cast @@ -0,0 +1,54 @@ +{"version":3,"term":{"cols":186,"rows":52,"type":"xterm-ghostty","version":"ghostty 1.3.1","theme":{"fg":"#cccccc","bg":"#1e1e1e","palette":"#000000:#cd3131:#0dbc79:#e5e510:#2472c8:#bc3fbc:#11a8cd:#e5e5e5:#666666:#f14c4c:#23d18b:#f5f543:#3b8eea:#d670d6:#29b8db:#e5e5e5"}},"timestamp":1778706694,"env":{"SHELL":"/bin/zsh"}} +[0.0, "o", "\u001b[?2026h\u001b[H\u001b[38;2;232;232;232;1m rig.fm - Terminal Radio\u001b[m\r\n\n\u001b[38;2;68;68;68m╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮╭───────────────────────────────────────────────────╮\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;232;232;232;1mFilters\u001b[m\u001b[117X\u001b[4;127H\u001b[38;2;68;68;68m││\u001b[m \u001b[38;2;232;232;232;1m♥ Sponsors\u001b[m\u001b[40X\u001b[40C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m\u001b[125X\u001b[5;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;200;200;200m1. Country:\u001b[m \u001b[38;2;144;144;144mAll Countrys\u001b[m\u001b[99X\u001b[6;127H\u001b[38;2;68;68;68m││\u001b[38;2;102;102;"] +[0.000, "o", "102m Sponsor rig.fm: github.com/sponsors/MWhyte\u001b[m \u001b[6b\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;200;200;200m2. Genre:\u001b[m \u001b[38;2;144;144;144mAll Genres\u001b[m\u001b[103X\u001b[7;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;200;200;200m3. Language:\u001b[m \u001b[38;2;144;144;144mAll Languages\u001b[m\u001b[97X\u001b[8;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;200;200;200m4. Station:\u001b[m \u001b[38;2;144;144;144mAll Stations\u001b[m\u001b[99X\u001b[9;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m→ \u001b[38;2;200;200;200m5. Favorites:\u001b[m \u001b[38;2;94;158;219;1m★ Only\u001b[m\u001b[103X\u001b[10;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m\u001b[125X\u001b[11;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[38;2;144;144;144m Press Tab to focus\u001b[m\u001b[105X\u001b[12;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m\u001b[125X\u001b[13;127H\u001b[38;2;68;68;68m"] +[0.000, "o", "││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m│\u001b[m\u001b[125X\u001b[14;127H\u001b[38;2;68;68;68m││\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;68;68;68m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰───────────────────────────────────────────────────╯\u001b[m\r\n\u001b[38;2;94;158;219m╭─────────────────────────────────────────────────────────────────────────────────────────────────────"] +[0.000, "o", "────────────────────────╮\u001b[38;2;68;68;68m╭───────────────────────────────────────────────────╮\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;94;158;219;1mStations (10)\u001b[m\u001b[111X\u001b[17;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;232;232;232;1mPlayer\u001b[m\u001b[44X\u001b[44C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[18;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;144;144;144m10 items\u001b[m\u001b[115X\u001b[19;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;232;232;232;1mDance Wave!\u001b[m\u001b[39X\u001b[39C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[20;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;144;144;144mNo song info\u001b[m\u001b[38X\u001b[38C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mDeep House Radio ★\u001b[m\u001b[105X\u001b[21;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C"] +[0.000, "o", "\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mIreland • deep house • MP3 • 128 kbps • 8 clicks\u001b[m\u001b[75X\u001b[22;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;144;144;144mHungary\u001b[m\u001b[43X\u001b[43C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[23;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m││\u001b[m \u001b[38;2;94;158;219mDance Wave! ★\u001b[m\u001b[110X\u001b[24;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;94;158;219m▶\u001b[m \u001b[38;2;144;144;144m▁▂▃▂▁▂▃▂\u001b[m\u001b[39X\u001b[39C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m││\u001b[m \u001b[38;2;144;144;144mHungary • club dance electronic ... • MP3 • 128 kbps • 243 clicks\u001b[m\u001b[58X\u001b[25;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[26;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;102;102;102mvol \u001b[38;2;94;158;219m████████████████████████████\u001b[38;2;6"] +[0.000, "o", "8;68;68m░░░░░░░░░░░░\u001b[38;2;144;144;144m 70%\u001b[m \u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mBloop London Radio (channel 4) - MUSIC ONLY THEMED STREAM. NATURAL HIGH. DRENCHED IN GROOVES, AN ORGANIC JOURNEY OF BEATS…\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;68;68;68m─────────────────────────────────────────────────\u001b[m \u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe United Kingdom Of Great Britain And Northern Ireland • electronic,grooves • MP3 • 128 kbps • 3 clicks\u001b[m\u001b[18X\u001b[28;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m \u001b[38;2;102;102;102mMP3 · 128 kbps\u001b[m\u001b[36X\u001b[36C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[29;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mQmusic ★\u001b[m\u001b[115X\u001b[30;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b"] +[0.000, "o", "[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe Netherlands • no tags • MP3 • 96 kbps • 204 clicks\u001b[m\u001b[69X\u001b[31;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[32;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mQ Radio Belfast ★\u001b[m\u001b[106X\u001b[33;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe United Kingdom Of Great Britain And Northern Ireland • no tags • MP3 • 128 kbps • 5 clicks\u001b[m\u001b[29X\u001b[34;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[35;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mDeep House Radio ★\u001b[m\u001b[105X\u001b[36;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m"] +[0.000, "o", "\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe United States Of America • electronic • MP3 • 128 kbps • 77 clicks\u001b[m\u001b[53X\u001b[37;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[38;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mlofi girl ★\u001b[m\u001b[112X\u001b[39;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe United States Of America • no tags • MP3 • 0 kbps • 7 clicks\u001b[m\u001b[59X\u001b[40;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[41;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232mBBC Radio 6 Music ★\u001b[m\u001b[104X\u001b[42;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;102;102;102mThe"] +[0.000, "o", " United Kingdom Of Great Britain And Northern Ireland • alternative,blues,danc... • UNKNOWN • 0 kbps • 75 clicks\u001b[m \u001b[7b\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[44;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;151;151;151m•\u001b[38;2;60;60;60m•\u001b[m\u001b[121X\u001b[45;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m\u001b[125X\u001b[46;127H\u001b[38;2;94;158;219m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;98;98;98m↑/k\u001b[m \u001b[38;2;74;74;74mup\u001b[38;2;60;60;60m • \u001b[38;2;98;98;98m↓/j\u001b[m \u001b[38;2;74;74;74mdown\u001b[38;2;60;60;60m • \u001b[38;2;98;98;98m/\u001b[m \u001b[38;2;74;74;74mfilter\u001b[38;2;60;60;60m • \u001b[38;2;98;98;98m←/→\u001b[m \u001b[38;2;74;74;74mpage\u001b[38;2;60;60;60m • \u001b[38;2;98;98;98mq\u001b[m \u001b[38;2;74;74;74mquit\u001b[38;2;60;60;60m • \u001b[38;2;98;98;98m?\u001b[m \u001b[38;2;74;74;74mmore\u001b[m\u001b[66X\u001b[47;127H\u001b[38;2;94;158;219"] +[0.000, "o", "m│\u001b[38;2;68;68;68m│\u001b[m\u001b[51X\u001b[51C\u001b[38;2;68;68;68m│\u001b[m\r\n\u001b[38;2;94;158;219m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[38;2;68;68;68m╰───────────────────────────────────────────────────╯\u001b[m\r\n\n\u001b[38;2;144;144;144mtab: switch sections [Station List] • ↑↓/jk: navigate • enter/space: play • f: toggle fav • space: pause • +/-: volume • i: identify • t: sleep timer • ctrl+t: theme • ctrl+c: quit\u001b[m\u001b[?2026l"] +[0.296, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.399, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▃▂▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.402, "o", "\u001b[?2026h\u001b[7D\u001b[38;2;144;144;144m▁▂▃▂▁▁▂▃\u001b[m\u001b[?2026l"] +[0.399, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▁▂▃▂\u001b[m\u001b[?2026l"] +[0.266, "o", "\u001b[?2026h\u001b[20;130H\u001b[38;2;94;158;219mTracklist: https://dancewave.online\u001b[m\u001b[22;137H\u001b[38;2;144;144;144m · Club Dance Electronic House Trance\u001b[m\u001b[28;144H\u001b[38;2;102;102;102m (actual: 122)\u001b[m\u001b[?2026l"] +[0.135, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▃▂▁▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.399, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▁▁▂▃▂▁▂\u001b[m\u001b[?2026l"] +[0.400, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▁▁▂▃▂▁▂▃\u001b[m\u001b[?2026l"] +[0.101, "o", "\u001b[?2026h\u001b[24;134H\u001b[38;2;144;144;144m▂▃▂▁▂▃▂\u001b[m\u001b[?2026l"] +[0.166, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.150, "o", "\u001b[?2026h\u001b[20;130H\u001b[38;2;144;144;144mNo song info\u001b[m\u001b[23X\n\n\u001b[Z\u001b[37X\n\n\u001b[4D\u001b[38;2;144;144;144m▁▂▃▂▁▁▂▃\u001b[m\u001b[?2026l"] +[0.249, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▁▂▃▂\u001b[m\u001b[?2026l"] +[0.152, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▃▂▁▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.251, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▁▁▂▃▂▁▂\u001b[m\u001b[?2026l"] +[0.147, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▁▁▂▃▂▁▂▃\u001b[m\u001b[?2026l"] +[0.252, "o", "\u001b[?2026h\u001b[7D\u001b[38;2;144;144;144m▂▃▂▁▂▃▂\u001b[m\u001b[?2026l"] +[0.148, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.252, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▃▂▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.168, "o", "\u001b[?2026h\u001b[7D\u001b[38;2;144;144;144m▁▂▃▂▁▁▂▃\u001b[m\u001b[?2026l"] +[0.231, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▂▃▂▁▁▂▃▂\u001b[m\u001b[?2026l"] +[0.168, "o", "\u001b[?2026h\u001b[24;133H\u001b[38;2;144;144;144m▃▂▁▁▂▃▂▁\u001b[m\u001b[?2026l"] +[0.151, "o", "\u001b[?2026h\r\u001b[7B\u001b[J\u001b[H\u001b[K\n\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[21;65H\u001b[1K \u001b[38;2;94;158;219m╭──────────────────────────────────────────────────────╮\u001b[m\u001b[K\u001b[22;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[22;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[23;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;232;232;232;1m♪ Identify Track\u001b[m\u001b[35X\u001b[23;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[24;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[24;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[25;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;94;158;219m⠇\u001b[m \u001b[38;2;232;232;232mListening...\u001b[m\u001b[35X\u001b[25;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[26;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[26;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[27;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m \u001b[38;2;144;144;144mThis takes about 12-15 seconds. esc to cancel.\u001b[m \u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[28;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[28;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[29;65"] +[0.000, "o", "H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[29;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[30;65H\u001b[1K \u001b[38;2;94;158;219m│\u001b[m\u001b[54X\u001b[30;121H\u001b[38;2;94;158;219m│\u001b[m\u001b[K\u001b[31;66H\u001b[38;2;94;158;219m╰──────────────────────────────────────────────────────╯\u001b[m\u001b[?2026l"] +[0.081, "o", "\u001b[?2026h\u001b[25;71H\u001b[38;2;94;158;219m⠏\u001b[m \u001b[?2026l"] +[0.084, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠋\u001b[m \u001b[?2026l"] +[0.082, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠙\u001b[m \u001b[?2026l"] +[0.083, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠹\u001b[m \u001b[?2026l"] +[0.083, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠸\u001b[m \u001b[?2026l"] +[0.083, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠼\u001b[m \u001b[?2026l"] +[0.084, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠴\u001b[m \u001b[?2026l"] +[0.084, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠦\u001b[m \u001b[?2026l"] +[0.085, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠧\u001b[m \u001b[?2026l"] +[0.084, "o", "\u001b[?2026h\b\b\u001b[38;2;94;158;219m⠇\u001b[m \u001b[?2026l"] +[0.050, "o", "\u001b[?2026h\b\b\u001b[38;2;232;232;232;1mForever Baby\u001b[m \u001b[26;71H\u001b[38;2;94;158;219mCarlita & Janet Planet\u001b[m\u001b[27;71H\u001b[38;2;144;144;144mSentimental\u001b[38;2;102;102;102m · 2024\u001b[m\u001b[28X\u001b[29;71H\u001b[38;2;102;102;102mpress o to open in Shazam · enter/esc to close\u001b[m\u001b[?2026l"] +[4.791, "o", "\u001b[>4m\u001b[=0;1u\r\u001b[52d\u001b[?1049l\u001b[?25h\u001b[?2004l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?2027l"] +[0.003, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] +[0.000, "o", "\u001b]2;mrwhyte@MacBookAir:~/Code/GitHub/rig\u0007\u001b]1;..de/GitHub/rig\u0007"] +[0.004, "o", "\u001b]7;file://MacBookAir.lan/Users/mrwhyte/Code/GitHub/rig\u001b\\"] +[0.074, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[1;36mrig\u001b[0m on \u001b[1;35m \u001b[0m\u001b[1;35mfeature/shazam-identification\u001b[0m \u001b[1;31m[\u001b[0m\u001b[1;31m$\u001b[0m\u001b[1;31m!\u001b[0m\u001b[1;31m?\u001b[0m\u001b[1;31m]\u001b[0m via \u001b[1;36m🐹 \u001b[0m\u001b[1;36mv1.26.3\u001b[0m\u001b[1;36m \u001b[0mtook \u001b[1;33m29s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] +[0.000, "o", "\u001b[?1h\u001b="] +[0.000, "o", "\u001b[?2004h"] +[0.159, "o", "\u001b[?2004l\r\r\n"] +[0.039, "x", "0"] diff --git a/docs/assets/identify.gif b/docs/assets/identify.gif new file mode 100644 index 0000000000000000000000000000000000000000..029a7aa8fbd1930c298d92f8c5a94121f4038e6a GIT binary patch literal 144042 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
S2AR(DD zo`IFNb(oxXFLrh~SaE-+`zrIOB-Xhx2K97I-0Ly7Q*uW7(otIZ?o<%vmsj2VjRoq#1og+BASanf`VhQ4CnEmY!_XnCs-sY{U z6by=`f7k6eJ!tHOWfvQbXV>Uk4rNM$@@)M}Vwm-O67Q_LifW^06n_0#l9@rx+0E`S ziIzC|@&}s%^%V*2z4qrP-G?~4dNUI@`mv%}UbH*BF%8`&I!@s_K82_Blu`n#?$a>U zekZjojk2<4M>kG4r&ks6GKuyor7+PG80QXeyuaIxbgb2Y4lS9aIq&pfAft7quXd#S zuiE?HnJER81MR9FqUtsD?RDAe*!YaMyfo3(tvz1R-l3aNZ9~t6-|yn2hxV;|;`HBF zv{u}0O&YQ(f6$tpe6e3Svu;&vgqt^k-{z&Ca<>?|m6n|yFd8i+RqHNRtBX6IIrFlz zr1$gpR<*vCZTi$}C)GdKJSGk(enpf1{e6jIjV@XJA6tD$FT5ieNHFS*EYXYUHL0CH zc!$yA<3G=X#T>4Q`o(M|L8A}tv|Eu3W~WCsm*Vpcl<8_r)sp~_P;SL4# zB~fB;ppuU?C51KWDZaF>ucfg~j_G%$rdp(DtmdX4mpDh1<3)YZ<&`e+M%5;U$?}fV z*Q#0`I+wPdG`D8894n6>_vtiFqNxM2?ueI`7q_@1VG+SS7w-tklD%q3b-2gw+-P`c zc16=?cj6^%WZ8@xGP&89;`H+K(D+PwEqYis;{7jm4_3~Zn8%Z{f5x4%OVf%x_|JHe!neqz0r1I^&%9p{s$SsOUJ$vv#G|o@j$1meTA~_S z;{HdLlO>~Fm*D6{#UZl5mn9nhuY%i4r$&M#|FWtEpp>(qr2*)Cgg77DB3fx{BI;;Q zMhU3S#){T;j&7^!(a+9LWp$l2{*K*Hn}{xR)`?8|oB?Ypbta|Y@7|peRR7?a-G(#p zwx|r@bJ5j*Oj)_^6C}JcvD*sMc?J~I1+Z))DQUr$#@OEcPey%pNN=p~#hz-zDZ4TU zdfep2M_&r(N3N??MTx=gsU(G~Vb`2#v*}9l6)SlExJ8!^2CTcfQj6A^=Z4{K@>T<8 zeI4{Yr+{g_cp2LFxJP?6Fj@Wo;pwd3ntc4Xy^UHBqq~(Z5kXQwy1}4fsC12P+31$; z7~L?sVRR!QAtDS=N>NZkF!=KRJje0;1NTom?&IF|x~}sq%@Xd)p9H@fdtZN&`HU?n zHfO348b2ZbGA}-rDWtvn(BsLqOM|6{4E+Z=`Mu^br<0MubTW4_?xMGg<)otG+KOn>Fr8))ZKkb{l5X=w3w?BjjesJJ_2!s;c)BhxcTAGsQP&qWV8|tk3jr&LEgGA<=Us{d4`$ zb4lxS@uG8ut#k34a|rfaqC3k)XJYeck zXgn!VefhL|QQ|{Bax-#3Z_(bZ$wb6iOW-KrXh=lr*O^;Jl46G+w5m_HGqSPQRsLHK z%hXi{!>13z1IZ_399MOUmQ6;(V5 zNhLLMu-7f^TAlne4GDL40$+AU_1_d6Z&c;mWllf;qc(PZEDtqH+Ds!`Omyj-)`z`J2ZBx!Q8Ct`#2XHNA$e&g^gYri-kq@%!L-bpJrXBs{k(4x}Ad>`2R>CU)q^FOdCdnczjO9s+4T~VDkD%v`$jXmMi4fo| zA%oVEw)KgQ^mbIG35qr>M2v|<5RoiLVEa;=!-3-+T`9eSLi8W|8$K;=#%9G-%pNzl z18eHXrqe{}hp?xeny^*3VG?~J(s}a7?qq9E~XV> zjr%y2Rr=I!Ak{NS!e(eXp!I8{ZpuWH1U0XJGlTsq&r)aM+C2%LD{S|0^F?`?*&74y z$-)cE()^g3XDxB=Ps~!Zzen_@fti@U8niaOHN88Wf2VsMI9<~W8JNtw^6L7%4pg@Y z64NO>B3CTb>!o&F-6qd-sBQUB_S4)}?6d0BG54=EZa=C=_3XpP_!$Bn`vnW-Ji{xG zU4{p9r(rpEeUasgh?`@d+o%;-ceV-qW=UrQi25T*VfWcJJCUb+c-_QSnAD+$w-u4PDr2*~)g1<{h?BcG49)4oQGp3cR|lSEaG1cSb@){Mo( z7TiJ-fOyc2B;~rIaW86e2&lo|zN{7D#;pq!C-f3AnJs=oU!Gx>RUq+;6JmTPW#Gbu55YZj~6d$wtD zo(->tgH!tZ@loALE49ysCb$Qb7? zow^Y>+4B_R@|u|4x)w>l>>`nQPrfP>`q--+Pqmu`rEzjTFQv+RVSJ|~#@3D(@}B?i ze_-3c=WF(jh6U^95xlCc&?VGbTdXGrENFoMMKN|F<6v$DTtmOlB1HS;4{F)r_0p19 zoqzw*bfAlstv{aG1utpAy z2s#m^Jq$O5+*=#)WOayaGaVtK!HU9&YdGoi3E#?rhW&cQLg*hF{6?(}I=)J#5-}Np zRuT2xa_Y41&ZLmt^B?(IP}{CgeLJ$_#2_bY|{yNyugPe*ov;dq3(Z) zMi^q~TQnfVan(uF;H?8XD%Fu~EkbM)BI$Z9>p?Ci^1CCB-V+SLCKxh6?kuqidpr_1 zJ)wb$(dIBzk6-6dK9(0!dC<+LKs;~AUov4x%*3IrlK+DZF@q7->PlAUI*CdKluD>z zRMtBe9$X-|h}>S0@jiE?5}E(}RD2?qv`jHdtcE*u{dCGI29es0cqI{`spCrZBlUhT zAqT(BpsL8r3~+1tn*XGl6&XBj?L{SM&0a$#Q=g7_sLRNvc+p=vpPh2Xst{hp7LA2Jpf-vt&?okKL_^EdlGUxv*+g9dQ zI2xVTJUOq} z@ZsOzc5SOD9KJdlPp_|ZU$kKp|6kYEGqbsUw%*Ne`ore+1r|dq>=>%Ou_Jk>P5JMw zhiZCb@3w0@U$FGzv||0htfM`(yxOyI`s262%bpwj-EZE)Oq)LnC426F{HDr*Cpa|3 zkqle92MMO4qYOt#;4w=<$J$T-yddoN1!2#QWS?AIE8=cuMf1dw_$$wJ+}>SC1plB_ ziTE#Ep}%`@`SuoA`(^L4d~KBMf(=F9L#Bg_>OlHbG*RcTQ4w+_09+A}Af%W9!@J)N zRs@jnmW+@Wd&tsp?5ad?jHe-+)W9fI(kn#*HUx@L0C;;aKmlMF5~3s)TXyGHL+^q; zz;4)WUoplAnIyG0!iz7+R9?+CWaB^^E}w+-%ZAboJo7)1?sBO|j2T~es?N<+5LtAM z(GA|$JR@DBD|+%am`6N^8jT|IM*v9;ZjkC67@(|i6fkQARY8Drq>s;KODK#;ZZba9 zw$J5?>Tl-t7jn>tUyl?3?#UMMNpM?SL^cOU|E0EH2XE4y}{UPfKQ#dSTlsSf23L1*Nv_n+%oQ7UeiM*EpP1~RUH5*! zWO{dJS$)jb9Zoq_iFx#Ph5TEuOO^HATAx^h4cbpps69cpzy|?}1azI~U1wd#!l3J2 z(aK|lzM*&+uItf(20R|Y^e~_N_QPCh|)#3AKNTCX${(VA46Q<*Biu7ZSWyYAsKM)&7?k}&$le56J z#{Qpu{6#bTNw+;EGH-y-_k89v-8V0NE`8l#cmka8I1YFX z^l|a?vdgs1QdfAfLQgy4&L(CXiwI*v5)`TdNyU&^e(t%+?wn#4)box%e7!yyLl(23 z$h{Zjyl%b90LE;4Y6HJll?eHm;8UMh#?R5QmHf}qe-`eG8AuR+_r3D)(_W!Q^t0KykW*_ zVQO?BANw1iPd4~rRX9O5_^WMnfk9;4ugLjvK%IYlCpi9E4V=Q@M#pRa@&Gy4Zfm%j zAiaWmy%3g;f#7-K7n9?cqoXXdfCZhT*(R}R*tmKPumToPN}Tk$D%LzDJm(hFwFi~E za5q;%#@xz*jUid>@b4KOg&4%h3c#Bd@K5 z9iuLNc)>*K4=MX74RH8XUbLp8BS~EIIKnmnQMd|x2l4la26R=&%Go*QINFc%11G!S z4{}~9k4L|x15EP+zpVzO!GmE)0tHOg$E$)+M<9AKBb@_i-{Jk}yUbye%}!0YinV=MsAC^b;!EK1401{rb+PvHapmn>!|8Y>?S54rBgBmk@aA~l ze}O(vPvgJ%6vJDTB5fhjUhK?|Qs_p8GKLq$mZTZvyxNa1G{{ksft+S$coL^}t7ihi z#Sj6MZYGeun#Lpmamr{V!swA<;wvwe_V7BQYoda7J2GREx;WdK23OY7ZpWDH_hJgr zb?73ImG$7LvXik&SJOg2z{s%6C%q#ySkp|`&wZ31EhuBHo_&)n>6r7yH^6BU7QzI; z+u7M?mBIpw!XWlN>$Sns*71if*jve4EWlRXRS$}yTr2EZ4fH;Wmov6A%!J@%AQQZv z5Pt_bUP<~Rw}bu2TZD3-CSaJ>PbkB-CX4$o1AtibNF1MB%)Fj za_kA`8|W}e-ID==>p<#pY=mO9YG4C!A^^-7G$a$VV9yw3ht-Iw>(OY8rps@@*1tZY z7g2ALKMIkkaAdag`Mgfw9a~)!8)2J?gql4&>;{5?O*aDhNmx**%=sxmv^B4x?uS*4?|PtFOCVb_^Q?x)r{+m+4X3)R9I-c%pO?;+e=`$Wm9bXs zSI~$Fl5`x)_$AbC%y$#gNiT?M_UoCU?+wgt=$Caf9eY`(ibPlDy^CuY(f~*AAyfp4 zOw@W_)zGvCwcMg^yWTr%!TR=P{B|agPe}q!$J_Qb9Hu%VQI+-yzG>ELR_w7s)ho9u z1+RVWm{w-@;n9~2kb;pQ%zjOq__eQ6#|?#4bzuu6w2-bXJi3B{x%n6#GOO0Jvgf(! z*!RV}zUnfxX1#38(f(6Z5ea=`+$B!%Izphs>DzUdcYC&+O_Q{J-yb!zn#yW2B`&b}iZmlgJj>k41c?|faeaZA)F-J!9dhGd)yvvR1 z(;gK}a1hoR1uC`;n>!ZGg!0wgw75@c^pc*rJOHwV6KW!ao>-tu-D!-$Dg8x z+<0(KfskaFI#4;wdo^#M2pnbEn=M!AQ~6<1Vb62fxi1sg1T)Jbg3S%d4gs^BPQF0- zvZn_tJ>TTc9sa2|ws`xg4uN5ePndQ`>vTQg3^M$H@CCmetfLtSY$Gm6Z|QATf(`Zu z55`y8*VWQISM&7?_F}6V-S=;4Qo<2hRx9w#*CyEBt8p5T>Dp`?8|+THiu7&Q>}Y#B zNA3}b-KS^H_exK|n%Lc7KDu->(}$|pFU9^bi~nkv$U^o6(gSmy$t3N|wx|tjpY*B> z%w?GJt?2&pXL9kwE1ux_i$7QrKf8vRmsrx;2yFK3OrdK1YS)Z+OK^r$0P=(E{1csE zp)BM_W9FHJ@jd$yPxG~RI%!+e!9UNv&Y0IO_ofO^19Nht06vEUx%WjZ{c_CH$(Qb@ zs-2Jite)YlOcUeZ6f6P}Kvlklq2u)iGN&gxLt?TW4znK;ET;&xTPb=-e^qTv=-Nsl zGQRS+hwbA^d*J<+!S7AR4dfuo1+Q!`2anYpHfCPFR?070cLlG&$^LHqV(o~vbj`CCgsTpz`y)xZu`;D{^KCAu4@fR zM}y*qaW%raV6y!>=mVJt7uz8Jgm;}ui(i*V#7fKasEDT;4kIz8#}C$GqUH)u@RmI` z&9k*7eXDYU%}?qAgASIi#TpVan6@sC+mOf)PC;G@>65-v|GW^Cld~nOgN{_;@9h=6gHa#X7g?L_D^_5(@}em zENgQ+2f@d-ko|q13K#2d!B&U1`LeCq@g47`!{saToag4>vQTdIy(yXt4J)J+>FCHv z4o^eGKdCIXg5KD(llPegZ3%>oQ&U!$NUX<0Ji_Sx;C^;@Sefr0TY!?rYkK=&|0p3@ z_`@&uF|)(wgR=^C3AY^@yXa3(?tP{IX2v*Y$UNuq#$wMy3Rrd*xRx~I`PJ9u_sWl} zQoR@(qWnzxxL0sMndJv7r}dra*(qYW9Fk0H0d)tUcCjaa(G@Z9nVLhTHn8#lD@VTW z;X4t}-~3qN^y+d@s3W{gwK&0}{MqvYjjEz*{?H=E%Jh%)BvF}n_bN`l1-sd$NaXzB z(l#V$fu{)iPI=8XjLkf&%FebLgoSaHJ)qxNG(1-tU4AJr+xO!&0UO1dgviUwc zHEjY&zJK?b{@xIGbpeKBNul}MZ=rk{&XGpI?4D|Ee4zm{q~_@f{XI$R{#1o+ec|X2kE;-EQz+L zWJ)oO8~l9+EK2O)@%(`Xk|B9;z7q*GH4p(Bjxi@|RTB;xRSy|n zDB<8B>1;#o6Mkl~!7rQ)D8%H$Yz?iz-72MSWOuLJ!Zrhy<_UAaur?le?~8+weAS>V zYu8bySaG3j?qqk!rvKW;1j1sRMqpyd)-UIC z2STGkz9sJ_h8m6MU#n94r#$OQD+_kGGtX&JM#{#-Sic zv0ho%U*v&l*`yl{D3Nk|*1~C9O}&D7RsPyG9Yv%U?c@eiM5pSxMr$N#1qr88Skc|E zkUNdxg*BR*QO}z-B(NXSBQ$OO`Ngq2Exw%q%iSn3th&*fRN!#=Z1upzM9`eek2>mzktIX5Rqj6D)7-Nh6il1m$t~_ z7}z!5Muz!16CH8Z*J%>H*>=E8#80fg%SjUx$<1j7kt8D&Px9Z6QmTo09;0(p5nd7m z_a3K<7i5DJp-sp?-|=`(EQwEhk;I7im=reNLTM{p*?RDZ7->XNQ)$>0_-@A97ydo0 z+z-0Fa2%x3OsJrp(Eq<|``uJB=kct|p+k9mv+XU|*6lhkXPR%E9}^y_Z^gpnz_mbYD5P|t< z@GaO@m%ZL;@wxk~&#F}@nWUi+g|g3@T~We$wOP^Ze_&fOsj-(N2EH4<`uXkE&Res7 zTd!}(9@cxUvifgd?O7geMv2b(?q&RSq}BNU4{W=S(*723&}qfyv{zE} zAK3OM>Ge^AyH?;VpkFWOxP42{<4foFP5ZBTxpP4$LlpYG_+LD-0jE<^2R#)yQHqeW zMg5zyZ||(XTm8&YcoTBD8A{QwxDu`Z&tUz=d@AJXsPXN;Z@V2^|E@ABC_?{UZ0TS9 z{uM1cPXb5X{Zf_~YI1cZeaieu0^K{~@g}&pfaN#1T?TZN#E2Y%kz>L@Yn4C}Kp8hXfA=G0 zPv@|&ORT0G;WT23M4}pRgBj*gnsGOt>4|A~_zRwE%C~udNWkTH$T28PwY~au_K5qL z|CGhiqI1QD?SfHGrKGq~N_Zy@2EqYU*ziOm4{<;h107>xJcvGf9g-gapjO!dt=%Ca zXz0>$Bp*%d7pj!jT$%RzL7MGPWyein6Q;(qL{#@wiTF7-%z-T|H`;#?x?u>QCrrHM zVX2B6V>Bp7#KnXRDj%~8bnG?>2Eap@WWT=~qwV#AC#dWJf0Tq7NMdrA(s>?{cmU89 zrKKq*gOJzUVFbx7B@*@31B;GN(k5$AQ@s1_*`+hV$Zww#^RVxuScf2U}dr(h0no2`+BJ)m!_IpZ190~GRR1dwtR<0 zi+Cq?wkpi0G5EoX@$c^2?Mijx?43Oc>%ixwNl%MLRgT_uN-uR0D-!$M)w*9${S4>i z+fs2YXfMpOcCX&3k#V9zJyPr47~2kElIkdsblR|p7(pb8`7A+$1TeC2G!z}zy9LS`sq_-)cl-hQSF`jDJg*5@&+?W`hAvCDTCFotI%48O5)$~uz& zn*GNli0Pu8zlzYugU23zYkFhuv&$Z&J8>)l{%61}BZ1?i9k zvEqG!w_kvQE6rI0qAP;7(-*qG6*%24MnbqVPjH&%rznG4lEx)1_;TU!w{Kpeqq%7Zj zUSwFOfd@})CCk$ATmhkkU+)n(J|Cm1bxR%#x_u|mM z(s(=eSx4mpY#y~hFweM5Iz~bP1%|PFM3c*1OHv_lAPgG-;=n=q(s+ch1bA-uHWvs( z0Hj-<-CXvlhk?fCac@{a=)T75wTdq9U0@oTB&Xp0la!uPiqj(pmreCVd$}+!cCwCf z-ur96WVOXp677>gpGU4J-N1_QsP7gWX(EzJ48?v;`mb(7MZo4ylV8@$Bp0b1ih<&s zzkB=@@koMlpb5o0b+`K_-_FN2&ktzr0@*Fi2|_A1N#QSSI?bwmt92As8)E$f+A|pn2xI$ z_y7olD~2XT!5^POUMkTf%mWAPfM0naba)^(3e5*Zd1a9bJCN#Up}|-*^ENsbaYOo4 z3fid{CguQdu<>uSr-e#EXANGrrMpTDgA3D{Gl8T#skUszUbjP@0(vHVF?u+a5uEIf zSd8dLyXx_Rf076)7}3A8XW$2i*`FeZE|3mjKP)0rG)9LGg_-PSzdl=d z{XLm&772djM@fgGS~uV`Q=%fh6r4?QQxpfs9njIt1J}gdg}MAwuyAo8Tk-9;j1p-l z02Xt=taWOMCp2sOsI0SqrIqrFiZ9N|yfCR#dg+EmCiblZ( ze)zE^)1sT`^Veb)e?iuYf%nJ5tZ3lIVBWwHq+AnaE1c=q9`l034O4>H9iSl}6$(~$ zLh8am0rQ8HDh4@pkVP&&EpAHmkMX^vj|p|~copt(^H4DSA$w#e?Uo(*;DCVaJsdQ6 zJF50pSV$(zan6X*7V=1>JtQEV_eM5HC>Uy!y(ewSPWgV3Ld^)6#RSh>fEy3sq7Q|d zW8$X~9AsU7_p6fiR#Qg~z#|NRt4w;e1NU|gdWw>0^eI({gTaj*<3B94xf!;QMP7?b z7Y-MdwM@0)jHbf$Fh6nZmDe2(kcr+a=KHtHV6)){} z)=5U)0iEDaJTin8D+c(QD)<~0z6i@YEzaVS_6*=HoJR38Lo!sdGFtp{ShiXJITlsT zXSh*@HS&_RJJQ2X{ICzXz<|7IF@|jA+^egil#|404k)N5HRlS`7XYC;O1+y!O6Zi^ zqDclu`Z7&%Wh%ibAg`Y}!nLaMp@EP;6F0sqNSE@Jk^)4*aTEOZA6Np?^?_0njoPjM zEb{|Aj>@=ne~(}v6L#A5=)|%7teM?SQg(FP!@>sKe)tBEo70D?UFK?QX zGnWyz%=P@%k)gB->5~@P_n^K{&qQtpe@cZRr4O+I@rsl<3Za==7%&GhbQy;X5hXDv zO_lKsUWsv3v#0>4uGA)UU0u!%1PkZNok$-nuA2PC^hyah&Bv}5M)%y5ZuNaI*AZo; zCo}=k2vefV!O%Juhf%|s{GjYbNCFm!H&--_-Y7Rk>2}rY$M&9!BHDEX&UK{~nj_6R zn{3;9B;NvU{&TPB#IPtWGd2h3Ew&IdfI~6^X`v433PX-1UAaH)p=~FE69zPo4jCp) zsh1sc7?}V?2r}g_)N5|>6#oZ9YHenQ50uQRzsZEwl8y%9mOyGeXWL0r1244v z4XUQ=2Y4!)>93^s)*f^VK&>&6;Srsme@dn#%iglh{lE|=dxWCA87Dm94N zkll>ay2_&dJZ%2Tebb!i%zpO^Z>J24d}R>D)4V?1L%5r{vD~J6 zsv9}#E3%f`ExbeUekaG5l7}@Fn4gzH!vU-jq_3WC#SNy=nzCZeLk6^Mx_YDkH_JX?Z17X`ceaRmb-oy|5M|l*KM#%$+pZ9yAUd8XMRi z^GX=MC>?ujG2ZVn9zZ(rrDa@UW4z*Y9Gx(Mzds>sF%j=^TYs2bZJChSn20-_NJ*HS zzdtEuF^Tq=%psi`Zkd$am{d8PEKZo}yg&88V(PKSR5j^zW6PAp#uVS_R8zuq)&1%F z7SkY)=`PZlf|hCVjp@Ua>A{4VE3eUrw3$PLnSa}(vqH05_h;_?nVCk;EY;11KA9B@ zo-G5|eh|8u+uQ{_Zzna8oC6Ko9?r}iZ**>dojaA2`y6Zw5}N%oQ~smwZST^o@SoXQ zs@dN{^WD8OrgC#PERgps3;~~XD+JhyaF&PAg>Bh++5*16bwl6~@Wp4)t>=h`qkss% zAcQ9rQCx`TFa=_a2U9@YmWw*mx^og_{74P<2P{PRdAjLU-teu1TX0SO8;rn7p#&t&@r;obq{w z{d@zOvITWMc)(4z?ETnW08h9mZCs%$+3EwzI)2)`yf{@3V$;CPvUs(vo*|fZ=r!wn+&yEWyYR?*kifhfJsxyRrpZ?!HDa}lmY{srv94qRxghGPy*$*vo}nsn>#iQO({=EVJPQ*o#O>HDVDufU;xi*MQeuT0aI!qq zKE#MGV|@u{bR=w0J_@?8x63DNemu6VbbnU}^>pXFt(0R2l%l>CsX^(w!;`c_UAHrI z&-kIA~i0 zmw?nSX}fxM=Y9%kqEFZJ@8>yhAaBUQb^ZZS?*R_IO}(d|oTObV43;I|Zn#50USR=KJx3xENR*g`M3~n2^YP`|g&m&wgE* zu4}pZt6jo4Z{sPe=c0;MXMLoJtOn$p$CrPPe=&a>NCDn+-5n_S)bh-n{ku+%iWyU+ z#y_$jYoD~<{oSXzdB3Kzk%9+xpYPxI*$@x;S_;^Pj2RID^e8KyU6z^GKUf+u0Eicz z#x!jG-Z;gj0J(5qM+WEHUL8z=z8DprtJwIP6fNnBUX)@_lbO#4InQ(+T{v6cv)$^n ze|zEaNW$$=Gg9=@ukpS&Me~agQUC9kD#NN*3x%^RYN77GqKnjCM&101r?~H+26f_@ zclE7J(7)m>y=-;5%xJuFy*azizsjSyhI?H#U0;Db(ssWPgq`?xad{sIa-go*YTr;* ze=j)(hMp{tpA`!>d=Io0$)tZ#d%E^? z{M}8jw10Q?!{T~^7)%%z9tHz~34w9(35iKbgy47uLWMVP(lZlb)LDh`F-38NQE`lP zOnK!cbqOi;*aR9FAzK?fk(!VbTu{eJNY_ruyGI5Ae5yVw;*vz$>B zL$?;!x|~2=8xQ-meGnZ{b_iFHT0cxq{c(=Xzql$1lZvAW%UubWz{KPU!`_|ohoNvo z_f?q)-ybO&q!7Yb=@50l_?Jrkp~u3^Dxxez?CDyPfqVi_C$hv|PUUO1RLqjGi_nT8 zS}NZbDTYH?wOXqTb0Nem<%fzWg)9u!=b(dotkW+H!8tVmn{jmM~c9 zfc~eDP}Rv=iI;3TP#E%_O2+Itl|^^mRxhz`PGgM%R{K$nPH?Ou2}K;w8dT%^3z8?D zAcGUcb}f;L041IbP&{m_I)qKR%QJ-)?283{c%t zQ>5k_W9RFqPVWHJfe%VJfP;xMzqOv9dr$#EU&{59_srJ*jWD!@=L&tvuiI~s#_5+cMTWvv0^Lq?Dzukz`&B^jH$Z{ii(4Q{U)DS z{oyLSAMYq=@UaP+QX*~qZ`&%0s=UR7RuR-Ctze(cQ{H(0zqZMPQLy$GgJf)V6SRb+ zeQO#%1*kJH7gNA)R`gbzx`EF#JN#o6Ibz~Z4xdz|ltQoXR%;S#1ZG(|Bd)*&J{Pu_ z3hoAvHmhWdznyH^mxG#latg2CZx+_4S8_#GY}`y%hBES`m!*oTz5t4l;vSnm#d0nd zDaibb)v%**9MO8li;goAz33t+vr^otHV7^a>~H`Wk7gHhKkUEUP~JUvWc8mS68wtA zo?T4njqucdZJv>ob@7~27_u;#qg9C`X_XkxaD*Y-D_*3Hv}mi*dACeFOe=6sdb#HS zqiDAk_Jnq|W0j$%=ham1ogWuLIs6QcPaE6z))tLT+kY)4lT^s70kBJkv~Q$8w+qG* z>NU_P>eTW{bm3GqYr?J0DRd?2BcrO|9Ms^{H7To2J`071e>P4&{KWn2m28Md=$lcR|@%u zY|(N!iqnKB>zq-=s&-AIpsntfpZl!#$w^VO1M*y6^z!(}Y@UobxiBNy=8MhNx`*Fq z=U5eNBg343Yu;fZ1*1Ff9)g&cu)h#ry_vLCz}f=u=_tjuiUeh9$?x;NR>hTb>WIEOXISn01gg3PqP2r@+GwFy zwksvkAlg9*7Y@8QLyO8k(4D3n$W4X+7WDlZA1Xf4md6#&ML{@yI=C|`EYV>yp+)!e zQRAI5rQ{RFcm1cLh7Ne~bUavi>;;-|EF8!@^7JuwI}1XL3B&NkOMT_e>p7WcuR0n3 zGPDfTePtJu%m3mK-wq2<8u$ODtx+&1*~I$qyLHh^n1dN5k61@+o;m8<{MCm!xJMIul#-B8c7 zu)qccCX%ZP?Ei{~P`(Us$^xWN!s+>ho8W|)i-84KFLhhH;v#y18a@&RUKHDRt}-We z9FdKbo6Z#ymA715s?p$^t;g2#fKvWHlo3=2BgPYDo&oJ*yL?4tT!2}W{+u@^O} zjO-qY$qC1tluau%MGL~Tz9p$|xMOZMiFt;wC&F{5dKqflw3!LIR(HcbPMT3czGp{q z$0&Z}b9iW|);TO9Ex{yfGa9o}tY+@*0sAAAs^aW14k|d&e#E|3tWW!v()0tZ+}F~0 zq@#!!iEE^i>QRia$PhuU_I?Oy?i1(3C3cjolgRgnM%4(N7~y=IucX~WyfWieqXuT2 zJM;h>34RWkB96k8OOiN!F+H4tx07u_`>O#UmRt!ZGMpjFy`W{@*ZSP**v?1-q09 z^`+&^WS{tO>Cc}G?FqE{AK%{l77gbqDBWs#A6VHiWZiat&cyhoDQv)6!NY04(uznZ zuSdN{GbsgvTx~~WRxs^cf*2YXUJs|?4d2TLYUZl$5b4~Ee~qH$nD~c9cCoO3`T`Fv z8lJe<#91arz-fWE%Do}hKF8jV$c^xql%qi(xvO0TqjbHrqjCQNMQ4zKxH^7JqA%nVxe=iuMJ zw*dMHSxqE2cHVW*+d)Yl(v^nf-h1B#9-ZxS;k(`#8E`fG^na5bme-s;X^FF%=k`Yi3e%eCF`Q(i(klpf}$cWH2|WUu3gO?uSpt zJhjuxjn0(W{Iu*ie%N}X`{rml5l~wrTt7toyJI&ZQnTJP?wJYRmo~V!!T4FHft&4{bpMmDpxUpJ+MU`Yd-E1C8U2HO(LB+;ea|f+eyT{?oZ<~D4&?-t1U=8toFyv4FJQxHR%zz1EE0$t*YyG%u)KY5#}W34)@x24oY zIYVnb9ESIyuRmJ>vb`InAO$?G2PeLJ=`g7<75{x-0YkqfH2^u6z*oCq`A-Zr#eswe zS`|ocf^s;*i0SJYL?@ipnaT>Q_VP)(tPxtP49(h&(aE|Dm!J$tBZ*KkiBQW9m}?GL zo)2)(1XdWjYTXwAE=h3|+sVCj=Pi{@q6U2DdiYjMROh~!hcCBuI9dFYd%xyA&%|WQ z3~p5BfTX^~5@%RO)u#_ac!Ft%7)^JzE61RIpC5b=%y}iQ9tmYi@p|w{)OyLO{{noH%!b3MJkN?<+i~PDR5yDXZF&A$&`uoT z6_T_pBlRRy%_}tP#M&JAGzq1mzAG`5DYf;9A(DaewgR=n9sPngz6~CAR1rC=2#Ik> zsK7+KF^H>DMTse)o%W$TyYS1O0^L5=UpVAvt0brn0tA*w+ruSTQQ?eem7pb#M}#j^ zek2B0c?QNv#G~&qZo@2wAMW8{dTSgyFO%W{6#hyOjk|BuekChqQ;+{(hMT6)9p3nB ztO;rHk)3!*-5rGc-sK`5g1$+GD@y{c$_xagU3GR0p`*NZiz&h$nw~EpA|K?XnuRr)8n;O5rG#A-vRzHoQ%2O*^a# z*xTYgOyDp>b|~W?lJ}dzlb5D>nGh2>Q zmT(ExH?+Vfk1Wjqk=KWUP#?{(!<67y%Y_t1PcBvgo@^WG?7#=7*P`!GHH0fH?Guln8^4Q-M_Qs^%DSl#)q8oGt^zz`VM#{HOmoT(Be}X) z;ZaxNWQosL(~$3sMXG!eTl_^A0YyW~h0`wze=%}oZ~+IASuQ0mN7=_ym` zEl??KR_QOGD=#C2%&mNVU5R3z)ZTsgE@8P#2tuwIp9mJ)GYl`6mz!z2_Z zQ=Oe#o!edgj;1>Qy85wU^^`|7#;m3yu%@bpxiGh;j)|%ykfm(Brdg)8)vR_IThpFf zi#@3sqpa<|uEjCcmB-Z%nbiStwWHg$W8HN#>vi5*b#uA36Iv`&O!X^)^=nM!^SSl) zGWElT^&3nLJ2DNt-SwZ$YBmK}@PQ3q*Bib~74BU(S=N^YwGf7 zVv}vYW8N&j(8TkloFkr@E3aAPceB_ul#jXPS$A{CLbF6(i;Q#g{hk&*rwG633NnYUlY zm1#|t*)f+JFexbav?G~2asyjEKNM^A(72m-1om{GwK{^QF@8Zb0lzyU%sXEmbwqtA zLOavorvPO0fJaDe`R&exYn<7;Q;V6ArI`y7xuq{9;6Z{|kVrD@ zc0135=b)Yk{O9Mx4AdF)#UcAD30)r#8w%heMDYS%e z>R(~h@R2wq$g&Phb^@Y#*Pnu(C_3pPF__GpnIJKsEcya_DmVNjVLb8H}*&~1hEkAcv z{i8yH2TlGV*peL~-6)AY^g56JSe%JNP17SsZ457KTj2Rxq z;T~BJ&Vk~cFVojL0fVG8!@VQo^Rv7sv&6!q3}2^+Lx4>}v*%wS z;lVwk_?!MG7NeWNqx>h`s$XG`>*k63aD|E^%k3ah_;lQ@Q4Z5Xj|6r9nfP7^UmrIg??dFp_i1A1At4v>(yc2I} zPSnG4BhUWKedL}@6dU2FpIF{_2l~2dr#ncmxZrHDOrJk!=0a+jI5;9U!kRh@M1Wja z0U95{S{73>y6;L1#xfG#`h~2^Y4^v8MO0a)1bn3aG7Wfi0?MuNLm}QI?Fo|>R z8-k4p2@^P302*tjROClUa3CQ06eE1>vY==2FZkWx4~i^(0`ReT1pYX0kUVKl!eyyd z7+;b+P{FZs{BZ|9y(z+G_T7>if31;M`!FeJx3&Nzf?0Yj6d=C|eRF1teFEUe0ca#| zkx{q5wWW6}04}UE5eH~)14@eA*63euT`l{UHE9a{J!vn>~Kmu7jKI z{W%)+48x=TJx_&w-rDt4`+jdWq^kmTxHG9o;XaD(U>ma+rl1fcLLFj7DqwYxuz66Z zc#zZ}AI(M`%XXOg`mhObnEkpcwD+*^-yw$Ws6^qY%<4$c?69Kn|ERjlxF-MjZTLG! zjUL@G5NRc(1o;h68U+IhLAqmvwA6^v1Ei7e?iL0p-3=0>LsC>yck#dO|9!t+_wzm6 zlk@l?u+GGy!vsq^JC`$ z;&YakGdsnnQ-i}A^7r)k2byBi zMW&?RVgDa;PySq)>X1aIvZ;rMmg~ey<;1__Ff5FYIvXu`57^B)ZI-6F48AASr{MZU zcRP#XyD_W!w|Ks6N)VVfwwswc=Mmt-ep*W>&k3|3sBWt$)sccU(R= zCH_`~vGW0BEhd6|rmm(Q#Mfu%lFr@||6S&`9hb}=m+@Fd^UZ&y}w&F9R zOn&o%OHu!q{q!N93*UPt&c!MwD%Y!N`s<@0KK{;t^ zwPGAjjc<};8#tSSU%lRy%#Smw;b3)@2qP` zmT2YMJ?)bFGuSzwxaoypOaeP7k0)Z9=Z@|UPmb-&=Ff~Hp1?s3sBvu0m!q#Qum8(M z;Vc6=p(3h!HeOyRxJgNgDjcDt+6^~Rz{UsJs0PCKl(6CuTW|e6h`QIcY7N%bmWgX$ z$5x?Ke_=i7vh{l5vCZNcBMavH4GUV-eh{v}_>zCwTeig{=%#(*MpY~I?$LiLe#z9< z(RBUYtvX!pGEE_}q4wtNMZ=DEluReCZ6cSuNZCL>=12zUc}9&&$A2>*yD1PbHq zxcBu{B3C{j)M6NTNZ$*hmGjb`cS=%?f*A_1K2=C1(jW&&?s+|83aSo!6fIa1{hmiT zYENE3R#j2NU$ywkqP!9*(qK!(h>j|6^qFrhUwk!=ln z(Avmu;t^JOtG)Q~v#YXM?oY$|9ky$bmwW!C0z)O)Q(-NVavZ_#@;usbT$10Fb5pjQ z-S(A?IhlDw2i(tCwo@>dhQ_`=(0mn%^f);Fyp&lX;P`+z`-zZaee(%Fo0r_;nv zSPmej;qV3F3Avs*;Y>|TAbuO@?F%(cx=p-CYb%NX|9%0T35>mi4uem8C9|0&?os3fJ;v<-l^;tf`?B6dHuOojDw+yl%2MDv=7On>X=_v7Q6lbnD)WtD)>%Hs zgVx#p|76mwGQA0H{$JRZWWp|*`OlJhU78~3)oIE0mh&ELBO}ZVe4Zb+@b}Uf#(ev; zG;kWY;!=Bm{A&}oD14g#LYDo}%OZjg&?E_}qSizf@Xq1W{8F9l%5J}+U#YaeOy z?+=3;DBpvGb4X$Ae!O;|!N(WF)zwDtGMm{eY;>yg zxAxiYA7++9Psj5gbdkA@h>dHe<)GY^|F>&fBy%7Ri|=a^=->{ewtDF4lt6_D47C%f z2rHNwmRPfR%nzqkJzYlk3x9=wssHCS$*mk(xEw@Kssd^1B6*Yhou1B+p|Z?Le5LTq zM~0s;XlC0`2PzXRBH>j}4KsdS{ZeNx{8Kyby^E!mfL&m$hLK()M7(mm1@ojw5G=f# zq@f^FsaUrTDSxL$^oQU3enxVGm*}?-GFdYSwgLA~EpfCI=oc9jX0sX!E3Pv2k))l| zLQr3e?qiy0cK6?N@8drHQCakZj4cIF`d@C~h~0lHNqKnBy^8QfQXaRzc(SV!^)h)S zV)&Z7>7)zyed`(Cub2~j8)=x=+QJez^6wR#jkZNWJuei}`Ud#~*B;ukMZg7?#sl2X zV*}-KFm(+o%4<6Kzw_<^7ovgQVL6zt4PL z;3lTjgGdD^YZ{LoYC)BVb0LQ7BR3cBt*RTr&vGH^<9nJI=z3vG4ui1Aftp% zhZ6h;57~ezSCyX9&Kt#t*33gtEzaT+tyy1+XE8hI7&TAH9_b zw(=Gl!fwC%5A|lldUT7HEcYW-Zkb^s#L0Nc6)e!xH&W_9DN{s#@Tn*U3g+fQDgN~# zb1Yu*?!L`Dt`QbvzhulfeW}rgfx61MFAO0fTFvQu_*00{)Y%1tgZO;xorh~f$sS$Y zg>~%x;<>zOjjeqJq*Nt-YCmIPb&7SxJ)j*H?pD?y1x%*1Jh zT5;VWAAggn`mpZ6c*ntqYVmqr*y-RrhQy;L<;;21AAu}ESv3H=PN6gFK=5W=PUJ$?KE>{XI^ZWG?TzA!j7 zczM!wx)Fld)RPnJDIvFR`edW}^2vs}W6MuLoAN^~%JbJcoQKreZwf8$gXsKgv{8fAMyH%TIwq5BW?wFi5q}%B=d_;x)2jRI-#Tk>qGX(Vhttty{O&;D;pI z_XY}#^$A;UDYe9xW}{(04bR>&TFx^)Pt}sB0!D3`1`Nj2;O_aJWXFi88+r)}OiX{w zu{%p$zwAwI+Zy?a*JeY*&#LAxCox}Kvsu<|kDG@VD#bl-e6jfbXELO*ry+uJ64&=< zdN?Rtra*Gm;JB7=59K?N=6;*3Czmkh<1=*BEe}nx{x_A_pP$P8wuPK!tl-B#Q{Q)N zi4S)ZTEw1b;(qw;%2BrB1?NNnj19X_UtHj^8viN~{J5{_+%}y}@w+6vZ|7xo+iZ30 z?~3#NT?LM|xvtLs{P!nYCJ);e$7BCg_sShP5OIuJD*tI3{&?(O?K?2{#np(t|9R$a;+8C>&w$>l zWh&*D{TFf9GYmWDWzHWJlyN0f?f!ons{d~3JKrq#X6e+8e>n-D^lRFbzpPyQo9FZ5 zc1tkeN`piGT*=w*84PzdQ{DOd+41cUYx(Pl^v*wBl>bi8Wp6f|+i{nfs4(qEkGp!SRfBn2p0F%DVY3M~Aqu_&90VaqQPp55 zA5wij_~XxDi4vr&bl{@_q?{+xuLqCs68X#~gohDdHHVlOp{!EkeiuVM=L>zM8v4d2 zGy%Y8M1&d+gdU{e$>sb{s%4bw4#j>DPefXjgxN#9x4DB|XD@1FrAcU58=My?ugqzyz!8x*SpLSIrx41h^QP-!I*zC5Um zJ)CnWiWm15M0OV>pk?kpt?#0ha0CdG$VfI3>F_j?0UOb16BRlW(QM4NDu%o0>r?H4&Xu8>Os5s z(AO=INHqA$1|0&ACV`@PYtYD=*iabwtR$YroB4DgUPdymSSKzN4JLv{+ls_4?9&gU1r>@VeDFflH0fz=ALHU!y z5Q*uW@lN`Q*EvZprLpphVmpH?d zI11C7mQf0}g~jK{q?hn#9(kqrGQB9{zxy$W2pu1yeP`t26G6F!A|Rh+tnMNyq;_OW zT3Ry}eBYavHwR2T7}sZ;#iF0NE2BEV#LU$K4jKf9L z%!>e=Wg>)f;)0p7=}Xh-3*%x{$q51@uF;4vCo`4uBqLC-Ub+R_(J zFR!tfcQNySB|cAH-nS>MEm77j%N}ygDl7M;0LdQF!wvT2nu=MeAD_y69h)U+HM)Ry-k_Es$`xM&*YIC2^W3YTND1ZtGBmfRidAxJwd^bQ73z~4 zNK27*1G&V|nu;S@nTH=}+j~X4bzdDnC5K`g*cHT#Nts_~&>Q|BM?^uG5Md~Q?zLF8 zP!!olu!=bklkG3^*um|z z)Qm2c1(;VWEdneaQeQv}IXM86xIqn8PC1#nZdk}={r#^~<(yvH^I8(C*+xiBMeYrW zrH*nBsaBUEOEisPt>6Q4oz89;juzW4`IVkjvbz~upfoQ4u$et>bfdt}rx}l@L}RFq zCm=b~Y$q8kXNGmkx*g3q47E28o&|sLfGIcO(d(YQVqJfqVeg{+qdRx9HSVm{J&1TH z@ZP!T6Kard^A`V$rxr?Pbg=4x#qn8TDZJ4MGqUw+aFu8%XjrL->oETMrSm-4z647I>0Es!Iidz=( ze8*_>rZUr{nFcOf+tXJ-{mm}Qu8xWar%lSmH3*AFa7K@$iuT0n^nB`}?KP#{q&0~0 zX`?#V8c84B_(>T}NX8*fs`UCHJEkk2`dLVABW2_3fu|3@Bq(7Bpv@X|jj!J2B1D%R zOfPS$DMo6&2)^dLg3^hzI&ZKvol(28Jp9V3z%vPrF@(;7&BAlo+m%>^NEO9~U-O^I zg}v&A5s)bK++)%mDvqY*;FgMnTDrKs4+l+#PWG(i=!$F$?QuQ5U(mhaGBTWr7^;{~ znjDEa8yT|D`YVd7fZjAH1rF`r!8l@i!nSB=YfdapC z#_lIrJil|m4~4&W*YyXo>vvGGR1$y9m{vi?yxN|uuNfW+k)7sz5c-ie{3C6khPs&C zbRpZkw;bub4#mvUv}{c4PEl*+U%vlF85Lr>&!-ndtw!UY{^wY)t!Ho0)>q;8(Q@*U z7X8FSmhJChSnjsJmQ6autv*Kc1mh3YjNiq~3Cl~fsj@I*18g}qX0fM%ePpiu0%UOBa zPc7HMT+%Y#^aYwU;9uOM_G80OTA_z?Gw3%MZRy#Mq)j?A;yUjdzA7sI)B5^IO>jjQ zh}q~Bo;8dbfB&1b-I8nmtUrz^r{?j7&)R_L@ zAbMY*YVl09j*8NXr(%ytaLCo`G(&0d!w+X6$A%WuCB@h&d)WgO|RF(tCT!KmlK0lUsFwk#n!3G z<-Grr(!3(q{52IjS!v==>hMj&nTkFnqw7sDEy!&y5_^wBVaMd|r>?jhp7pbsUJ4QEF_^q*1Y^?C!`NT%hi2S={$$rIwujfzYF%r5x#PX-C z6X}kAx)j3ZTkL&LeqzQWPq}sAK4%9LN@I?+7y{a<&LYOH*umgl z5VHxc@}&DUy4F}qgU7&9HsRh0nWO9z2X56ofOPyYNoU@Zp86OG5*FhK`(p_^k>`G> zq~cJ~)Xl0D_H*yw(aFw{eE{Qn79$&oL!PZM`>K}%5d*L;4Wx4<=7q&H*Zt0bW?)YDf*Qi z@EoC=Bj=F{w6F53tO!h|+L}UZo4dxVm#P6hE~6zZhah*GAwVwRQCkjd$R2Yg>CZ3r7S2VMp)RZ+-m(gG158 z!NVEo@u}&V*(n-Y0LsQZw;Eo)wz0Xjy|cTw|E&|#b8vEc_VfJn=r3UM;`-*cm>wU* zWbva}khL2Lp%HjDFu^GMw43>VU|Tb8-(NrVmj})a2|4g&BU#nz3I-F2IM^dmb%nzz z9U^1HwLsBmhP2zk@?d@O3mXM$a>!MEiOy%rWj3RshSKR`?R@pm>WyW%+44_;CYYhd z^7(3$-bkKgqzV_FWM7$41}S*bi+OSAvqp2(O1tbEX0wRq>NPd7?QefIT58sNQ8Xu0 zhN$X|es{dy82r|{?cr2$4lB)p+MV$?JiRPrZ4LX=C9it7w=H;Gsag(<<9o=

rHbS@Jl)XI!g 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 E7vOQ}*Z=?k literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html index 5c83502..4420c6e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -119,6 +119,11 @@

Keyboard-driven

Favorites

Save your go-to stations for quick access. Your favorites persist across sessions.

+
+
🎤
+

Identify the playing track

+

Press i on a playing station. rig fingerprints the audio locally in pure Go and asks Shazam to identify it. No API key. Press o to open the track on shazam.com.

+
🎵

Now playing

@@ -169,6 +174,18 @@

Favourites

Saving and managing favourite radio stations in the terminal
+
+

Identify the playing track

+
+
+
+
+
+ rig +
+ Identifying the playing track Shazam-style from the terminal +
+