Clone this, get cargo and run cargo build --release.
Then ./target/release/imgview /path/to/image will render images ✨
Created
June 5, 2017 18:09
-
-
Save goto-bus-stop/34b6b2fa510c2254a55c1578a91a20ce to your computer and use it in GitHub Desktop.
imgview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [package] | |
| name = "imgview" | |
| version = "0.1.0" | |
| [[bin]] | |
| name = "imgview" | |
| path = "main.rs" | |
| [dependencies] | |
| clap = "2.24.2" | |
| image = "0.13.0" | |
| term = "0.4.5" | |
| term_size = "0.3.0" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub struct Color { | |
| pub r: u8, | |
| pub g: u8, | |
| pub b: u8, | |
| } | |
| pub const COLORS: [Color; 256] = [ | |
| Color { r: 0x00, g: 0x00, b: 0x00 }, | |
| Color { r: 0x80, g: 0x00, b: 0x00 }, | |
| Color { r: 0x00, g: 0x80, b: 0x00 }, | |
| Color { r: 0x80, g: 0x80, b: 0x00 }, | |
| Color { r: 0x00, g: 0x00, b: 0x80 }, | |
| Color { r: 0x80, g: 0x00, b: 0x80 }, | |
| Color { r: 0x00, g: 0x80, b: 0x80 }, | |
| Color { r: 0xc0, g: 0xc0, b: 0xc0 }, | |
| Color { r: 0x80, g: 0x80, b: 0x80 }, | |
| Color { r: 0xff, g: 0x00, b: 0x00 }, | |
| Color { r: 0x00, g: 0xff, b: 0x00 }, | |
| Color { r: 0xff, g: 0xff, b: 0x00 }, | |
| Color { r: 0x00, g: 0x00, b: 0xff }, | |
| Color { r: 0xff, g: 0x00, b: 0xff }, | |
| Color { r: 0x00, g: 0xff, b: 0xff }, | |
| Color { r: 0xff, g: 0xff, b: 0xff }, | |
| Color { r: 0x00, g: 0x00, b: 0x00 }, | |
| Color { r: 0x00, g: 0x00, b: 0x5f }, | |
| Color { r: 0x00, g: 0x00, b: 0x87 }, | |
| Color { r: 0x00, g: 0x00, b: 0xaf }, | |
| Color { r: 0x00, g: 0x00, b: 0xd7 }, | |
| Color { r: 0x00, g: 0x00, b: 0xff }, | |
| Color { r: 0x00, g: 0x5f, b: 0x00 }, | |
| Color { r: 0x00, g: 0x5f, b: 0x5f }, | |
| Color { r: 0x00, g: 0x5f, b: 0x87 }, | |
| Color { r: 0x00, g: 0x5f, b: 0xaf }, | |
| Color { r: 0x00, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0x00, g: 0x5f, b: 0xff }, | |
| Color { r: 0x00, g: 0x87, b: 0x00 }, | |
| Color { r: 0x00, g: 0x87, b: 0x5f }, | |
| Color { r: 0x00, g: 0x87, b: 0x87 }, | |
| Color { r: 0x00, g: 0x87, b: 0xaf }, | |
| Color { r: 0x00, g: 0x87, b: 0xd7 }, | |
| Color { r: 0x00, g: 0x87, b: 0xff }, | |
| Color { r: 0x00, g: 0xaf, b: 0x00 }, | |
| Color { r: 0x00, g: 0xaf, b: 0x5f }, | |
| Color { r: 0x00, g: 0xaf, b: 0x87 }, | |
| Color { r: 0x00, g: 0xaf, b: 0xaf }, | |
| Color { r: 0x00, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0x00, g: 0xaf, b: 0xff }, | |
| Color { r: 0x00, g: 0xd7, b: 0x00 }, | |
| Color { r: 0x00, g: 0xd7, b: 0x5f }, | |
| Color { r: 0x00, g: 0xd7, b: 0x87 }, | |
| Color { r: 0x00, g: 0xd7, b: 0xaf }, | |
| Color { r: 0x00, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0x00, g: 0xd7, b: 0xff }, | |
| Color { r: 0x00, g: 0xff, b: 0x00 }, | |
| Color { r: 0x00, g: 0xff, b: 0x5f }, | |
| Color { r: 0x00, g: 0xff, b: 0x87 }, | |
| Color { r: 0x00, g: 0xff, b: 0xaf }, | |
| Color { r: 0x00, g: 0xff, b: 0xd7 }, | |
| Color { r: 0x00, g: 0xff, b: 0xff }, | |
| Color { r: 0x5f, g: 0x00, b: 0x00 }, | |
| Color { r: 0x5f, g: 0x00, b: 0x5f }, | |
| Color { r: 0x5f, g: 0x00, b: 0x87 }, | |
| Color { r: 0x5f, g: 0x00, b: 0xaf }, | |
| Color { r: 0x5f, g: 0x00, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0x00, b: 0xff }, | |
| Color { r: 0x5f, g: 0x5f, b: 0x00 }, | |
| Color { r: 0x5f, g: 0x5f, b: 0x5f }, | |
| Color { r: 0x5f, g: 0x5f, b: 0x87 }, | |
| Color { r: 0x5f, g: 0x5f, b: 0xaf }, | |
| Color { r: 0x5f, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0x5f, b: 0xff }, | |
| Color { r: 0x5f, g: 0x87, b: 0x00 }, | |
| Color { r: 0x5f, g: 0x87, b: 0x5f }, | |
| Color { r: 0x5f, g: 0x87, b: 0x87 }, | |
| Color { r: 0x5f, g: 0x87, b: 0xaf }, | |
| Color { r: 0x5f, g: 0x87, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0x87, b: 0xff }, | |
| Color { r: 0x5f, g: 0xaf, b: 0x00 }, | |
| Color { r: 0x5f, g: 0xaf, b: 0x5f }, | |
| Color { r: 0x5f, g: 0xaf, b: 0x87 }, | |
| Color { r: 0x5f, g: 0xaf, b: 0xaf }, | |
| Color { r: 0x5f, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0xaf, b: 0xff }, | |
| Color { r: 0x5f, g: 0xd7, b: 0x00 }, | |
| Color { r: 0x5f, g: 0xd7, b: 0x5f }, | |
| Color { r: 0x5f, g: 0xd7, b: 0x87 }, | |
| Color { r: 0x5f, g: 0xd7, b: 0xaf }, | |
| Color { r: 0x5f, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0xd7, b: 0xff }, | |
| Color { r: 0x5f, g: 0xff, b: 0x00 }, | |
| Color { r: 0x5f, g: 0xff, b: 0x5f }, | |
| Color { r: 0x5f, g: 0xff, b: 0x87 }, | |
| Color { r: 0x5f, g: 0xff, b: 0xaf }, | |
| Color { r: 0x5f, g: 0xff, b: 0xd7 }, | |
| Color { r: 0x5f, g: 0xff, b: 0xff }, | |
| Color { r: 0x87, g: 0x00, b: 0x00 }, | |
| Color { r: 0x87, g: 0x00, b: 0x5f }, | |
| Color { r: 0x87, g: 0x00, b: 0x87 }, | |
| Color { r: 0x87, g: 0x00, b: 0xaf }, | |
| Color { r: 0x87, g: 0x00, b: 0xd7 }, | |
| Color { r: 0x87, g: 0x00, b: 0xff }, | |
| Color { r: 0x87, g: 0x5f, b: 0x00 }, | |
| Color { r: 0x87, g: 0x5f, b: 0x5f }, | |
| Color { r: 0x87, g: 0x5f, b: 0x87 }, | |
| Color { r: 0x87, g: 0x5f, b: 0xaf }, | |
| Color { r: 0x87, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0x87, g: 0x5f, b: 0xff }, | |
| Color { r: 0x87, g: 0x87, b: 0x00 }, | |
| Color { r: 0x87, g: 0x87, b: 0x5f }, | |
| Color { r: 0x87, g: 0x87, b: 0x87 }, | |
| Color { r: 0x87, g: 0x87, b: 0xaf }, | |
| Color { r: 0x87, g: 0x87, b: 0xd7 }, | |
| Color { r: 0x87, g: 0x87, b: 0xff }, | |
| Color { r: 0x87, g: 0xaf, b: 0x00 }, | |
| Color { r: 0x87, g: 0xaf, b: 0x5f }, | |
| Color { r: 0x87, g: 0xaf, b: 0x87 }, | |
| Color { r: 0x87, g: 0xaf, b: 0xaf }, | |
| Color { r: 0x87, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0x87, g: 0xaf, b: 0xff }, | |
| Color { r: 0x87, g: 0xd7, b: 0x00 }, | |
| Color { r: 0x87, g: 0xd7, b: 0x5f }, | |
| Color { r: 0x87, g: 0xd7, b: 0x87 }, | |
| Color { r: 0x87, g: 0xd7, b: 0xaf }, | |
| Color { r: 0x87, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0x87, g: 0xd7, b: 0xff }, | |
| Color { r: 0x87, g: 0xff, b: 0x00 }, | |
| Color { r: 0x87, g: 0xff, b: 0x5f }, | |
| Color { r: 0x87, g: 0xff, b: 0x87 }, | |
| Color { r: 0x87, g: 0xff, b: 0xaf }, | |
| Color { r: 0x87, g: 0xff, b: 0xd7 }, | |
| Color { r: 0x87, g: 0xff, b: 0xff }, | |
| Color { r: 0xaf, g: 0x00, b: 0x00 }, | |
| Color { r: 0xaf, g: 0x00, b: 0x5f }, | |
| Color { r: 0xaf, g: 0x00, b: 0x87 }, | |
| Color { r: 0xaf, g: 0x00, b: 0xaf }, | |
| Color { r: 0xaf, g: 0x00, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0x00, b: 0xff }, | |
| Color { r: 0xaf, g: 0x5f, b: 0x00 }, | |
| Color { r: 0xaf, g: 0x5f, b: 0x5f }, | |
| Color { r: 0xaf, g: 0x5f, b: 0x87 }, | |
| Color { r: 0xaf, g: 0x5f, b: 0xaf }, | |
| Color { r: 0xaf, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0x5f, b: 0xff }, | |
| Color { r: 0xaf, g: 0x87, b: 0x00 }, | |
| Color { r: 0xaf, g: 0x87, b: 0x5f }, | |
| Color { r: 0xaf, g: 0x87, b: 0x87 }, | |
| Color { r: 0xaf, g: 0x87, b: 0xaf }, | |
| Color { r: 0xaf, g: 0x87, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0x87, b: 0xff }, | |
| Color { r: 0xaf, g: 0xaf, b: 0x00 }, | |
| Color { r: 0xaf, g: 0xaf, b: 0x5f }, | |
| Color { r: 0xaf, g: 0xaf, b: 0x87 }, | |
| Color { r: 0xaf, g: 0xaf, b: 0xaf }, | |
| Color { r: 0xaf, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0xaf, b: 0xff }, | |
| Color { r: 0xaf, g: 0xd7, b: 0x00 }, | |
| Color { r: 0xaf, g: 0xd7, b: 0x5f }, | |
| Color { r: 0xaf, g: 0xd7, b: 0x87 }, | |
| Color { r: 0xaf, g: 0xd7, b: 0xaf }, | |
| Color { r: 0xaf, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0xd7, b: 0xff }, | |
| Color { r: 0xaf, g: 0xff, b: 0x00 }, | |
| Color { r: 0xaf, g: 0xff, b: 0x5f }, | |
| Color { r: 0xaf, g: 0xff, b: 0x87 }, | |
| Color { r: 0xaf, g: 0xff, b: 0xaf }, | |
| Color { r: 0xaf, g: 0xff, b: 0xd7 }, | |
| Color { r: 0xaf, g: 0xff, b: 0xff }, | |
| Color { r: 0xd7, g: 0x00, b: 0x00 }, | |
| Color { r: 0xd7, g: 0x00, b: 0x5f }, | |
| Color { r: 0xd7, g: 0x00, b: 0x87 }, | |
| Color { r: 0xd7, g: 0x00, b: 0xaf }, | |
| Color { r: 0xd7, g: 0x00, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0x00, b: 0xff }, | |
| Color { r: 0xd7, g: 0x5f, b: 0x00 }, | |
| Color { r: 0xd7, g: 0x5f, b: 0x5f }, | |
| Color { r: 0xd7, g: 0x5f, b: 0x87 }, | |
| Color { r: 0xd7, g: 0x5f, b: 0xaf }, | |
| Color { r: 0xd7, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0x5f, b: 0xff }, | |
| Color { r: 0xd7, g: 0x87, b: 0x00 }, | |
| Color { r: 0xd7, g: 0x87, b: 0x5f }, | |
| Color { r: 0xd7, g: 0x87, b: 0x87 }, | |
| Color { r: 0xd7, g: 0x87, b: 0xaf }, | |
| Color { r: 0xd7, g: 0x87, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0x87, b: 0xff }, | |
| Color { r: 0xd7, g: 0xaf, b: 0x00 }, | |
| Color { r: 0xd7, g: 0xaf, b: 0x5f }, | |
| Color { r: 0xd7, g: 0xaf, b: 0x87 }, | |
| Color { r: 0xd7, g: 0xaf, b: 0xaf }, | |
| Color { r: 0xd7, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0xaf, b: 0xff }, | |
| Color { r: 0xd7, g: 0xd7, b: 0x00 }, | |
| Color { r: 0xd7, g: 0xd7, b: 0x5f }, | |
| Color { r: 0xd7, g: 0xd7, b: 0x87 }, | |
| Color { r: 0xd7, g: 0xd7, b: 0xaf }, | |
| Color { r: 0xd7, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0xd7, b: 0xff }, | |
| Color { r: 0xd7, g: 0xff, b: 0x00 }, | |
| Color { r: 0xd7, g: 0xff, b: 0x5f }, | |
| Color { r: 0xd7, g: 0xff, b: 0x87 }, | |
| Color { r: 0xd7, g: 0xff, b: 0xaf }, | |
| Color { r: 0xd7, g: 0xff, b: 0xd7 }, | |
| Color { r: 0xd7, g: 0xff, b: 0xff }, | |
| Color { r: 0xff, g: 0x00, b: 0x00 }, | |
| Color { r: 0xff, g: 0x00, b: 0x5f }, | |
| Color { r: 0xff, g: 0x00, b: 0x87 }, | |
| Color { r: 0xff, g: 0x00, b: 0xaf }, | |
| Color { r: 0xff, g: 0x00, b: 0xd7 }, | |
| Color { r: 0xff, g: 0x00, b: 0xff }, | |
| Color { r: 0xff, g: 0x5f, b: 0x00 }, | |
| Color { r: 0xff, g: 0x5f, b: 0x5f }, | |
| Color { r: 0xff, g: 0x5f, b: 0x87 }, | |
| Color { r: 0xff, g: 0x5f, b: 0xaf }, | |
| Color { r: 0xff, g: 0x5f, b: 0xd7 }, | |
| Color { r: 0xff, g: 0x5f, b: 0xff }, | |
| Color { r: 0xff, g: 0x87, b: 0x00 }, | |
| Color { r: 0xff, g: 0x87, b: 0x5f }, | |
| Color { r: 0xff, g: 0x87, b: 0x87 }, | |
| Color { r: 0xff, g: 0x87, b: 0xaf }, | |
| Color { r: 0xff, g: 0x87, b: 0xd7 }, | |
| Color { r: 0xff, g: 0x87, b: 0xff }, | |
| Color { r: 0xff, g: 0xaf, b: 0x00 }, | |
| Color { r: 0xff, g: 0xaf, b: 0x5f }, | |
| Color { r: 0xff, g: 0xaf, b: 0x87 }, | |
| Color { r: 0xff, g: 0xaf, b: 0xaf }, | |
| Color { r: 0xff, g: 0xaf, b: 0xd7 }, | |
| Color { r: 0xff, g: 0xaf, b: 0xff }, | |
| Color { r: 0xff, g: 0xd7, b: 0x00 }, | |
| Color { r: 0xff, g: 0xd7, b: 0x5f }, | |
| Color { r: 0xff, g: 0xd7, b: 0x87 }, | |
| Color { r: 0xff, g: 0xd7, b: 0xaf }, | |
| Color { r: 0xff, g: 0xd7, b: 0xd7 }, | |
| Color { r: 0xff, g: 0xd7, b: 0xff }, | |
| Color { r: 0xff, g: 0xff, b: 0x00 }, | |
| Color { r: 0xff, g: 0xff, b: 0x5f }, | |
| Color { r: 0xff, g: 0xff, b: 0x87 }, | |
| Color { r: 0xff, g: 0xff, b: 0xaf }, | |
| Color { r: 0xff, g: 0xff, b: 0xd7 }, | |
| Color { r: 0xff, g: 0xff, b: 0xff }, | |
| Color { r: 0x08, g: 0x08, b: 0x08 }, | |
| Color { r: 0x12, g: 0x12, b: 0x12 }, | |
| Color { r: 0x1c, g: 0x1c, b: 0x1c }, | |
| Color { r: 0x26, g: 0x26, b: 0x26 }, | |
| Color { r: 0x30, g: 0x30, b: 0x30 }, | |
| Color { r: 0x3a, g: 0x3a, b: 0x3a }, | |
| Color { r: 0x44, g: 0x44, b: 0x44 }, | |
| Color { r: 0x4e, g: 0x4e, b: 0x4e }, | |
| Color { r: 0x58, g: 0x58, b: 0x58 }, | |
| Color { r: 0x60, g: 0x60, b: 0x60 }, | |
| Color { r: 0x66, g: 0x66, b: 0x66 }, | |
| Color { r: 0x76, g: 0x76, b: 0x76 }, | |
| Color { r: 0x80, g: 0x80, b: 0x80 }, | |
| Color { r: 0x8a, g: 0x8a, b: 0x8a }, | |
| Color { r: 0x94, g: 0x94, b: 0x94 }, | |
| Color { r: 0x9e, g: 0x9e, b: 0x9e }, | |
| Color { r: 0xa8, g: 0xa8, b: 0xa8 }, | |
| Color { r: 0xb2, g: 0xb2, b: 0xb2 }, | |
| Color { r: 0xbc, g: 0xbc, b: 0xbc }, | |
| Color { r: 0xc6, g: 0xc6, b: 0xc6 }, | |
| Color { r: 0xd0, g: 0xd0, b: 0xd0 }, | |
| Color { r: 0xda, g: 0xda, b: 0xda }, | |
| Color { r: 0xe4, g: 0xe4, b: 0xe4 }, | |
| Color { r: 0xee, g: 0xee, b: 0xee }, | |
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| extern crate clap; | |
| extern crate image; | |
| extern crate term; | |
| extern crate term_size; | |
| mod colors; | |
| use std::fs::File; | |
| use std::io::{ | |
| stdin, | |
| Error, | |
| Read, | |
| Seek, | |
| SeekFrom, | |
| BufReader, | |
| }; | |
| use clap::{ | |
| App, | |
| Arg, | |
| }; | |
| use image::{ | |
| load, | |
| load_from_memory, | |
| guess_format, | |
| Rgba, | |
| Pixel, | |
| RgbaImage, | |
| ImageError | |
| }; | |
| use colors::{Color, COLORS}; | |
| fn read_image_from_file(mut file: File) -> Result<RgbaImage, ImageError> { | |
| let mut magic_buf = [0 as u8; 512]; | |
| file.read(&mut magic_buf)?; | |
| file.seek(SeekFrom::Start(0))?; | |
| let reader = BufReader::new(file); | |
| let format = guess_format(&magic_buf)?; | |
| load(reader, format).map(|image| image.to_rgba()) | |
| } | |
| fn read_image_from_stdin() -> Result<RgbaImage, ImageError> { | |
| let mut buf = vec![]; | |
| stdin().read_to_end(&mut buf).unwrap(); | |
| load_from_memory(buf.as_slice()).map(|image| image.to_rgba()) | |
| } | |
| fn abs_sub(a: u8, b: u8) -> u32 { | |
| (if a > b { | |
| a - b | |
| } else { | |
| b - a | |
| }) as u32 | |
| } | |
| fn get_distance(a: &Color, b: &Color) -> u32 { | |
| abs_sub(a.r, b.r).pow(2) + abs_sub(a.g, b.g).pow(2) + abs_sub(a.b, b.b).pow(2) | |
| } | |
| fn get_closest_color(pixel: &Rgba<u8>) -> u16 { | |
| let (r, g, b, _) = pixel.channels4(); | |
| let mut best_distance = std::u32::MAX; | |
| let mut best_color: u16 = 0; | |
| for i in 0..256 { | |
| let color = &COLORS[i as usize]; | |
| let distance = get_distance(color, &Color { r: r, g: g, b: b }); | |
| if distance < best_distance { | |
| best_distance = distance; | |
| best_color = i; | |
| } | |
| } | |
| return best_color; | |
| } | |
| fn print_image(image: RgbaImage, width: u32) -> Result<(), Error> { | |
| let mut t = term::stdout().unwrap(); | |
| let (size_x, size_y) = image.dimensions(); | |
| let step = (size_x / width) as u32; | |
| for y in 0..(size_y / 2 / step) { | |
| for x in 0..(size_x / step) { | |
| let fgcolor = get_closest_color(image.get_pixel(x * step, y * 2 * step)); | |
| let bgcolor = get_closest_color(image.get_pixel(x * step, (y * 2 + 1) * step)); | |
| t.fg(fgcolor)?; | |
| t.bg(bgcolor)?; | |
| write!(t, "▀")?; | |
| } | |
| t.reset()?; | |
| write!(t, "\n")?; | |
| } | |
| Ok(()) | |
| } | |
| fn get_default_width() -> u32 { | |
| term_size::dimensions().map(|sizes| sizes.0 as u32) | |
| .map_or(80, |width| if width > 80 { 80 } else { width }) | |
| } | |
| fn main() { | |
| let matches = App::new("imgview") | |
| .version("0.1.0") | |
| .about("Render images to the terminal in 256 colours") | |
| .arg(Arg::with_name("width") | |
| .short("w") | |
| .long("width") | |
| .value_name("COLUMNS") | |
| .takes_value(true)) | |
| .arg(Arg::with_name("input") | |
| .index(1)) | |
| .get_matches(); | |
| let width = u32::from_str_radix(matches.value_of("width").unwrap_or(""), 10) | |
| .unwrap_or_else(|_| get_default_width()); | |
| let file_path = matches.value_of("input").unwrap_or("-"); | |
| let image = ( | |
| if file_path != "-" { | |
| match File::open(file_path) { | |
| Ok(file) => read_image_from_file(file), | |
| Err(err) => Err(ImageError::IoError(err)), | |
| } | |
| } else { | |
| read_image_from_stdin() | |
| } | |
| ).unwrap(); | |
| print_image(image, width).unwrap(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment