├── src ├── displayable.rs └── main.rs ├── .gitignore ├── test.csv ├── Cargo.toml ├── README ├── docs ├── motivations.md └── format.md ├── Cargo.lock ├── main.rs └── coronadata.csv /src/displayable.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /test.csv: -------------------------------------------------------------------------------- 1 | Animal List 2 | ANIMAL,LEGS,ARMS,CLAWS,TAIL 3 | human,2,2,no,no 4 | fish,0,0,yes,yes 5 | dog,4,0,yes,yes 6 | cat,4,0,yes,yes 7 | penguin,(2),2,no,yes 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ted" 3 | version = "0.1.0" 4 | authors = ["Erich Spaker "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | termion = "1.5.5" 11 | csv = "1.1" 12 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | TEd : Table Editor 2 | It's like vim for spreadsheets. 3 | 4 | row mode 5 | column mode 6 | navigation minigrid 7 | 8 | vaguely vim keybinds: 9 | i to insert 10 | navigate with arrow keys or hjkl 11 | :w to save 12 | :q to quit 13 | some other stuff read the code I don't remember 14 | 15 | -- 16 | see docs for delusions of grandeur -------------------------------------------------------------------------------- /docs/motivations.md: -------------------------------------------------------------------------------- 1 | # The Data Problem 2 | Data has a fundemental problem. It comes from somewhere, and it goes somewhere. 3 | Sometimes those somewheres are the same kind of somewhere, and everything is good. 4 | 5 | But sometimes, that data comes from somewhere, to go somewhere very different. 6 | And then you need a transformation. 7 | And where does that transform live? What is fair? 8 | Should the source format to the destination's preference. 9 | Or should the destination translate from whatever is easiest for the source. 10 | Should they do a little of both (please no). 11 | Or should they hire a translator to sit in the middle? 12 | Serious questions. -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "bstr" 5 | version = "0.2.13" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" 8 | dependencies = [ 9 | "lazy_static", 10 | "memchr", 11 | "regex-automata", 12 | "serde", 13 | ] 14 | 15 | [[package]] 16 | name = "byteorder" 17 | version = "1.3.4" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 20 | 21 | [[package]] 22 | name = "csv" 23 | version = "1.1.3" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" 26 | dependencies = [ 27 | "bstr", 28 | "csv-core", 29 | "itoa", 30 | "ryu", 31 | "serde", 32 | ] 33 | 34 | [[package]] 35 | name = "csv-core" 36 | version = "0.1.10" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" 39 | dependencies = [ 40 | "memchr", 41 | ] 42 | 43 | [[package]] 44 | name = "itoa" 45 | version = "0.4.5" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 48 | 49 | [[package]] 50 | name = "lazy_static" 51 | version = "1.4.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 54 | 55 | [[package]] 56 | name = "libc" 57 | version = "0.2.70" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" 60 | 61 | [[package]] 62 | name = "memchr" 63 | version = "2.3.3" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 66 | 67 | [[package]] 68 | name = "numtoa" 69 | version = "0.1.0" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" 72 | 73 | [[package]] 74 | name = "redox_syscall" 75 | version = "0.1.56" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 78 | 79 | [[package]] 80 | name = "redox_termios" 81 | version = "0.1.1" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 84 | dependencies = [ 85 | "redox_syscall", 86 | ] 87 | 88 | [[package]] 89 | name = "regex-automata" 90 | version = "0.1.9" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" 93 | dependencies = [ 94 | "byteorder", 95 | ] 96 | 97 | [[package]] 98 | name = "ryu" 99 | version = "1.0.4" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" 102 | 103 | [[package]] 104 | name = "serde" 105 | version = "1.0.110" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" 108 | 109 | [[package]] 110 | name = "ted" 111 | version = "0.1.0" 112 | dependencies = [ 113 | "csv", 114 | "termion", 115 | ] 116 | 117 | [[package]] 118 | name = "termion" 119 | version = "1.5.5" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" 122 | dependencies = [ 123 | "libc", 124 | "numtoa", 125 | "redox_syscall", 126 | "redox_termios", 127 | ] 128 | -------------------------------------------------------------------------------- /docs/format.md: -------------------------------------------------------------------------------- 1 | This file outlines my current thoughts on the design of TED's files format (not a typo). 2 | 3 | # Design principals: 4 | - use standard file formats, play nice with standard tools 5 | - expose the model to the user 6 | - don't break the (simplicity and interoperability of) csv 7 | 8 | # A usecase walkthrough. 9 | ## 1. Your webscraper produces a file prices.csv 10 | You open the file in ted, change a value, and save. prices.csv is updated, no other changes. 11 | 12 | ## 2. You change the formatting of a column to show percentages. 13 | You save the file, prices.csv is unchanged, but a new file prices.json has been created. It looks like this: 14 | ``` 15 | { 16 | "meta" : [ 17 | { 18 | "row" : 1, 19 | "header" : true 20 | } 21 | ] 22 | "format": [ 23 | { 24 | "column" : 3, 25 | "display" : "percent" 26 | } 27 | ] 28 | } 29 | ``` 30 | 31 | > NOTE: meta header will likely end up in the .toml (hopefully autodetected), instead of / in addition to here. 32 | 33 | ## 3. You add a formula column summing column A and B 34 | You save the file and a new line is added to prices.json 35 | ``` 36 | { 37 | ... 38 | "columns" : [ 39 | { 40 | "show" : 5 41 | "formula" : "A# + B#" 42 | } 43 | ] 44 | } 45 | ``` 46 | 47 | ## 4. You add another sheet to the spreadsheet, called products 48 | You add a column of product id's and a column of their name. You save. 49 | 2 new files are created. products.csv, and prices.toml. 50 | products.csv has your data and prices.toml look like this: 51 | ``` 52 | [prices] 53 | index = 0 54 | path = "prices.csv" 55 | 56 | [products] 57 | index = 1 58 | path = "products.csv" 59 | ``` 60 | 61 | ## 5. You have another file on disk, which you want to load as a dataset. 62 | You create a symlink to the data. And add to prices.toml 63 | ``` 64 | [my_imported_data] 65 | index = 3 66 | readonly = "true" 67 | path = "my_imported_data.csv" 68 | ``` 69 | It shows in the ted like a regular sheet, but displays `linked` and `ro`. 70 | Instead of doing it manually you could have ran `:ln ../../mylinkeddata.csv` in ted. 71 | 72 | ### Note: 73 | It might be the case that this is a bad system for supporting windows users, so perhaps prices.toml would support a `link = "../../my_data.csv"` directive. 74 | alternatively perhaps ted would just be able to parse symlinks on windows and load the referenced file... 75 | why not both, with a command `:convert_links ` 76 | 77 | ## 6. You have a script which loads some data from the internet and scrapes it to produce a table, you want this data as part of the spreadsheet. 78 | Add a line to prices.toml. 79 | ``` 80 | [scraperdata] 81 | index = 4 82 | path = "scraper.csv" 83 | automated = true 84 | 85 | [program.scraper] 86 | exec = "./scrape.sh ${updates.path}" 87 | updates = "scraperdata" 88 | ``` 89 | 90 | There would also be a format for things where you don't even want the data saved. Instead loaded every time ted is invoked. (Rarely desireable, but supported) 91 | ``` 92 | [scraperdata] 93 | index = 4 94 | exec = "./scrape.sh" #assuming scrape.sh outputs csv to std out. 95 | ``` 96 | 97 | > Note: Ted's support for script generated datasets can be used to query databases!. However, in the future we hope to have builtin support for database QUERIES and edits! 98 | 99 | ## 7. You have a csv that is tab seperated. 100 | When importing the document, it should be autodetected, and will be recorded in the .toml if/when one is created. 101 | You of course, can do that manually. 102 | ``` 103 | [tab_seperated_sheet] 104 | index = 5 105 | path = "tsv_sheet.csv" 106 | 107 | [tab_seperated_sheet.format] 108 | column_seperator = "\t" 109 | ``` 110 | 111 | NOTE: unsolved problem, how to deal with formatting of the toml? in the example above, there are many ways to set tab_seperated_sheet.format.column_seperator. 112 | If you set it manually, will ted overwrite it with default format the next time it needs to update the toml. 113 | TODO: implement pandorica transform for toml ;) 114 | 115 | ## 8. You want a pivot table. 116 | Ted is built around the concept of: 1 table, 1 sheet, 1 file (well, techincally 2, one csv for data, one json for metadata). 117 | Pivot tables are no different, except that they have no data file. 118 | Creating a pivot table named "mypivot" based on the "prices" csv will create a file mypivot.json 119 | ``` 120 | { 121 | "pivot" : { 122 | "rows" : [] 123 | "columns" : [] 124 | "data" : [] 125 | "filter" : [] 126 | } 127 | } 128 | ``` 129 | 130 | because pivot tables refer to another sheet, the toml file must be updated as well, specifying the datasource. 131 | we do not specify the data range, because in ted "1 table = 1 sheet", the range will always be the full table. 132 | (note you can always create a derivative table with a subset rows/columns, and use that as the pivot source, if you are in the very abnormal case where you don't want all rows + all columns available to the pivot) 133 | We don't worry about heading here either, since the heading is metadata associated with the source table. 134 | 135 | ``` 136 | [mypivot] 137 | pivot = "prices" 138 | ``` 139 | 140 | > NOTE: You may have noticed by now, that the general devision of labor between json and toml files is to put relationships and identifying information in the toml, and formatting,transformations,config,etc. in the json. This topic would need a lot of consideration and effort to pin down as the spec is developed. 141 | > The main point of certainty is: 1 toml = 1 document (compare to 1 excel file) and 1 json = 1 sheet. 142 | > Having multible toml's in a folder is probably allowed, and perhaps its even permissible for them to share some csv/json files! 143 | 144 | Adding calculated fields to the pivot tables output is the same as it is for a regular table (see 3), it gets put in the json in the same place. 145 | 146 | ## 9. And now, you want to send your amazing spreadsheet to someone. 147 | Conveniently, your data is still just in csv's so if thats all they need, send them that. 148 | But if they are a fellow TEd enjoyer, you can send them your spreadsheet the typical unix way: as a tar archive. 149 | 150 | And TEd should be able to open and edit this achive file, and save it back to the tar file. 151 | And you can extract the file if you ever need access to the internals, and TEd doesn't care. 152 | 153 | Further, TEd would hopefully support the common compression algorithms both on the tar archive, and on the csv's themselves. 154 | Ideally, you should be able to compress prices.csv into prices.csv.lz4, and then open the project in TEd without even change the toml. -------------------------------------------------------------------------------- /main.rs: -------------------------------------------------------------------------------- 1 | //tutorial-read-01.rs 2 | #![allow(dead_code)] 3 | #![allow(unused_variables)] 4 | #![allow(unused_macros)] 5 | #![allow(unused_imports)] 6 | 7 | use std::io::{stdin, stdout, Stdout, Write}; 8 | use termion::event::Key; 9 | use termion::input::TermRead; 10 | use termion::raw::IntoRawMode; 11 | 12 | use std::env; 13 | use std::error::Error; 14 | use std::ffi::OsString; 15 | use std::fs::File; 16 | use std::process; 17 | 18 | fn run() -> Result, Box> { 19 | let file_path = get_first_arg()?; 20 | let file = File::open(file_path)?; 21 | let mut vec = Vec::new(); 22 | let mut rdr = csv::ReaderBuilder::new() 23 | .flexible(true) 24 | .has_headers(false) 25 | .from_reader(file); 26 | for result in rdr.records() { 27 | let record = result?; 28 | vec.push(record) 29 | } 30 | Ok(vec) 31 | } 32 | 33 | /// Returns the first positional argument sent to this process. If there are no 34 | /// positional arguments, then this returns an error. 35 | fn get_first_arg() -> Result> { 36 | match env::args_os().nth(1) { 37 | None => Err(From::from("expected 1 argument, but got none")), 38 | Some(file_path) => Ok(file_path), 39 | } 40 | } 41 | 42 | enum ViewMode { 43 | Column, 44 | Row, 45 | } 46 | 47 | enum InputMode { 48 | Normal, 49 | Insert, 50 | Command, 51 | Select, 52 | } 53 | 54 | enum Dir { 55 | Up, 56 | Down, 57 | Left, 58 | Right, 59 | } 60 | 61 | struct Mode { 62 | view: ViewMode, 63 | input: InputMode, 64 | position: (u16, u16), //row, column 65 | offset: u16, 66 | minimap: bool, 67 | minimap_width: u16, 68 | minimap_height: u16, 69 | dims: (u16, u16), //cols rows 70 | margin: u16, 71 | paste: String, 72 | command: String, 73 | stdout: termion::screen::AlternateScreen>, 74 | stale: bool, 75 | cursor: (u16, u16), 76 | exit: bool, 77 | no_clear: bool, 78 | } 79 | 80 | impl Mode { 81 | fn other_key(&mut self, c: char) { 82 | let code: String = c.escape_default().collect(); 83 | write!( 84 | self.stdout, 85 | "{}{}{}", 86 | termion::cursor::Goto(self.dims.0 - code.len() as u16, self.dims.1), 87 | termion::clear::CurrentLine, 88 | code 89 | ) 90 | .unwrap(); 91 | self.no_clear = true; 92 | } 93 | fn move_cell(&mut self, dir: Dir) { 94 | match dir { 95 | Dir::Left => self.position.1 += 1, 96 | Dir::Right => { 97 | if self.position.1 > 0 { 98 | self.position.1 -= 1; 99 | } 100 | } 101 | Dir::Up => { 102 | if self.position.0 > 0 { 103 | self.position.0 -= 1; 104 | } 105 | } 106 | Dir::Down => self.position.0 += 1, 107 | } 108 | } 109 | fn enter_command(&mut self) { 110 | self.input = InputMode::Command; 111 | self.command.clear(); 112 | self.cursor = (0, 0); 113 | } 114 | fn edit_cell(&self) {} 115 | fn change_cell(&self) {} 116 | fn delete_cell(&self) {} 117 | fn yank_cell(&self) {} 118 | fn paste_cell(&self) {} 119 | fn view_toggle(&self) {} 120 | fn minimap_toggle(&self) {} 121 | fn command_key(&mut self, c: char) { 122 | self.command.insert(self.cursor.1 as usize, c); 123 | self.cursor.1 += 1 124 | } 125 | fn command_del(&mut self) { 126 | if self.cursor.1 > 0 { 127 | self.command.remove(self.cursor.1 as usize - 1); 128 | self.cursor.1 -= 1; 129 | } 130 | } 131 | fn command_enter(&mut self) { 132 | self.input = InputMode::Normal; 133 | command_parse(self.command.clone().as_str(), self) 134 | } 135 | fn command_esc(&mut self) { 136 | self.input = InputMode::Normal; 137 | } 138 | fn insert_key(&self, c: char) {} 139 | fn insert_enter(&self) {} 140 | fn insert_esc(&self) {} 141 | fn insert_del(&self) {} 142 | fn move_insert(&self, dir: Dir) {} 143 | } 144 | 145 | fn command_parse(cmd: &str, mode: &mut Mode) { 146 | match cmd { 147 | "q" => mode.exit = true, 148 | _ => (), 149 | } 150 | } 151 | 152 | //PROBLEM: terminal cannot get keyup requests 153 | //this means no chorded keybinds 154 | fn main() { 155 | //setup input output 156 | //let ttyin = get_tty().unwrap(); 157 | let mut cells = run().unwrap(); 158 | 159 | let ttyin = stdin(); 160 | let ttyout = termion::screen::AlternateScreen::from(stdout().into_raw_mode().unwrap()); 161 | let mut mode = Mode { 162 | view: ViewMode::Column, 163 | input: InputMode::Normal, 164 | position: (0, 0), 165 | offset: 0, 166 | minimap: true, 167 | minimap_width: 10, 168 | minimap_height: 6, 169 | dims: termion::terminal_size().unwrap(), 170 | margin: 11, 171 | paste: String::from(""), 172 | command: String::from(""), 173 | stdout: ttyout, 174 | stale: true, 175 | cursor: (0, 0), 176 | exit: false, 177 | no_clear: false, 178 | }; 179 | 180 | //clear screen 181 | write!( 182 | mode.stdout, 183 | "{}{}", 184 | termion::clear::All, 185 | termion::cursor::Goto(1, 1) 186 | ) 187 | .unwrap(); 188 | mode.stdout.flush().unwrap(); 189 | 190 | //detecting keydown events 191 | draw(&mut mode, &cells); 192 | mode.stdout.flush().unwrap(); 193 | for c in ttyin.keys() { 194 | mode.no_clear = false; 195 | key_delegate(c.unwrap(), &mut mode); // Print the key we type... 196 | draw(&mut mode, &cells); 197 | mode.stdout.flush().unwrap(); 198 | if mode.exit { 199 | break; 200 | } 201 | } 202 | } 203 | 204 | fn key_delegate(key: Key, mode: &mut Mode) { 205 | match mode.input { 206 | InputMode::Normal => normal_mode(key, mode), 207 | InputMode::Command => command_mode(key, mode), 208 | InputMode::Insert => insert_mode(key, mode), 209 | InputMode::Select => (), 210 | } 211 | } 212 | 213 | fn normal_mode(key: Key, mode: &mut Mode) { 214 | match key { 215 | Key::Char('k') => mode.move_cell(Dir::Up), 216 | Key::Char('j') => mode.move_cell(Dir::Down), 217 | Key::Char('l') => mode.move_cell(Dir::Left), 218 | Key::Char('h') => mode.move_cell(Dir::Right), 219 | 220 | Key::Char(':') => mode.enter_command(), 221 | Key::Char(';') => mode.enter_command(), 222 | 223 | Key::Char('i') => mode.edit_cell(), 224 | Key::Char('c') => mode.change_cell(), 225 | Key::Char('d') => mode.delete_cell(), 226 | Key::Char('y') => mode.yank_cell(), 227 | Key::Char('p') => mode.paste_cell(), 228 | 229 | Key::Char('t') => mode.view_toggle(), 230 | Key::Char('m') => mode.minimap_toggle(), 231 | 232 | Key::Left => mode.move_cell(Dir::Up), 233 | Key::Right => mode.move_cell(Dir::Down), 234 | Key::Up => mode.move_cell(Dir::Left), 235 | Key::Down => mode.move_cell(Dir::Right), 236 | Key::Char(c) => mode.other_key(c), 237 | _ => (), 238 | } 239 | } 240 | 241 | fn command_mode(key: Key, mode: &mut Mode) { 242 | match key { 243 | Key::Char('\n') => mode.command_enter(), 244 | Key::Char(c) => mode.command_key(c), 245 | Key::Backspace => mode.command_del(), 246 | Key::Esc => mode.command_esc(), 247 | _ => (), 248 | } 249 | } 250 | 251 | fn insert_mode(key: Key, mode: &mut Mode) { 252 | match key { 253 | Key::Char('\n') => mode.insert_enter(), 254 | Key::Char(c) => mode.insert_key(c), 255 | Key::Backspace => mode.insert_del(), 256 | Key::Esc => mode.insert_esc(), 257 | Key::Left => mode.move_insert(Dir::Left), 258 | Key::Right => mode.move_insert(Dir::Right), 259 | Key::Up => mode.move_insert(Dir::Up), 260 | Key::Down => mode.move_insert(Dir::Down), 261 | _ => (), 262 | } 263 | } 264 | 265 | //todo, make mode not mut and make stdout seperate 266 | fn draw(mode: &mut Mode, cells: &Vec) { 267 | match mode.input { 268 | InputMode::Normal => normal_draw(mode, cells), 269 | InputMode::Command => command_draw(mode), 270 | InputMode::Insert => insert_draw(mode, cells), 271 | InputMode::Select => (), 272 | } 273 | } 274 | 275 | fn normal_draw(mode: &mut Mode, cells: &Vec) { 276 | if !mode.no_clear { 277 | write!( 278 | mode.stdout, 279 | "{}{}", 280 | termion::cursor::Goto(0, mode.dims.1), 281 | termion::clear::All, 282 | ) 283 | .unwrap(); 284 | 285 | let line = mode.position.0 as i16 - mode.offset as i16 + 1; 286 | if line > mode.dims.1 as i16 - 1 { 287 | mode.offset += 1; 288 | } else if line > 0 { 289 | mode.offset -= 1; 290 | } 291 | let line = mode.position.0 - mode.offset + 1; 292 | 293 | for i in 0..(mode.dims.1 - 1) { 294 | let n = i + mode.offset; 295 | let contents = cells.get(n as usize); 296 | let cell = match contents { 297 | Some(cell) => cell.get(mode.position.1 as usize), 298 | None => break, 299 | }; 300 | let cell = match cell { 301 | Some(cell) => cell, 302 | None => "XXX", 303 | }; 304 | 305 | write!( 306 | mode.stdout, 307 | "{}{:>3}: {}", 308 | termion::cursor::Goto(mode.margin, i + 1), 309 | n, 310 | cell, 311 | ) 312 | .unwrap(); 313 | } 314 | write!( 315 | mode.stdout, 316 | "{}r{} c{}{}", 317 | termion::cursor::Goto(1, mode.dims.0), 318 | mode.position.0, 319 | mode.position.1, 320 | termion::cursor::Goto(mode.margin, line), 321 | ) 322 | .unwrap(); 323 | } 324 | } 325 | 326 | fn insert_draw(mode: &mut Mode, cells: &Vec) {} 327 | fn command_draw(mode: &mut Mode) { 328 | write!( 329 | mode.stdout, 330 | "{}{}:{}{}{}", 331 | termion::cursor::Goto(0, mode.dims.1), 332 | termion::clear::CurrentLine, 333 | mode.command, 334 | termion::cursor::Goto(mode.cursor.1 + 2, mode.dims.1), 335 | termion::cursor::Show, 336 | ) 337 | .unwrap(); 338 | } 339 | 340 | //make r replace because it doesn't do anything 341 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //tutorial-read-01.rs 2 | #![allow(dead_code)] 3 | #![allow(unused_variables)] 4 | #![allow(unused_macros)] 5 | #![allow(unused_imports)] 6 | 7 | use std::io::{stdin, stdout, Stdout, Write}; 8 | use termion::event::Key; 9 | use termion::input::TermRead; 10 | use termion::raw::IntoRawMode; 11 | 12 | use std::cmp; 13 | use std::env; 14 | use std::error::Error; 15 | use std::ffi::OsString; 16 | use std::fs::File; 17 | use std::process; 18 | 19 | fn run() -> Result, Box> { 20 | let file_path = get_first_arg()?; 21 | let file = File::open(file_path)?; 22 | let mut vec = Vec::new(); 23 | let mut rdr = csv::ReaderBuilder::new() 24 | .flexible(true) 25 | .has_headers(false) 26 | .from_reader(file); 27 | for result in rdr.records() { 28 | let record = result?; 29 | vec.push(record) 30 | } 31 | Ok(vec) 32 | } 33 | fn write(cells: &Vec) { 34 | let file_path = get_first_arg().unwrap(); 35 | let file = File::create(file_path).unwrap(); 36 | let mut wrt = csv::WriterBuilder::new() 37 | .flexible(true) 38 | .has_headers(false) 39 | .from_writer(file); 40 | for result in cells { 41 | wrt.write_record(result.iter()).unwrap(); 42 | } 43 | } 44 | 45 | /// Returns the first positional argument sent to this process. If there are no 46 | /// positional arguments, then this returns an error. 47 | fn get_first_arg() -> Result> { 48 | match env::args_os().nth(1) { 49 | None => Err(From::from("expected 1 argument, but got none")), 50 | Some(file_path) => Ok(file_path), 51 | } 52 | } 53 | 54 | #[derive(PartialEq)] 55 | enum ViewMode { 56 | Column, 57 | Row, 58 | } 59 | 60 | #[derive(PartialEq)] 61 | enum InputMode { 62 | Normal, 63 | Insert, 64 | Command, 65 | Select, 66 | } 67 | 68 | enum Dir { 69 | Up, 70 | Down, 71 | Left, 72 | Right, 73 | } 74 | 75 | struct Mode { 76 | view: ViewMode, 77 | input: InputMode, 78 | position: (u16, u16), //column, row 79 | offset: u16, 80 | minimap: bool, 81 | minimap_width: u16, 82 | minimap_height: u16, 83 | dims: (u16, u16), 84 | margin: u16, 85 | paste: String, 86 | command: String, 87 | stdout: termion::screen::AlternateScreen>, 88 | stale: bool, 89 | cursor: (u16, u16), 90 | exit: bool, 91 | no_clear: bool, 92 | mode_pos: (u16, u16), 93 | cells: Vec, 94 | cols: u16, 95 | } 96 | 97 | impl Mode { 98 | fn other_key(&mut self, c: char) { 99 | let code: String = c.escape_default().collect(); 100 | write!( 101 | self.stdout, 102 | "{}{}{}", 103 | termion::cursor::Goto(self.dims.0 - code.len() as u16, self.dims.1), 104 | termion::clear::CurrentLine, 105 | code 106 | ) 107 | .unwrap(); 108 | self.no_clear = true; 109 | } 110 | fn move_cell(&mut self, dir: Dir) { 111 | let (ver, hor) = match self.view { 112 | ViewMode::Column => (&mut self.position.1, &mut self.position.0), 113 | ViewMode::Row => (&mut self.position.0, &mut self.position.1), 114 | }; 115 | match dir { 116 | Dir::Left => *hor += 1, 117 | Dir::Right => { 118 | if *hor > 0 { 119 | *hor -= 1; 120 | } 121 | } 122 | Dir::Up => { 123 | if *ver > 0 { 124 | *ver -= 1; 125 | } 126 | } 127 | Dir::Down => *ver += 1, 128 | } 129 | } 130 | fn enter_command(&mut self) { 131 | self.input = InputMode::Command; 132 | self.command.clear(); 133 | self.cursor = (0, 0); 134 | } 135 | fn edit_cell(&mut self) { 136 | self.input = InputMode::Insert; 137 | self.command = get_cell(self); 138 | self.cursor = (0, 0); 139 | } 140 | fn append_cell(&mut self) { 141 | self.input = InputMode::Insert; 142 | self.command = get_cell(self); 143 | self.cursor = (self.command.len() as u16, 0); 144 | } 145 | fn change_cell(&mut self) { 146 | self.input = InputMode::Insert; 147 | self.command.clear(); 148 | self.cursor = (0, 0); 149 | } 150 | fn delete_cell(&mut self) { 151 | self.paste = get_cell(self); 152 | set_cell("", self); 153 | } 154 | fn yank_cell(&mut self) { 155 | self.paste = get_cell(self); 156 | } 157 | fn paste_cell(&mut self) { 158 | set_cell(self.paste.clone().as_str(), self); 159 | } 160 | fn view_toggle(&mut self) { 161 | self.view = match self.view { 162 | ViewMode::Column => ViewMode::Row, 163 | ViewMode::Row => ViewMode::Column, 164 | }; 165 | } 166 | fn minimap_toggle(&mut self) { 167 | self.minimap = !self.minimap; 168 | } 169 | fn command_key(&mut self, c: char) { 170 | self.command.insert(self.cursor.0 as usize, c); 171 | self.cursor.0 += 1 172 | } 173 | fn command_del(&mut self) { 174 | if self.cursor.0 > 0 { 175 | self.command.remove(self.cursor.0 as usize - 1); 176 | self.cursor.0 -= 1; 177 | } 178 | } 179 | fn command_enter(&mut self) { 180 | self.input = InputMode::Normal; 181 | command_parse(self.command.clone().as_str(), self) 182 | } 183 | fn command_esc(&mut self) { 184 | self.input = InputMode::Normal; 185 | } 186 | fn insert_key(&mut self, c: char) { 187 | self.command.insert(self.cursor.0 as usize, c); 188 | self.cursor.0 += 1 189 | } 190 | fn insert_enter(&mut self) { 191 | self.input = InputMode::Normal; 192 | set_cell(self.command.clone().as_str(), self); 193 | } 194 | fn insert_esc(&mut self) { 195 | self.input = InputMode::Normal; 196 | } 197 | fn insert_del(&mut self) { 198 | if self.cursor.0 > 0 { 199 | self.command.remove(self.cursor.0 as usize - 1); 200 | self.cursor.0 -= 1; 201 | } 202 | } 203 | fn move_insert(&mut self, dir: Dir) { 204 | match dir { 205 | Dir::Left => { 206 | if self.cursor.0 > 0 { 207 | self.cursor.0 -= 1 208 | } 209 | } 210 | Dir::Right => { 211 | if self.cursor.0 < self.command.len() as u16 { 212 | self.cursor.0 += 1 213 | } 214 | } 215 | _ => (), 216 | }; 217 | } 218 | } 219 | 220 | fn get_cell(mode: &mut Mode) -> String { 221 | let contents = mode.cells.get(mode.position.1 as usize); 222 | match contents { 223 | Some(cell) => match cell.get(mode.position.0 as usize) { 224 | Some(cell) => cell.to_string(), 225 | None => "".to_string(), 226 | }, 227 | None => "".to_string(), 228 | } 229 | } 230 | 231 | fn set_cell(txt: &str, mode: &mut Mode) { 232 | let contents = mode.cells.get_mut(mode.position.1 as usize); 233 | let min = std::cmp::max(mode.position.0 + 1, mode.cols); 234 | let empty = csv::StringRecord::from(vec![""].repeat(min as usize)); 235 | match contents { 236 | Some(cell) => match cell.get(mode.position.0 as usize) { 237 | Some(_) => { 238 | let new = mod_r(&cell, mode.position.0 as usize, txt); 239 | cell.clear(); 240 | cell.extend(new.iter()); 241 | } 242 | None => { 243 | cell.extend(vec![""].repeat(mode.position.0 as usize - cell.len())); 244 | cell.push_field(txt); 245 | } 246 | }, 247 | None => { 248 | mode.cells.resize(mode.position.1 as usize, empty.clone()); 249 | mode.cells 250 | .push(mod_r(&empty, mode.position.0 as usize, txt)); 251 | } 252 | }; 253 | } 254 | 255 | fn mod_r(base: &csv::StringRecord, x: usize, txt: &str) -> csv::StringRecord { 256 | base.into_iter() 257 | .enumerate() 258 | .map(|(i, v)| if i == x { txt } else { v }) 259 | .collect() 260 | } 261 | 262 | fn command_parse(cmd: &str, mode: &mut Mode) { 263 | let mut args = cmd.split_ascii_whitespace(); 264 | match args.next() { 265 | Some("q") => mode.exit = true, 266 | Some("w") => write(&mode.cells), 267 | Some("set") => match args.next() { 268 | Some("minimap") => match args.next() { 269 | Some("width") => { 270 | mode.minimap_width = match args.next() { 271 | Some(c) => c.parse().unwrap_or(mode.minimap_width), 272 | _ => 10, 273 | } 274 | } 275 | Some("height") => { 276 | mode.minimap_height = match args.next() { 277 | Some(c) => c.parse().unwrap_or(mode.minimap_height), 278 | _ => 6, 279 | } 280 | } 281 | None => mode.minimap = !mode.minimap, 282 | _ => (), 283 | }, 284 | _ => (), 285 | }, 286 | Some("gr") => { 287 | mode.position.1 = match args.next() { 288 | Some(c) => c.parse().unwrap_or(mode.position.1), 289 | _ => 0, 290 | } 291 | } 292 | Some("gc") => { 293 | mode.position.0 = match args.next() { 294 | Some(c) => c.parse().unwrap_or(mode.position.0), 295 | _ => 0, 296 | } 297 | } 298 | _ => (), 299 | } 300 | } 301 | 302 | //PROBLEM: terminal cannot get keyup requests 303 | //this means no chorded keybinds 304 | fn main() { 305 | //setup input output 306 | //let ttyin = get_tty().unwrap(); 307 | let cells = run().unwrap(); 308 | let cols = match cells.get(0) { 309 | Some(cell) => cell.len() as u16, 310 | None => 0, 311 | }; 312 | 313 | let ttyin = stdin(); 314 | let ttyout = termion::screen::AlternateScreen::from(stdout().into_raw_mode().unwrap()); 315 | let mut mode = Mode { 316 | view: ViewMode::Column, 317 | input: InputMode::Normal, 318 | position: (0, 0), 319 | offset: 0, 320 | minimap: true, 321 | minimap_width: 6, 322 | minimap_height: 6, 323 | dims: termion::terminal_size().unwrap(), 324 | margin: 0, 325 | paste: String::from(""), 326 | command: String::from(""), 327 | stdout: ttyout, 328 | stale: true, 329 | cursor: (0, 0), 330 | exit: false, 331 | no_clear: false, 332 | mode_pos: (0, 0), 333 | cells: cells, 334 | cols: cols, 335 | }; 336 | 337 | //clear screen 338 | write!( 339 | mode.stdout, 340 | "{}{}", 341 | termion::clear::All, 342 | termion::cursor::Goto(1, 1) 343 | ) 344 | .unwrap(); 345 | mode.stdout.flush().unwrap(); 346 | 347 | //detecting keydown events 348 | draw(&mut mode); 349 | mode.stdout.flush().unwrap(); 350 | for c in ttyin.keys() { 351 | mode.no_clear = false; 352 | key_delegate(c.unwrap(), &mut mode); // Print the key we type... 353 | draw(&mut mode); 354 | mode.stdout.flush().unwrap(); 355 | if mode.exit { 356 | break; 357 | } 358 | } 359 | } 360 | 361 | fn key_delegate(key: Key, mode: &mut Mode) { 362 | match mode.input { 363 | InputMode::Normal => normal_mode(key, mode), 364 | InputMode::Command => command_mode(key, mode), 365 | InputMode::Insert => insert_mode(key, mode), 366 | InputMode::Select => (), 367 | } 368 | } 369 | 370 | fn normal_mode(key: Key, mode: &mut Mode) { 371 | match key { 372 | Key::Char('k') => mode.move_cell(Dir::Up), 373 | Key::Char('j') => mode.move_cell(Dir::Down), 374 | Key::Char('l') => mode.move_cell(Dir::Left), 375 | Key::Char('h') => mode.move_cell(Dir::Right), 376 | 377 | Key::Char(':') => mode.enter_command(), 378 | Key::Char(';') => mode.enter_command(), 379 | 380 | Key::Char('i') => mode.edit_cell(), 381 | Key::Char('a') => mode.append_cell(), 382 | Key::Char('c') => mode.change_cell(), 383 | Key::Char('d') => mode.delete_cell(), 384 | Key::Char('y') => mode.yank_cell(), 385 | Key::Char('p') => mode.paste_cell(), 386 | 387 | Key::Char('t') => mode.view_toggle(), 388 | Key::Char('m') => mode.minimap_toggle(), 389 | 390 | Key::Char('g') => { 391 | mode.enter_command(); 392 | mode.command = "gc ".to_string(); 393 | mode.cursor.0 = mode.command.len() as u16; 394 | } 395 | Key::Char('G') => { 396 | mode.enter_command(); 397 | mode.command = "gr ".to_string(); 398 | mode.cursor.0 = mode.command.len() as u16; 399 | } 400 | 401 | Key::Left => mode.move_cell(Dir::Up), 402 | Key::Right => mode.move_cell(Dir::Down), 403 | Key::Up => mode.move_cell(Dir::Left), 404 | Key::Down => mode.move_cell(Dir::Right), 405 | Key::Char(c) => mode.other_key(c), 406 | _ => (), 407 | } 408 | } 409 | 410 | fn command_mode(key: Key, mode: &mut Mode) { 411 | match key { 412 | Key::Char('\n') => mode.command_enter(), 413 | Key::Char(c) => mode.command_key(c), 414 | Key::Backspace => mode.command_del(), 415 | Key::Esc => mode.command_esc(), 416 | Key::Left => mode.move_insert(Dir::Left), 417 | Key::Right => mode.move_insert(Dir::Right), 418 | _ => (), 419 | } 420 | } 421 | 422 | fn insert_mode(key: Key, mode: &mut Mode) { 423 | match key { 424 | Key::Char('\n') => mode.insert_enter(), 425 | Key::Char(c) => mode.insert_key(c), 426 | Key::Backspace => mode.insert_del(), 427 | Key::Esc => mode.insert_esc(), 428 | Key::Left => mode.move_insert(Dir::Left), 429 | Key::Right => mode.move_insert(Dir::Right), 430 | Key::Up => mode.move_insert(Dir::Up), 431 | Key::Down => mode.move_insert(Dir::Down), 432 | _ => (), 433 | } 434 | } 435 | 436 | //todo, make mode not mut and make stdout seperate 437 | fn draw(mode: &mut Mode) { 438 | match mode.input { 439 | InputMode::Normal => normal_draw(mode), 440 | InputMode::Command => command_draw(mode), 441 | InputMode::Insert => normal_draw(mode), 442 | InputMode::Select => (), 443 | } 444 | } 445 | 446 | fn truncate(s: &str, max_chars: usize) -> &str { 447 | match s.char_indices().nth(max_chars) { 448 | None => s, 449 | Some((idx, _)) => &s[..idx], 450 | } 451 | } 452 | 453 | fn valid(cells: &Vec, x: u16, y: u16) -> bool { 454 | let contents = cells.get(y as usize); 455 | return match contents { 456 | Some(cell) => cell.get(x as usize).is_some(), 457 | None => false, 458 | }; 459 | } 460 | 461 | fn normal_draw(mode: &mut Mode) { 462 | let norm = format!( 463 | "{}{}", 464 | termion::color::White.fg_str(), 465 | termion::color::Black.bg_str() 466 | ); 467 | let red = format!( 468 | "{}{}", 469 | termion::color::Red.fg_str(), 470 | termion::color::Black.bg_str() 471 | ); 472 | let invr = format!( 473 | "{}{}", 474 | termion::color::Black.fg_str(), 475 | termion::color::AnsiValue::grayscale(23).bg_string() 476 | ); 477 | let dull = format!( 478 | "{}{}", 479 | termion::color::AnsiValue::grayscale(15).fg_string(), 480 | termion::color::Black.bg_str(), 481 | ); 482 | write!(mode.stdout, "{}", termion::cursor::Hide,).unwrap(); 483 | if mode.minimap { 484 | //TODO empty cells are greyed out 485 | let width = mode.minimap_width * 2 + 3; 486 | mode.margin = width - 1; 487 | let pos = &mut mode.mode_pos; 488 | if mode.position.0 < pos.0 { 489 | pos.0 = cmp::max(pos.0, mode.minimap_width) - mode.minimap_width; 490 | } 491 | if mode.position.1 < pos.1 { 492 | pos.1 = cmp::max(pos.1, mode.minimap_height) - mode.minimap_height; 493 | } 494 | if mode.position.0 >= pos.0 + mode.minimap_width { 495 | pos.0 += mode.minimap_width; 496 | } 497 | if mode.position.1 >= pos.1 + mode.minimap_height { 498 | pos.1 += mode.minimap_height; 499 | } 500 | 501 | for y in 1..(mode.minimap_height + 1) { 502 | let mut line = String::new(); 503 | let a = "⊠"; //"▦"; //"✚"; //"⏺"; //"▣"; 504 | let b = "▢"; 505 | for x in 0..mode.minimap_width { 506 | let xx = pos.0 + x; 507 | let yy = pos.1 + y - 1; 508 | if (xx, yy) == mode.position { 509 | line.push_str(invr.as_str()); 510 | line.push_str(a); 511 | } else if ( xx == mode.position.0 && mode.view == ViewMode::Column ) 512 | || ( yy == mode.position.1 && mode.view == ViewMode::Row ) 513 | { 514 | line.push_str(invr.as_str()); 515 | line.push('⏹'); 516 | } else { 517 | if !valid(&mode.cells, xx, yy) { 518 | line.push_str(dull.as_str()); 519 | } 520 | if (xx, yy) == mode.position { 521 | line.push_str(a); 522 | } else { 523 | line.push_str(b); 524 | } 525 | } 526 | if x == mode.minimap_width - 1 || mode.view == ViewMode::Column { 527 | line.push_str(norm.as_str()); 528 | } 529 | line.push(' '); 530 | line.push_str(norm.as_str()); 531 | } 532 | write!(mode.stdout, "{}{} ", termion::cursor::Goto(2, y + 2), line).unwrap(); 533 | } 534 | 535 | write!( 536 | mode.stdout, 537 | "{}└{}┌─{:len$}┘│{}┐{}{:>len$}─┘", 538 | termion::cursor::Goto(1, 3), 539 | termion::cursor::Goto(1, 1), 540 | pos.1, 541 | termion::cursor::Goto(1, 2), 542 | pos.0, 543 | termion::cursor::Goto(1, mode.minimap_height + 3), 544 | pos.0 + mode.minimap_width - 1, 545 | termion::cursor::Goto(width - 2, mode.minimap_height + 2), 546 | termion::cursor::Goto(1, mode.minimap_height + 4), 547 | pos.1 + mode.minimap_height - 1, 548 | len = width as usize - 4, 549 | ) 550 | .unwrap(); 551 | for y in (mode.minimap_height + 4)..(mode.dims.1 - 1) { 552 | write!( 553 | mode.stdout, 554 | "{}{}", 555 | termion::cursor::Goto(1, y + 1), 556 | " ".repeat(width as usize) 557 | ) 558 | .unwrap(); 559 | } 560 | } else { 561 | mode.margin = 0; 562 | } 563 | 564 | if !mode.no_clear { 565 | let down = match mode.view { 566 | ViewMode::Column => mode.position.1, 567 | ViewMode::Row => mode.position.0, 568 | }; 569 | 570 | if down < mode.offset { 571 | mode.offset = down 572 | } 573 | 574 | if down - mode.offset > mode.dims.1 - 2 { 575 | mode.offset = down + 2 - mode.dims.1; 576 | } 577 | 578 | let line = down - mode.offset; 579 | 580 | for i in 0..(mode.dims.1 - 1) { 581 | let n = match mode.view { 582 | ViewMode::Column => i + mode.offset, 583 | ViewMode::Row => mode.position.1, 584 | }; 585 | let m = match mode.view { 586 | ViewMode::Row => i + mode.offset, 587 | ViewMode::Column => mode.position.0, 588 | }; 589 | 590 | let active = (m, n) == mode.position; 591 | let contents = mode.cells.get(n as usize); 592 | let (cell, invalid) = match contents { 593 | Some(cell) => match cell.get(m as usize) { 594 | Some(cell) => (cell.to_string(), false), 595 | None => ("¶".to_string(), true), 596 | }, 597 | None => ("¶".to_string(), false), 598 | }; 599 | 600 | let mlen = mode.dims.0 - mode.margin - 5; 601 | let cell = if active && mode.input == InputMode::Insert { 602 | mode.command.clone() 603 | } else { 604 | cell 605 | }; 606 | 607 | let cell = truncate(cell.as_str(), mlen as usize); 608 | let cell = format!("{: { 611 | if active { 612 | &invr 613 | } else if invalid { 614 | &red 615 | } else { 616 | &norm 617 | } 618 | } 619 | _ => { 620 | if active { 621 | &norm 622 | } else { 623 | &dull 624 | } 625 | } 626 | }; 627 | let cell = format!("{}{}{}", color, cell, norm); 628 | let l = match mode.view { 629 | ViewMode::Row => m, 630 | ViewMode::Column => n, 631 | }; 632 | write!( 633 | mode.stdout, 634 | "{} {:>3}: {}", 635 | termion::cursor::Goto(mode.margin, i + 1), 636 | l, 637 | cell 638 | ) 639 | .unwrap(); 640 | } 641 | write!( 642 | mode.stdout, 643 | "{}r{} c{}{}{}{}", 644 | termion::cursor::Goto(1, mode.dims.1), 645 | mode.position.1, 646 | mode.position.0, 647 | termion::clear::UntilNewline, 648 | termion::cursor::Goto(mode.margin + 6 + mode.cursor.0, line + 1), 649 | if true { 650 | termion::cursor::Show.to_string() 651 | } else { 652 | termion::cursor::Hide.to_string() 653 | }, 654 | ) 655 | .unwrap(); 656 | } 657 | } 658 | 659 | fn command_draw(mode: &mut Mode) { 660 | write!( 661 | mode.stdout, 662 | "{}{}:{}{}{}", 663 | termion::cursor::Goto(1, mode.dims.1), 664 | termion::clear::CurrentLine, 665 | mode.command, 666 | termion::cursor::Goto(mode.cursor.0 + 2, mode.dims.1), 667 | termion::cursor::Show, 668 | ) 669 | .unwrap(); 670 | } 671 | 672 | //make r replace because it doesn't do anything 673 | -------------------------------------------------------------------------------- /coronadata.csv: -------------------------------------------------------------------------------- 1 | variable_name,dataset,code_list,definition,, 2 | budget_cpp_dstb,Budget,,"Average cost of drugs budgeted per patient for drug-susceptible TB treatment, excluding buffer stock (US Dollars)" 3 | budget_cpp_mdr,Budget,,"Average cost of drugs budgeted per patient for MDR-TB treatment, excluding buffer stock (US Dollars)" 4 | budget_cpp_xdr,Budget,,"Average cost of drugs budgeted per patient for XDR-TB treatment, excluding buffer stock (US Dollars)" 5 | budget_fld,Budget,,Budget required for drugs to treat drug-susceptible TB (US Dollars) 6 | budget_lab,Budget,,"Budget required for laboratory infrastructure, equipment and supplies (US Dollars)" 7 | budget_mdrmgt,Budget,,Budget required for programme costs to treat drug-resistant TB (US Dollars) 8 | budget_orsrvy,Budget,,Budget required for operational research and surveys (US Dollars) 9 | budget_oth,Budget,,Budget required for all other budget line items (US Dollars) 10 | budget_patsup,Budget,,Budget required for patient support (US Dollars),,change,yank,yank,yank,yank,yank 11 | budget_prog,Budget,,Budget required for programme costs to treat drug-susceptible TB (US Dollars) 12 | budget_sld,Budget,,Budget required for drugs to treat drug-resistant TB (US Dollars) 13 | budget_staff,Budget,,Budget required for National TB Programme staff (central unit staff and subnational TB staff) (US Dollars) 14 | budget_tbhiv,Budget,,Budget required for collaborative TB/HIV activities (US Dollars) 15 | budget_tot,Budget,,Total budget required (US Dollars) 16 | cf_fld,Budget,,Expected funding for drugs to treat drug-susceptible TB (US Dollars) 17 | cf_lab,Budget,,"Expected funding for laboratory infrastructure, equipment and supplies (US Dollars)" 18 | cf_mdrmgt,Budget,,Expected funding for programme costs to treat drug-resistant TB (US Dollars) 19 | cf_orsrvy,Budget,,Expected funding for operational research and surveys (US Dollars) 20 | cf_oth,Budget,,Expected funding for all other budget line items (US Dollars) 21 | cf_patsup,Budget,,Expected funding for patient support (US Dollars) 22 | cf_prog,Budget,,Expected funding for programme costs to treat drug-susceptible TB (US Dollars) 23 | cf_sld,Budget,,Expected funding for drugs to treat drug-resistant TB (US Dollars) 24 | cf_staff,Budget,,Expected funding for National TB Programme staff (central unit staff and subnational TB staff) (US Dollars) 25 | cf_tbhiv,Budget,,Expected funding for collaborative TB/HIV activities (US Dollars) 26 | cf_tot,Budget,,Total expected funding for all budget line items (US Dollars) 27 | cf_tot_domestic,Budget,,"Expected funding from domestic sources, including loans (US Dollars)" 28 | cf_tot_gf,Budget,,"Expected funding from the Global Fund to Fight AIDS, Tuberculosis and Malaria (US Dollars)" 29 | cf_tot_grnt,Budget,,Expected funding from other sources (US Dollars) 30 | cf_tot_sources,Budget,,Total expected funding from all sources (US Dollars) 31 | cf_tot_usaid,Budget,,Expected funding from USAID (US Dollars) 32 | tx_dstb,Budget,,Number of patients expected to start drug-susceptible TB treatment 33 | tx_mdr,Budget,,Number of patients expected to start MDR-TB treatment 34 | tx_xdr,Budget,,Number of patients expected to start XDR-TB treatment 35 | bmu,Community engagement,,Number of TB Basic Management Units in the country 36 | bmu_community_impl,Community engagement,,Number of TB Basic Management Units which implemented community-based referrals or any form of community treatment adherence support 37 | bmu_ref_data,Community engagement,,Number of Basic Management Units with data on referrals by community health workers / community volunteers 38 | bmu_rxsupport_data,Community engagement,,Number of Basic Management Units with data on community treatment adherence support 39 | bmu_rxsupport_data_coh,Community engagement,,Total number of patients who started TB treatment in the Basic Management Units with data on community treatment adherence support 40 | community_data_available,Community engagement,0=No; 1=Yes,Are data available on community-based referrals or any form of community treatment adherence support? 41 | notified_ref,Community engagement,,Total number of new and relapse TB cases notified in the Basic Management Units with data on referrals by community health workers 42 | notified_ref_community,Community engagement,,Total number of new and relapse TB cases referred by community health workers / community volunteers in the Basic Management Units with data on referrals by community health workers 43 | rxsupport_community_coh,Community engagement,,Total number of patients who started TB treatment and who received any form of treatment adherence support from community health workers / community volunteers in the Basic Management Units with data on community treatment adherence support 44 | rxsupport_community_succ,Community engagement,,Total number of patients who were cured or who completed treatment among the cases who started TB treatment and who received any form of treatment adherence support from community health workers / community volunteers in the Basic Management Units with data on community treatment adherence support 45 | country,Country identification,,Country or territory name 46 | iso_numeric,Country identification,,ISO numeric country/territory code 47 | iso2,Country identification,,ISO 2-character country/territory code 48 | iso3,Country identification,,ISO 3-character country/territory code 49 | age_group,Disaggregated estimates,0-4=0-4 years; 5-14=5-14 years; 15-24=15-24 years ..etc; 15plus=15 years and above; 65plus=65 years and above; all=All ages;,Age group (in years) 50 | best,Disaggregated estimates,,Best estimate 51 | hi,Disaggregated estimates,,High bound of estimate 52 | lo,Disaggregated estimates,,Low bound of estimate 53 | measure,Disaggregated estimates,inc = incidence,The measure of TB burden being estimated 54 | risk_factor,Disaggregated estimates,alc=Harmful use of alcohol; dia=Diabetes; hiv=HIV; smk=Smoking; und=Undernourishment; all=All (not disaggregated by specific risk factors),Cases attributable to a specific risk factor 55 | sex,Disaggregated estimates,a=All (females and males); f=Females; m=Males,Sex 56 | unit,Disaggregated estimates,num=absolute number,The unit of measurement 57 | dst_rlt_hr_new,Drug resistance surveillance,,Number of new bacteriologically confirmed pulmonary TB patients with test results for rifampicin and isoniazid and with resistance to isoniazid (regardless of result for rifampicin) 58 | dst_rlt_hr_ret,Drug resistance surveillance,,Number of previously treated bacteriologically confirmed pulmonary TB patients with test results for rifampicin and isoniazid and with resistance to isoniazid (regardless of result for rifampicin) 59 | dst_rlt_new,Drug resistance surveillance,,Drug resistance surveillance: Among new pulmonary TB patients with positive identification for M. Tuberculosis complex (confirmed by culture and/or line-probe assay): number of patients with available drug susceptibility testing results for isoniazid and rifampicin,,,change mode append mode,,test,minimap on/off,,,saved 60 | dst_rlt_ret,Drug resistance surveillance,,Drug resistance surveillance: Among patients previously treated for TB with positive identification for M. Tuberculosis complex (confirmed by culture and/or line-probe assay): number of patients with available drug susceptibility testing results for isoniazid and rifampicin 61 | dst_rlt_rr_new,Drug resistance surveillance,,Number of new bacteriologically confirmed pulmonary TB patients with test results for rifampicin and isoniazid and with resistance to rifampicin (regardless of result for isoniazid) 62 | dst_rlt_rr_ret,Drug resistance surveillance,,Number of previously treated bacteriologically confirmed pulmonary TB patients with test results for rifampicin and isoniazid and with resistance to rifampicin (regardless of result for isoniazid) 63 | mdr_dst_rlt,Drug resistance surveillance,,Drug resistance surveillance: Total number of pulmonary MDR-TB patients with drug susceptibility test results for any fluoroquinolone and any second-line injectable agent 64 | mdr_new,Drug resistance surveillance,,Drug resistance surveillance: Among new TB patients with available drug susceptibility testing results (variable dst_rlt_new): number of patients with resistance to isoniazid and rifampicin (MDR-TB) 65 | mdr_ret,Drug resistance surveillance,,Drug resistance surveillance: Among patients previously treated for TB with available drug susceptibility testing results (variable dst_rlt_ret): number of patients with resistance to isoniazid and rifampicin (MDR-TB) 66 | nrr_014,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and who are aged 0-14 years" 67 | nrr_15plus,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and who are aged 15 years and over" 68 | nrr_ageunk,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and whose age is unknown" 69 | nrr_hivneg,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and who are HIV-negative" 70 | nrr_hivpos,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and who are HIV-positive" 71 | nrr_hivunk,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number susceptible to rifampicin and whose HIV status is unknown" 72 | pulm_labconf_new,Drug resistance surveillance,,Number of new bacteriologically confirmed pulmonary TB cases 73 | pulm_labconf_ret,Drug resistance surveillance,,Number of previously treated bacteriologically confirmed pulmonary TB cases 74 | pulm_labconf_unk,Drug resistance surveillance,,Number of bacteriologically confirmed pulmonary TB cases with unknown TB treatment history 75 | r_rlt_new,Drug resistance surveillance,,Number of new bacteriologically confirmed pulmonary TB patients with test results for rifampicin 76 | r_rlt_ret,Drug resistance surveillance,,Number of previously treated bacteriologically confirmed pulmonary TB patients with test results for rifampicin 77 | rr_014,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 78 | rr_15plus,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 15 years and over" 79 | rr_ageunk,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and whose age is unknown" 80 | rr_dr_2li,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 81 | rr_dr_fq,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 82 | rr_dr_fq_2li,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 83 | rr_ds_fq2li,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 84 | rr_dst_rlt,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are aged 0-14 years" 85 | rr_hivneg,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are HIV-negative" 86 | rr_hivpos,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and who are HIV-positive" 87 | rr_hivunk,Drug resistance surveillance,,"Among patients with results for rifampicin testing in r_rlt_new and r_rlt_ret, number resistant to rifampicin and whose HIV status is unknown" 88 | rr_new,Drug resistance surveillance,,Number of new bacteriologically confirmed pulmonary TB patients with resistance to rifampicin (RR-TB) 89 | rr_ret,Drug resistance surveillance,,Number of previously treated bacteriologically confirmed pulmonary TB patients with resistance to rifampicin (RR-TB) 90 | xdr,Drug resistance surveillance,,Drug resistance surveillance: Among pulmonary MDR-TB patients with drug susceptibility test results for any fluoroquinolone (FQ) and any second-line injectable agent (2LI) (variable mdr_dst_rlt): number with any resistance to both FQ and 2LI (i.e. XDR-TB) 91 | c_cdr,Estimates,,"Case detection rate (all forms) [also known as TB treatment coverage], percent" 92 | c_cdr_hi,Estimates,,"Case detection rate (all forms) [also known as TB treatment coverage], percent, high bound" 93 | c_cdr_lo,Estimates,,"Case detection rate (all forms) [also known as TB treatment coverage], percent, low bound" 94 | c_newinc_100k,Estimates,,"Case notification rate, which is the total of new and relapse cases and cases with unknown previous TB treatment history per 100 000 population (calculated)" 95 | cfr,Estimates,,Estimated TB case fatality ratio 96 | cfr_hi,Estimates,,Estimated TB case fatality ratio: high bound 97 | cfr_lo,Estimates,,Estimated TB case fatality ratio: low bound 98 | cfr_pct,Estimates,,Estimated TB case fatality ratio expressed as a percentage 99 | cfr_pct_hi,Estimates,,Estimated TB case fatality ratio: high bound expressed as a percentage 100 | cfr_pct_lo,Estimates,,Estimated TB case fatality ratio: low bound expressed as a percentage 101 | e_inc_100k,Estimates,,Estimated incidence (all forms) per 100 000 population 102 | e_inc_100k_hi,Estimates,,"Estimated incidence (all forms) per 100 000 population, high bound" 103 | e_inc_100k_lo,Estimates,,"Estimated incidence (all forms) per 100 000 population, low bound" 104 | e_inc_num,Estimates,,Estimated number of incident cases (all forms) 105 | e_inc_num_hi,Estimates,,"Estimated number of incident cases (all forms), high bound" 106 | e_inc_num_lo,Estimates,,"Estimated number of incident cases (all forms), low bound" 107 | e_inc_rr_num,Estimates,,Estimated incidence of rifampicin resistant TB (absolute number) 108 | e_inc_rr_num_hi,Estimates,,Estimated incidence of rifampicin resistant TB (absolute number): high bound 109 | e_inc_rr_num_lo,Estimates,,Estimated incidence of rifampicin resistant TB (absolute number): low bound 110 | e_inc_tbhiv_100k,Estimates,,Estimated incidence of TB cases who are HIV-positive per 100 000 population 111 | e_inc_tbhiv_100k_hi,Estimates,,"Estimated incidence of TB cases who are HIV-positive per 100 000 population, high bound" 112 | e_inc_tbhiv_100k_lo,Estimates,,"Estimated incidence of TB cases who are HIV-positive per 100 000 population, low bound" 113 | e_inc_tbhiv_num,Estimates,,Estimated incidence of TB cases who are HIV-positive 114 | e_inc_tbhiv_num_hi,Estimates,,"Estimated incidence of TB cases who are HIV-positive, high bound" 115 | e_inc_tbhiv_num_lo,Estimates,,"Estimated incidence of TB cases who are HIV-positive, low bound" 116 | e_mdr_pct_rr,Estimates,,Estimated percentage of rifampicin resistant TB cases that have MDR-TB 117 | e_mdr_pct_rr_new,Estimates,,Estimated percentage of new rifampicin resistant TB cases that have MDR-TB 118 | e_mdr_pct_rr_ret,Estimates,,Estimated percentage of previously treated rifampicin resistant TB cases that have MDR-TB 119 | e_mort_100k,Estimates,,Estimated mortality of TB cases (all forms) per 100 000 population 120 | e_mort_100k_hi,Estimates,,"Estimated mortality of TB cases (all forms) per 100 000 population, high bound" 121 | e_mort_100k_lo,Estimates,,"Estimated mortality of TB cases (all forms) per 100 000 population, low bound" 122 | e_mort_exc_tbhiv_100k,Estimates,,"Estimated mortality of TB cases (all forms, excluding HIV) per 100 000 population" 123 | e_mort_exc_tbhiv_100k_hi,Estimates,,"Estimated mortality of TB cases (all forms, excluding HIV), per 100 000 population, high bound" 124 | e_mort_exc_tbhiv_100k_lo,Estimates,,"Estimated mortality of TB cases (all forms, excluding HIV), per 100 000 population, low bound" 125 | e_mort_exc_tbhiv_num,Estimates,,"Estimated number of deaths from TB (all forms, excluding HIV)" 126 | e_mort_exc_tbhiv_num_hi,Estimates,,"Estimated number of deaths from TB (all forms, excluding HIV), high bound" 127 | e_mort_exc_tbhiv_num_lo,Estimates,,"Estimated number of deaths from TB (all forms, excluding HIV), low bound" 128 | e_mort_num,Estimates,,Estimated number of deaths from TB (all forms) 129 | e_mort_num_hi,Estimates,,"Estimated number of deaths from TB (all forms), high bound" 130 | e_mort_num_lo,Estimates,,"Estimated number of deaths from TB (all forms), low bound" 131 | e_mort_tbhiv_100k,Estimates,,"Estimated mortality of TB cases who are HIV-positive, per 100 000 population" 132 | e_mort_tbhiv_100k_hi,Estimates,,"Estimated mortality of TB cases who are HIV-positive, per 100 000 population, high bound" 133 | e_mort_tbhiv_100k_lo,Estimates,,"Estimated mortality of TB cases who are HIV-positive, per 100 000 population, low bound" 134 | e_mort_tbhiv_num,Estimates,,Estimated number of deaths from TB in people who are HIV-positive 135 | e_mort_tbhiv_num_hi,Estimates,,"Estimated number of deaths from TB in people who are HIV-positive, high bound" 136 | e_mort_tbhiv_num_lo,Estimates,,"Estimated number of deaths from TB in people who are HIV-positive, low bound" 137 | e_pop_num,Estimates,,Estimated total population number 138 | e_rr_in_notified_labconf_pulm,Estimates,,Estimated number of RR-TB cases among notified bacteriologically confirmed pulmonary TB cases 139 | e_rr_in_notified_labconf_pulm_hi,Estimates,,Estimated number of RR-TB cases among notified bacteriologically confirmed pulmonary TB cases: high bound 140 | e_rr_in_notified_labconf_pulm_lo,Estimates,,Estimated number of RR-TB cases among notified bacteriologically confirmed pulmonary TB cases: low bound 141 | e_rr_pct_new,Estimates,,Estimated percentage of new TB cases with rifampicin resistant TB 142 | e_rr_pct_new_hi,Estimates,,Estimated percentage of new TB cases with rifampicin resistant TB: high bound 143 | e_rr_pct_new_lo,Estimates,,Estimated percentage of new TB cases with rifampicin resistant TB: low bound 144 | e_rr_pct_ret,Estimates,,Estimated percentage of previously treated TB cases with rifampicin resistant TB 145 | e_rr_pct_ret_hi,Estimates,,Estimated percentage of previously treated TB cases with rifampicin resistant TB: high bound 146 | e_rr_pct_ret_lo,Estimates,,Estimated percentage of previously treated TB cases with rifampicin resistant TB: low bound 147 | e_tbhiv_prct,Estimates,,Estimated HIV in incident TB (percent) 148 | e_tbhiv_prct_hi,Estimates,,"Estimated HIV in incident TB (percent), high bound" 149 | e_tbhiv_prct_lo,Estimates,,"Estimated HIV in incident TB (percent), low bound" 150 | source_drs_coverage_new,Estimates,,Indicates whether national or subnational data from drug resistance surveys or surveillance was used to estimate the proportion of new TB cases with MDR-TB 151 | source_drs_coverage_ret,Estimates,,Indicates whether national or subnational data from drug resistance surveys or surveillance was used to estimate the proportion of previously treated TB cases with MDR-TB 152 | source_drs_year_new,Estimates,,"Year of drug resistance surveillance, survey or model used to estimate proportion of new TB cases with MDR-TB" 153 | source_drs_year_ret,Estimates,,"Year of drug resistance surveillance, survey or model used to estimate proportion of previously treated TB cases with MDR-TB" 154 | source_rr_new,Estimates,,Method used to estimate proportion of new TB patients with rifampicin-resistant TB 155 | source_rr_ret,Estimates,,Method used to estimate proportion of previously treated TB patients with rifampicin-resistant TB 156 | exp_cpp_dstb,Expenditure and utilisation,,"Average cost of drugs spent per patient starting first-line TB treatment, excluding buffer stock (US Dollars)" 157 | exp_cpp_mdr,Expenditure and utilisation,,"Average cost of drugs spent per patient starting second-line treatment for MDR-TB, excluding buffer stock (US Dollars)" 158 | exp_cpp_xdr,Expenditure and utilisation,,"Average cost of drugs spent per patient starting XDR-TB treatment, excluding buffer stock (US Dollars)" 159 | exp_fld,Expenditure and utilisation,,Actual expenditure on drugs to treat drug-susceptible TB (US Dollars) 160 | exp_lab,Expenditure and utilisation,,"Actual expenditure on laboratory infrastructure, equipment and supplies (US Dollars)" 161 | exp_mdrmgt,Expenditure and utilisation,,Actual expenditure on programme costs to treat drug-resistant TB (US Dollars) 162 | exp_orsrvy,Expenditure and utilisation,,Actual expenditure on operational research and surveys (US Dollars) 163 | exp_oth,Expenditure and utilisation,,Actual expenditure on all other budget line items (US Dollars) 164 | exp_patsup,Expenditure and utilisation,,Actual expenditure on patient support (US Dollars) 165 | exp_prog,Expenditure and utilisation,,Actual expenditure on programme costs to treat drug-susceptible TB (US Dollars) 166 | exp_sld,Expenditure and utilisation,,Actual expenditure on drugs to treat drug-resistant TB (US Dollars) 167 | exp_staff,Expenditure and utilisation,,Actual expenditure on National TB Programme staff (central unit staff and subnational TB staff) (US Dollars) 168 | exp_tbhiv,Expenditure and utilisation,,Actual expenditure on collaborative TB/HIV activities (US Dollars) 169 | exp_tot,Expenditure and utilisation,,Total actual expenditure (US Dollars) 170 | hcfvisit_dstb,Expenditure and utilisation,,Typical number of visits to a health facility after diagnosis for patients starting first-line TB treatment 171 | hcfvisit_mdr,Expenditure and utilisation,,Typical number of visits to a health facility after diagnosis for patients starting MDR-TB/XDR-TB treatment 172 | hosp_type_mdr,Expenditure and utilisation,2=Not applicable; 140=Primary-level hospital; 141=Secondary-level hospital; 142= Tertiary-level hospital,Type of facility most often used if MDR-TB patients are hospitalized 173 | hospd_dstb_dur,Expenditure and utilisation,,Estimated average duration of stay if patients starting first-line TB treatment are hospitalized (days) 174 | hospd_dstb_prct,Expenditure and utilisation,,Estimated percentage of patients starting first-line TB treatment that are hospitalized (%) 175 | hospd_mdr_dur,Expenditure and utilisation,,Estimated average duration of stay if patients starting MDR-TB/XDR-TB treatment are hospitalized (days) 176 | hospd_mdr_prct,Expenditure and utilisation,,Estimated percentage of patients starting MDR-TB/XDR-TB treatment that are hospitalized (%) 177 | rcvd_fld,Expenditure and utilisation,,Funding received for drugs to treat drug-susceptible TB (US Dollars) 178 | rcvd_lab,Expenditure and utilisation,,"Funding received for laboratory infrastructure, equipment and supplies (US Dollars)" 179 | rcvd_mdrmgt,Expenditure and utilisation,,Funding received for programme costs to treat drug-resistant TB (US Dollars) 180 | rcvd_orsrvy,Expenditure and utilisation,,Funding received for operational research and surveys (US Dollars) 181 | rcvd_oth,Expenditure and utilisation,,Funding received for all other budget line items (US Dollars) 182 | rcvd_patsup,Expenditure and utilisation,,Funding received for patient support (US Dollars) 183 | rcvd_prog,Expenditure and utilisation,,Funding received for programme costs to treat drug-susceptible TB (US Dollars) 184 | rcvd_sld,Expenditure and utilisation,,Funding received for drugs to treat drug-resistant TB (US Dollars) 185 | rcvd_staff,Expenditure and utilisation,,Funding received for National TB Programme staff (central unit staff and subnational TB staff) (US Dollars) 186 | rcvd_tbhiv,Expenditure and utilisation,,Funding received for collaborative TB/HIV activities (US Dollars) 187 | rcvd_tot,Expenditure and utilisation,,Total funding received for all budget line items (US Dollars) 188 | rcvd_tot_domestic,Expenditure and utilisation,,"Funding received from domestic sources, including loans (US Dollars)" 189 | rcvd_tot_gf,Expenditure and utilisation,,"Funding received from the Global Fund to Fight AIDS, Tuberculosis and Malaria (US Dollars)" 190 | rcvd_tot_grnt,Expenditure and utilisation,,Funding received from other sources (US Dollars) 191 | rcvd_tot_sources,Expenditure and utilisation,,Total funding received from all sources (US Dollars) 192 | rcvd_tot_usaid,Expenditure and utilisation,,Funding received from USAID (US Dollars) 193 | collab_private_lab,Laboratories,0=No; 1=yes,Were any non-NTP laboratories in the private sector (including NGOs) collaborating with the NTP? 194 | collab_public_lab,Laboratories,0=No; 1=yes,Were any non-NTP laboratories in the public sector collaborating with the NTP? 195 | culture,Laboratories,,Number of sites providing TB diagnostic services using culture at the end of the reporting year 196 | dst,Laboratories,,Number of sites providing phenotypic drug susceptibility testing for first-line drugs only at the end of the reporting year 197 | dst_eqa_pass,Laboratories,,Number of sites providing phenotypic drug susceptibility testing for first-line drugs only that demonstrated proficiency by panel testing 198 | lab_cul,Laboratories,,Number of laboratories providing TB diagnostic services using culture 199 | lab_dst,Laboratories,,Number of laboratories providing TB diagnostic services using drug susceptibility testing 200 | lab_dst_eqa,Laboratories,,Number of drug susceptibility testing laboratories for which External Quality Assessment (EQA) was carried out 201 | lab_dst_eqa_pass,Laboratories,,Number of drug susceptibility testing laboratories which demonstrated acceptable performance 202 | lab_lpa,Laboratories,,Number of laboratories providing TB diagnostic services using Line Probe Assay (LPA) rifampicin 203 | lab_lpa_eqa,Laboratories,,Number of Line Probe Assay (LPA) rifampicin laboratories for which External Quality Assessment (EQA) was carried out 204 | lab_lpa_eqa_pass,Laboratories,,Number of Line Probe Assay (LPA) rifampicin laboratories which demonstrated acceptable performance 205 | lab_sm,Laboratories,,Number of laboratories providing TB diagnostic services using smear microscopy 206 | lab_sm_eqa,Laboratories,,Number of smear microscopy laboratories for which External Quality Assessment (EQA) was carried out 207 | lab_sm_eqa_pass,Laboratories,,Number of smear microscopy laboratories which demonstrated acceptable performance 208 | lab_sm_led,Laboratories,,Number of laboratories providing TB diagnostic services using LED microscopes for smear microscopy 209 | lab_xpert,Laboratories,,Number of laboratories providing TB diagnostic services using xpert MTB/RIF 210 | lab_xpert_eqa,Laboratories,,Number of laboratories providing TB diagnostic services using xpert MTB/RIF for which External Quality Assessment (EQA) was carried out 211 | lpa,Laboratories,,Number of sites providing Line Probe Assay services at the end of the reporting year 212 | lpa_eqa_pass,Laboratories,,Number of sites providing Line Probe Assay services that demonstrated proficiency by panel testing 213 | nrl,Laboratories,0=No; 1=yes,Was there a national reference laboratory or laboratories (NRL)? 214 | nrl_iso15189,Laboratories,0=No; 1=yes,Has the national reference laboratory (or national reference laboratories) achieved national or international accreditation according to the ISO 15189 standard? 215 | nrl_qms,Laboratories,0=No; 1=yes,Has a formal quality management system towards achieving laboratory accreditation been implemented at the National Reference Laboratory? 216 | nrl_srl_link,Laboratories,0=No; 1=yes,Has a formal link been established between the National Reference Laboratory and a partner Supranational Reference Laboratory? 217 | qms,Laboratories,0=No; 1=yes,"Is a formal quality management system towards achieving accreditation being implemented in all laboratories conducting culture, LPA and/or DST?" 218 | sldst,Laboratories,,Number of sites providing phenotypic drug susceptibility testing for first-line drugs and second-line drugs at the end of the reporting year 219 | sldst_avail_incntry,Laboratories,0=No; 1=yes,Was second-line drug susceptibility testing available within the country for TB National Treatment Programme patients? 220 | sldst_avail_outcntry,Laboratories,0=No; 1=yes,Was second-line drug susceptibility testing available outside the country for TB National Treatment Programme patients? 221 | sldst_eqa_pass,Laboratories,,Number of sites providing phenotypic drug susceptibility testing for first-line drugs and second-line drugs that demonstrated proficiency by panel testing 222 | sllpa,Laboratories,,"Number of sites providing Line Probe Assay (LPA) services for rifampicin, isoniazid, fluoroquinolones, second-line injectables" 223 | sllpa_eqa_pass,Laboratories,,"Number of sites providing Line Probe Assay (LPA) services for rifampicin, isoniazid, fluoroquinolones, second-line injectables that demonstrated proficiency by panel testing" 224 | smear,Laboratories,,Number of sites providing TB diagnostic services using smear microscopy at the end of the reporting year 225 | smear_eqa,Laboratories,,Number of sites providing TB diagnostic services using smear microscopy covered by a comprehensive EQA system 226 | xpert,Laboratories,,Number of sites providing TB diagnostic services using Xpert MTB/RIF at the end of the reporting year 227 | xpert_eqa,Laboratories,,Number of sites providing TB diagnostic services using Xpert MTB/RIF covered by a comprehensive EQA system 228 | xpert_etrans,Laboratories,,Number of sites using Xpert MTB/RIF which transmit results automatically to clinicians and to an information management system 229 | e_prevtx_kids_pct,Latent TB infection,,Estimated % of children received TB preventive therapy aged under 5 who are household contacts of TB cases and who are eligible for TB preventive therapy 230 | e_prevtx_kids_pct_hi,Latent TB infection,,Estimated % of children received TB preventive therapy aged under 5 who are household contacts of TB cases and who are eligible for TB preventive therapy: High bound 231 | e_prevtx_kids_pct_lo,Latent TB infection,,Estimated % of children received TB preventive therapy aged under 5 who are household contacts of TB cases and who are eligible for TB preventive therapy: Low bound 232 | e_hh_size,Latent TB infection,,Estimated average household size 233 | e_prevtx_eligible,Latent TB infection,,Estimated number of children aged under 5 who are household contacts of TB cases who are eligible for TB preventive therapy 234 | e_prevtx_eligible_hi,Latent TB infection,,Estimated number of children aged under 5 who are household contacts of TB cases who are eligible for TB preventive therapy: high bound 235 | e_prevtx_eligible_lo,Latent TB infection,,Estimated number of children aged under 5 who are household contacts of TB cases who are eligible for TB preventive therapy: low bound 236 | newinc_con04_prevtx,Latent TB infection,,(If prevtx_data_available=60) Number of children aged under 5 started on TB preventive treatment who are household contacts of bacteriologically-confirmed new and relapse TB cases notified 237 | ptsurvey_newinc,Latent TB infection,,(If prevtx_data_available=61) Number of bacteriologically-confirmed TB new and relapse cases notified in the reporting year whose medical records or treatment cards were included in a survey 238 | ptsurvey_newinc_con04_prevtx,Latent TB infection,,(If prevtx_data_available=61) Number of children aged under 5 started on TB preventive treatment who are household contacts of the TB cases in ptsurvey_newinc 239 | source_hh,Latent TB infection,,Source of estimate of average household size 240 | prevtx_data_available,LTBI/Policies and services,0=No; 60= Yes available from the routine surveillance system; 61=Yes estimated from a survey of a random sample of medical records or treatment cards of TB patients representative of the national TB patient population,Are data available on the number of household contacts of TB cases started on TB preventive treatment? 241 | tbhiv_sentin_cil,Non-routine HIV surveillance,,Lower limit (95% confidence interval) of prevalence (%) of HIV in TB patients estimated using sentinel sites 242 | tbhiv_sentin_ciu,Non-routine HIV surveillance,,Upper limit (95% confidence interval) of prevalence (%) of HIV in TB patients estimated using sentinel sites 243 | tbhiv_sentin_prev,Non-routine HIV surveillance,,Prevalence (%) of HIV in TB patients estimated using sentinel sites 244 | tbhiv_sentin_yr,Non-routine HIV surveillance,,Year in which prevalence of HIV in TB patients was estimated using sentinel sites 245 | tbhiv_surv_cil,Non-routine HIV surveillance,,Lower limit (95% confidence interval) of prevalence (%) of HIV in TB patients estimated using nationwide representative surveys 246 | tbhiv_surv_ciu,Non-routine HIV surveillance,,Upper limit (95% confidence interval) of prevalence (%) of HIV in TB patients estimated using nationwide representative surveys 247 | tbhiv_surv_prev,Non-routine HIV surveillance,,"Prevalence (%) of HIV in TB patients estimated using nationwide representative 248 | surveys" 249 | tbhiv_surv_yr,Non-routine HIV surveillance,,Year in which prevalence of HIV in TB patients was estimated using nationwide representative surveys 250 | all_conf_xdr,Notification,,Number of laboratory-confirmed XDR-TB cases identified in the current year (including in MDR cases diagnosed in previous years). 251 | c_newinc,Notification,,Total of new and relapse cases and cases with unknown previous TB treatment history 252 | conf_mdr,Notification,,Number of laboratory-confirmed MDR-TB cases identified 253 | conf_mdr_tx,Notification,,Number of laboratory-confirmed MDR-TB patients who started treatment for MDR-TB 254 | conf_rrmdr,Notification,,Number of laboratory-confirmed RR-TB or MDR-TB cases identified 255 | conf_rrmdr_tx,Notification,,Number of laboratory-confirmed rifampicin-resistant (RR-TB) or multidrug-resistant TB (MDR-TB) patients who started treatment for MDR-TB 256 | conf_xdr_tx,Notification,,Number of laboratory-confirmed XDR-TB patients who started treatment for XDR-TB 257 | hiv_art,Notification,,HIV-positive TB patients started or continued on antiretroviral therapy (ART) 258 | hiv_cpt,Notification,,HIV-positive TB patients started or continued on co-trimoxazole preventive therapy (CPT) 259 | hiv_ipt,Notification,,People living with HIV newly enrolled in HIV care who started treatment for latent TB infection 260 | hiv_ipt_reg_all,Notification,,People living with HIV currently enrolled in HIV care who started treatment for latent TB infection 261 | hiv_reg,Notification,,Total number of people registered as HIV-positive regardless of year of diagnosis. (Total number of adults and children enrolled in HIV care; includes everyone in the HIV care and/or ART register) 262 | hiv_reg_all,Notification,,Number of adults and children currently enrolled in HIV care during the year. 263 | hiv_reg_new,Notification,,Number of adults and children newly enrolled in HIV care during the year. 264 | hiv_reg_new2,Notification,,Total number of adults and children newly enrolled in pre-ART care or on ART during the reporting period 265 | hiv_tbdetect,Notification,,Total number of adults and children newly enrolled in HIV care who are diagnosed as having active TB disease during the reporting period 266 | hiv_tbscr,Notification,,Number of adults and children enrolled in HIV care who had their TB status assessed and recorded during their last visit 267 | hivtest,Notification,,TB patients (new and re-treatment) with an HIV test result recorded in the TB register 268 | hivtest_pos,Notification,,TB patients (new and re-treatment) recorded as HIV-positive 269 | mdr_shortreg_tx,Notification,,Number of patients started on shorter MDR-TB treatment regiments during the reporting year 270 | mdr_shortreg_used,Notification,0=No; 1=Yes; 3=Don't know,Had any patients been started on shorter MDR-TB treatment regimens by the end of the reporting year? 271 | mdr_tx_adsm,Notification,,Number of patients actively monitored for adverse events while on MDR-TB treatment in the reporting year 272 | mdr_tx_adverse_events,Notification,,Number of patients on MDR-TB treatment who had adverse events registered in the reporting year 273 | mdrxdr_bdq_tx,Notification,,Number of patients started on Bedaquiline during the reporting year 274 | mdrxdr_bdq_used,Notification,0=No; 1=Yes; 3=Don't know,"Had any TB patients been started on Bedaquiline for the treatment of MDR-/XDR-TB by the end of reporting year as part of expanded access, compassionate use or under normal programmatic use, whether in the public or private sector?" 275 | mdrxdr_dlm_tx,Notification,,Number of patients started on Delamanid during the reporting year 276 | mdrxdr_dlm_used,Notification,0=No; 1=Yes; 3=Don't know,"Had any TB patients been started on Delamanid for the treatment of MDR-/XDR-TB by the end of reporting as part of expanded access, compassionate use or under normal programmatic use, whether in the public or private sector?" 277 | new_clindx,Notification,,"New pulmonary clinically diagnosed TB cases (not bacteriologically confirmed as positive for TB, but diagnosed with active TB by a clinician or another medical practitioner who has decided to give the patient a full course of TB treatment). It also includes pulmonary clinically diagnosed cases with unknown previous TB treatment history." 278 | new_ep,Notification,,New extrapulmonary cases (bacteriologically confirmed or clinically diagnosed). As of 2013 this also includes extrapulmonary cases with unknown previous TB treatment history. 279 | new_ep_f014,Notification,,New extrapulmonary cases: females aged 0-14 years (not used after 2012) 280 | new_ep_f04,Notification,,New extrapulmonary cases: females aged 0-4 years (not used after 2012) 281 | new_ep_f1524,Notification,,New extrapulmonary cases: females aged 15-24 years (not used after 2012) 282 | new_ep_f15plus,Notification,,New extrapulmonary cases: females aged 15 years and over (not used after 2012) 283 | new_ep_f2534,Notification,,New extrapulmonary cases: females aged 25-34 years (not used after 2012) 284 | new_ep_f3544,Notification,,New extrapulmonary cases: females aged 35-44 years (not used after 2012) 285 | new_ep_f4554,Notification,,New extrapulmonary cases: females aged 45-54 years (not used after 2012) 286 | new_ep_f514,Notification,,New extrapulmonary cases: females aged 5-14 years (not used after 2012) 287 | new_ep_f5564,Notification,,New extrapulmonary cases: females aged 55-64 years (not used after 2012) 288 | new_ep_f65,Notification,,New extrapulmonary cases: females aged 65 years and over (not used after 2012) 289 | new_ep_fu,Notification,,New extrapulmonary cases: females age unknown (not used after 2012) 290 | new_ep_m014,Notification,,New extrapulmonary cases: males aged 0-14 years (not used after 2012) 291 | new_ep_m04,Notification,,New extrapulmonary cases: males aged 0-4 years (not used after 2012) 292 | new_ep_m1524,Notification,,New extrapulmonary cases: males aged 15-24 years (not used after 2012) 293 | new_ep_m15plus,Notification,,New extrapulmonary cases: males aged 15 years and over (not used after 2012) 294 | new_ep_m2534,Notification,,New extrapulmonary cases: males aged 25-34 years (not used after 2012) 295 | new_ep_m3544,Notification,,New extrapulmonary cases: males aged 35-44 years (not used after 2012) 296 | new_ep_m4554,Notification,,New extrapulmonary cases: males aged 45-54 years (not used after 2012) 297 | new_ep_m514,Notification,,New extrapulmonary cases: males aged 5-14 years (not used after 2012) 298 | new_ep_m5564,Notification,,New extrapulmonary cases: males aged 55-64 years (not used after 2012) 299 | new_ep_m65,Notification,,New extrapulmonary cases: males aged 65 years and over (not used after 2012) 300 | new_ep_mu,Notification,,New extrapulmonary cases: males age unknown (not used after 2012) 301 | new_ep_sexunk014,Notification,,"New extrapulmonary cases: sex unknown, aged 0-14 years (not used after 2012)" 302 | new_ep_sexunk04,Notification,,"New extrapulmonary cases: sex unknown, aged 0-4 years (not used after 2012)" 303 | new_ep_sexunk15plus,Notification,,"New extrapulmonary cases: sex unknown, aged 15 years and over (not used after 2012)" 304 | new_ep_sexunk514,Notification,,"New extrapulmonary cases: sex unknown, aged 5-14 years (not used after 2012)" 305 | new_ep_sexunkageunk,Notification,,"New extrapulmonary cases: sex unknown, age unknown (not used after 2012)" 306 | new_labconf,Notification,,New pulmonary bacteriologically confirmed TB cases (smear positive or culture positive or positive by WHO-recommended rapid diagnostics such as Xpert MTB/RIF). As of 2013 this also includes pulmonary bacteriologically confirmed cases with unknown previous TB treatment history. 307 | new_oth,Notification,,Other new cases (not used after 2012) 308 | new_sn,Notification,,New pulmonary smear-negative cases (not used after 2012) 309 | new_sn_f014,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 0-14 years (not used after 2012) 310 | new_sn_f04,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 0-4 years (not used after 2012) 311 | new_sn_f1524,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 15-24 years (not used after 2012) 312 | new_sn_f15plus,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 15 years and over (not used after 2012) 313 | new_sn_f2534,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 25-34 years (not used after 2012) 314 | new_sn_f3544,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 35-44 years (not used after 2012) 315 | new_sn_f4554,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 45-54 years (not used after 2012) 316 | new_sn_f514,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 5-14 years (not used after 2012) 317 | new_sn_f5564,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 55-64 years (not used after 2012) 318 | new_sn_f65,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females aged 65 years and over (not used after 2012) 319 | new_sn_fu,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: females age unknown (not used after 2012) 320 | new_sn_m014,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 0-14 years (not used after 2012) 321 | new_sn_m04,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 0-4 years (not used after 2012) 322 | new_sn_m1524,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 15-24 years (not used after 2012) 323 | new_sn_m15plus,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 15 years and above (not used after 2012) 324 | new_sn_m2534,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 25-34 years (not used after 2012) 325 | new_sn_m3544,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 35-44 years (not used after 2012) 326 | new_sn_m4554,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 45-54 years (not used after 2012) 327 | new_sn_m514,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 5-14 years (not used after 2012) 328 | new_sn_m5564,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 55-64 years (not used after 2012) 329 | new_sn_m65,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males aged 65 years and over (not used after 2012) 330 | new_sn_mu,Notification,,New pulmonary smear negative/smear unknown/smear not done cases: males age unknown (not used after 2012) 331 | new_sn_sexunk014,Notification,,"New pulmonary smear negative/smear unknown/smear not done cases: sex unknown, aged 0-14 years (not used after 2012)" 332 | new_sn_sexunk04,Notification,,"New pulmonary smear negative/smear unknown/smear not done cases: sex unknown, aged 0-4 years (not used after 2012)" 333 | new_sn_sexunk15plus,Notification,,"New pulmonary smear negative/smear unknown/smear not done cases: sex unknown, aged 15 years and over (not used after 2012)" 334 | new_sn_sexunk514,Notification,,"New pulmonary smear negative/smear unknown/smear not done cases: sex unknown, aged 5-14 years (not used after 2012)" 335 | new_sn_sexunkageunk,Notification,,"New pulmonary smear negative/smear unknown/smear not done cases: sex unknown, age unknown (not used after 2012)" 336 | new_sp,Notification,,New pulmonary smear-positive cases (not used after 2012) 337 | new_sp_f014,Notification,,New pulmonary smear positive cases: females aged 0-14 years (not used after 2012) 338 | new_sp_f04,Notification,,New pulmonary smear positive cases: females aged 0-4 years (not used after 2012) 339 | new_sp_f1524,Notification,,New pulmonary smear positive cases: females aged 15-24 years (not used after 2012) 340 | new_sp_f2534,Notification,,New pulmonary smear positive cases: females aged 25-34 years (not used after 2012) 341 | new_sp_f3544,Notification,,New pulmonary smear positive cases: females aged 35-44 years (not used after 2012) 342 | new_sp_f4554,Notification,,New pulmonary smear positive cases: females aged 45-54 years (not used after 2012) 343 | new_sp_f514,Notification,,New pulmonary smear positive cases: females aged 5-14 years (not used after 2012) 344 | new_sp_f5564,Notification,,New pulmonary smear positive cases: females aged 55-64 years (not used after 2012) 345 | new_sp_f65,Notification,,New pulmonary smear positive cases: females aged 65 and over (not used after 2012) 346 | new_sp_fu,Notification,,New pulmonary smear positive cases: females age unknown (not used after 2012) 347 | new_sp_m014,Notification,,New pulmonary smear positive cases: males aged 0-14 years (not used after 2012) 348 | new_sp_m04,Notification,,New pulmonary smear positive cases: males aged 0-4 years (not used after 2012) 349 | new_sp_m1524,Notification,,New pulmonary smear positive cases: males aged 15-24 years (not used after 2012) 350 | new_sp_m2534,Notification,,New pulmonary smear positive cases: males aged 25-34 years (not used after 2012) 351 | new_sp_m3544,Notification,,New pulmonary smear positive cases: males aged 35-44 years (not used after 2012) 352 | new_sp_m4554,Notification,,New pulmonary smear positive cases: males aged 45-54 years (not used after 2012) 353 | new_sp_m514,Notification,,New pulmonary smear positive cases: males aged 5-14 years (not used after 2012) 354 | new_sp_m5564,Notification,,New pulmonary smear positive cases: males aged 55-64 years (not used after 2012) 355 | new_sp_m65,Notification,,New pulmonary smear positive cases: males aged 65 years and over (not used after 2012) 356 | new_sp_mu,Notification,,New pulmonary smear positive cases: males age unknown (not used after 2012) 357 | new_su,Notification,,New pulmonary smear unknown/not done cases 358 | newinc_rdx,Notification,,(if rdx_data_available=60) Number of new and relapse cases notified and tested using a WHO-recommended rapid diagnostic (for example Xpert MTB/RIF) at the time of TB diagnosis (regardless of test result) 359 | newrel_art,Notification,,"HIV-positive new and relapse (or all, if newrel_tbhiv_flg = 0 and year > 2015) TB patients started or continued on antiretroviral therapy" 360 | newrel_f014,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 0-14 years 361 | newrel_f04,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 0-4 years 362 | newrel_f1524,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 15-24 years 363 | newrel_f15plus,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 15 years and over 364 | newrel_f2534,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 25-34 years 365 | newrel_f3544,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 35-44 years 366 | newrel_f4554,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 45-54 years 367 | newrel_f514,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 5-14 years 368 | newrel_f5564,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 55-64 years 369 | newrel_f65,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females aged 65 years and over 370 | newrel_fu,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): females age unknown 371 | newrel_hivpos,Notification,,"Number of new and relapse (or all, if newrel_tbhiv_flg = 0 and year > 2015) TB patients recorded as HIV-positive" 372 | newrel_hivtest,Notification,,"Number of new and relapse (or all, if newrel_tbhiv_flg = 0 and year > 2015) TB patients tested for HIV at the time of TB diagnosis or with known HIV status at the time of TB diagnosis" 373 | newrel_m014,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 0-14 years 374 | newrel_m04,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 0-4 years 375 | newrel_m1524,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 15-24 years 376 | newrel_m15plus,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 15 years and over 377 | newrel_m2534,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 25-34 years 378 | newrel_m3544,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 35-44 years 379 | newrel_m4554,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 45-54 years 380 | newrel_m514,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 5-14 years 381 | newrel_m5564,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 55-64 years 382 | newrel_m65,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males aged 65 years and over 383 | newrel_mu,Notification,,New and relapse cases (but only new cases if rel_in_agesex_flg = 0): males age unknown 384 | newrel_sexunk014,Notification,,"New and relapse cases (but only new cases if rel_in_agesex_flg = 0): sex unknown, aged 0-14 years" 385 | newrel_sexunk04,Notification,,"New and relapse cases (but only new cases if rel_in_agesex_flg = 0): sex unknown, aged 0-4 years" 386 | newrel_sexunk15plus,Notification,,"New and relapse cases (but only new cases if rel_in_agesex_flg = 0): sex unknown, aged 15 years and over" 387 | newrel_sexunk514,Notification,,"New and relapse cases (but only new cases if rel_in_agesex_flg = 0): sex unknown, aged 5-14 years" 388 | newrel_sexunkageunk,Notification,,"New and relapse cases (but only new cases if rel_in_agesex_flg = 0): sex unknown, age unknown" 389 | newrel_tbhiv_flg,Notification,0=No; 1=Yes.,"Are data on HIV testing, HIV positivity and provision of antiretroviral therapy (ART) restricted to new and relapse TB cases only?" 390 | newret_oth,Notification,,Other cases not included in new and re-treatment case numbers 391 | notif_foreign,Notification,,New and re-treatment TB cases among foreign-born individuals 392 | rdst_new,Notification,,"Number of TB cases (pulmonary or extrapulmonary) tested for susceptibility to rifampicin using phenotypic DST or WHO-recommended rapid molecular diagnostics (e.g. Xpert MTB/RIF), before or after starting treatment: new cases" 393 | rdst_ret,Notification,,"Number of TB cases (pulmonary or extrapulmonary) tested for susceptibility to rifampicin using phenotypic DST or WHO-recommended rapid molecular diagnostics (e.g. Xpert MTB/RIF), before or after starting treatment: previously treated cases" 394 | rdst_unk,Notification,,"Number of TB cases (pulmonary or extrapulmonary) tested for susceptibility to rifampicin using phenotypic DST or WHO-recommended rapid molecular diagnostics (e.g. Xpert MTB/RIF), before or after starting treatment: cases with unknown previous TB treatment history" 395 | rdx_data_available,Notification,0=No; 60= Yes available from the routine surveillance system; 61=Yes estimated from a survey of a random sample of medical records or treatment cards of TB patients representative of the national TB patient population,Are data available on the number of new and relapse cases tested using a WHO-recommended rapid diagnostic during the reporting year? 396 | rdxsurvey_newinc,Notification,,(if rdx_data_available=61) Number of new and relapse cases whose medical records or treatment cards were included in the survey 397 | rdxsurvey_newinc_rdx,Notification,,(if rdx_data_available=61) Among the cases reported in rdxsurvey_newinc the number tested using a WHO-recommended rapid diagnostic (such as Xpert MTB/RIF) at the time of TB diagnosis (regardless of test result) 398 | rel_in_agesex_flg,Notification,0=No; 1=Yes.,Are all relapse cases included with new cases in the disaggregations by age and sex? 399 | ret_nrel,Notification,,"Previously treated patients, excluding relapse cases (pulmonary or extrapulmonary, bacteriologically confirmed or clinically diagnosed)" 400 | ret_oth,Notification,,Other re-treatment cases 401 | ret_rel,Notification,,Relapse cases 402 | ret_rel_clindx,Notification,,"Relapse pulmonary clinically diagnosed TB cases (not bacteriologically confirmed as positive for TB, but diagnosed with active TB by a clinician or another medical practitioner who has decided to give the patient a full course of TB treatment)." 403 | ret_rel_ep,Notification,,Relapse extrapulmonary cases (bacteriologically confirmed or clinically diagnosed) 404 | ret_rel_labconf,Notification,,Relapse pulmonary bacteriologically confirmed TB cases (smear positive or culture positive or positive by WHO-recommended rapid diagnostics such as Xpert MTB/RIF). 405 | ret_tad,Notification,,Treatment after default cases 406 | ret_taf,Notification,,Treatment after failure cases 407 | rr_sldst,Notification,,Number of laboratory-confirmed RR-TB or MDR-TB cases tested for susceptibility to second-line drugs (fluoroquinolones and second-line injectable agents) 408 | unconf_mdr_tx,Notification,,Number of MDR-TB (not laboratory-confirmed) patients who started treatment for MDR-TB 409 | unconf_rrmdr_tx,Notification,,Number of patients (not laboratory-confirmed as having rifampicin-resistant (RR-TB) or multidrg-resistant TB (MDR-TB)) who started treatment for MDR-TB 410 | c_new_snep_tsr,Outcomes,,"Treatment success rate for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases, percent (not used after 2011)" 411 | c_new_sp_tsr,Outcomes,,"Treatment success rate for new pulmonary smear-positive (and/or culture-positive) cases, percent (not used after 2011)" 412 | c_new_tsr,Outcomes,,"Treatment success rate for all new cases (including relapse cases if rel_with_new_flg = 1), percent" 413 | c_ret_tsr,Outcomes,,"Treatment success rate for re-treatment cases (excluding relapse cases if rel_with_new_flg = 1), percent" 414 | c_tbhiv_tsr,Outcomes,,"Treatment success rate for HIV-positive TB cases, percent" 415 | hiv_new_snep_cmplt,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done HIV-positive TB cases: completed (not used after 2011) 416 | hiv_new_snep_coh,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done HIV-positive TB cases: cohort size (not used after 2011) 417 | hiv_new_snep_def,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done HIV-positive TB cases: defaulted (not used after 2011) 418 | hiv_new_snep_died,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done HIV-positive TB cases: died (not used after 2011) 419 | hiv_new_snep_fail,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done HIV-positive TB cases: failed (not used after 2011) 420 | hiv_new_sp_cmplt,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: completed (not used after 2011) 421 | hiv_new_sp_coh,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: cohort size (not used after 2011) 422 | hiv_new_sp_cur,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: cured (not used after 2011) 423 | hiv_new_sp_def,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: defaulted (not used after 2011) 424 | hiv_new_sp_died,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: died (not used after 2011) 425 | hiv_new_sp_fail,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) HIV-positive TB cases: failed (not used after 2011) 426 | hiv_ret_cmplt,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: completed (not used after 2011) 427 | hiv_ret_coh,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: cohort size (not used after 2011) 428 | hiv_ret_cur,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: cured (not used after 2011) 429 | hiv_ret_def,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: defaulted (not used after 2011) 430 | hiv_ret_died,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: died (not used after 2011) 431 | hiv_ret_fail,Outcomes,,Outcomes for re-treatment HIV-positive TB cases: failed (not used after 2011) 432 | mdr_coh,Outcomes,,Outcomes for MDR-TB cases: cohort size 433 | mdr_died,Outcomes,,Outcomes for MDR-TB cases: died 434 | mdr_fail,Outcomes,,Outcomes for MDR-TB cases: treatment failed 435 | mdr_lost,Outcomes,,Outcomes for MDR-TB cases: lost to follow-up 436 | mdr_succ,Outcomes,,Outcomes for MDR-TB cases: treatment success (Cured or treatment completed) 437 | new_snep_cmplt,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases: completed (not used after 2011) 438 | new_snep_coh,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases: cohort size (not used after 2011) 439 | new_snep_def,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases: defauled (not used after 2011) 440 | new_snep_died,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases: died (not used after 2011) 441 | new_snep_fail,Outcomes,,Outcomes for new pulmonary smear-negative/extrapulmonary/smear unknown/smear not done cases: failed (not used after 2011) 442 | new_sp_cmplt,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: completed (not used after 2011) 443 | new_sp_coh,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: cohort size (not used after 2011) 444 | new_sp_cur,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: cured (not used after 2011) 445 | new_sp_def,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: defaulted (not used after 2011) 446 | new_sp_died,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: died (not used after 2011) 447 | new_sp_fail,Outcomes,,Outcomes for new pulmonary smear-positive (and/or culture-positive) cases: failed (not used after 2011) 448 | newrel_coh,Outcomes,,Outcomes for all new and relapse cases (but only new cases if rel_with_new_flg = 0): cohort size 449 | newrel_died,Outcomes,,Outcomes for all new and relapse cases (but only new cases if rel_with_new_flg = 0): died 450 | newrel_fail,Outcomes,,Outcomes for all new and relapse cases (but only new cases if rel_with_new_flg = 0): treatment failed 451 | newrel_lost,Outcomes,,Outcomes for all new and relapse cases (but only new cases if rel_with_new_flg = 0): lost to follow-up 452 | newrel_succ,Outcomes,,Outcomes for all new and relapse cases (but only new cases if rel_with_new_flg = 0): treatment success (cured or treatment completed) 453 | rel_with_new_flg,Outcomes,0=No; 1=Yes;,Are outcomes of relapse cases included in the newrel outcome variables? 454 | rep_meth,Outcomes,100=smear;101=culture;102=smear or culture;,Method of confirmation used to report treatment outcomes of pulmonary cases (not used after 2011) 455 | ret_cmplt,Outcomes,,Outcomes for re-treatment cases: completed (not used after 2011) 456 | ret_coh,Outcomes,,Outcomes for re-treatment cases: cohort size (not used after 2011) 457 | ret_cur,Outcomes,,Outcomes for re-treatment cases: cured (not used after 2011) 458 | ret_def,Outcomes,,Outcomes for re-treatment cases: defaulted (not used after 2011) 459 | ret_died,Outcomes,,Outcomes for re-treatment cases: died (not used after 2011) 460 | ret_fail,Outcomes,,Outcomes for re-treatment cases: failed (not used after 2011) 461 | ret_nrel_coh,Outcomes,,Outcomes for previously treated patients (excluding relapse cases if rel_with_new_flg = 1): cohort size 462 | ret_nrel_died,Outcomes,,Outcomes for previously treated patients (excluding relapse cases if rel_with_new_flg = 1): died 463 | ret_nrel_fail,Outcomes,,Outcomes for previously treated patients (excluding relapse cases if rel_with_new_flg = 1): treatment failed 464 | ret_nrel_lost,Outcomes,,Outcomes for previously treated patients (excluding relapse cases if rel_with_new_flg = 1): lost to follow-up 465 | ret_nrel_succ,Outcomes,,Outcomes for previously treated patients (excluding relapse cases if rel_with_new_flg = 1): treatment success (cured or treatment completed) 466 | tbhiv_coh,Outcomes,,"Outcomes for HIV-positive TB cases, all types: cohort size" 467 | tbhiv_died,Outcomes,,"Outcomes for HIV-positive TB cases, all types: died" 468 | tbhiv_fail,Outcomes,,"Outcomes for HIV-positive TB cases, all types: treatment failed" 469 | tbhiv_lost,Outcomes,,"Outcomes for HIV-positive TB cases, all types: lost to follow-up" 470 | tbhiv_succ,Outcomes,,"Outcomes for HIV-positive TB cases, all types: treatment success (cured or treatment completed)" 471 | xdr_coh,Outcomes,,Outcomes for XDR-TB cases: cohort size 472 | xdr_died,Outcomes,,Outcomes for XDR-TB cases: number died 473 | xdr_fail,Outcomes,,Outcomes for XDR-TB cases: number whose treatment failed 474 | xdr_lost,Outcomes,,Outcomes for XDR-TB cases: lost to follow-up 475 | xdr_succ,Outcomes,,Outcomes for XDR-TB cases: treatment success (Cured or treatment completed) 476 | caseb_err_nat,Policies and services,0=No; 42=Yes (all TB patients in the country); 43=Yes (but only for MDR-TB patients countrywide),Did the National Treatment Programme keep (or have access to) an electronic case-based database for TB patients on treatment at national level 477 | digital_adherence_support,Policies and services,3=don't know; 210=Not used by any treatment centre; 211=Used only by public sector treatment centres; 212=Used only by private sector treatment centres; 213=Used by public and private sector treatment centres,"Did any treatment centre use digital technologies such as short text messaging via mobile phones, video-communication or electronic medication monitors to support TB medication adherence in patients at risk of interrupting treatment?" 478 | ep_spec_available,Policies and services,0=No; 1=Yes; 2=Not applicable,Are data available on the number of bacteriologically confirmed extrapulmonary TB cases with test results for the speciation of the Mycobacterium tuberculosis complex in the reporting year? 479 | free_dx_followup,Policies and services,0=No; 1=yes,"Does national policy indicate that TB diagnostic and follow-up tests provided through the national TB programme are free of charge or that fees can be fully reimbursed through health insurance, or both, for all people with signs or symptoms of TB?" 480 | hcw_tb_infected,Policies and services,,Number of health-care workers who had TB 481 | hcw_tot,Policies and services,,Total number of health-care workers who were working in the country in the public and private sector 482 | lf_urine_lam,Policies and services,0=No; 1=yes,Does national policy and the diagnostic algorithm indicate the use of the lateral flow urine lipoarabinomannan assay (LF-LAM) to assist in the detection of TB in people living with HIV? 483 | mdrxdr_fail_morphine,Policies and services,,Number of patients who started second-line TB treatment 3 years previously whose treatment failed and who received oral morphine by prescription to treat pain or terminal dyspnoea 484 | newinc_con_prevtx,Policies and services,,(If prevtx_data_available=60) Number of household contacts of bacteriologically-confirmed pulmonary new and relapse TB cases notified in the reporting year who were started on TB preventive treatment 485 | newrel_ep_labconf,Policies and services,,"(if ep_spec_available=1) Among the new and relapse extrapulmonary TB cases reported in new_ep and ret_rel_ep, the number of cases that were bacteriologically confirmed, i.e. by culture or molecular technologies" 486 | newrel_ep_mbovis,Policies and services,,"(if ep_spec_available=1) Among extrapulmonary TB cases with test results for speciation reported in newrel_ep_spec, number of cases identified as having Mycobacterium bovis" 487 | newrel_ep_spec,Policies and services,,"(if ep_spec_available=1) Among bacteriologically confirmed extrapulmonary TB cases reported in newrel_ep_labconf, number of cases with test results for the speciation of the Mycobacterium tuberculosis complex" 488 | newrel_pulm_mbovis,Policies and services,,"(if pulm_spec_available=1) Among pulmonary cases with test results for speciation reported in newrel_pulm_spec, number of cases identified as having Mycobacterium bovis" 489 | newrel_pulm_spec,Policies and services,,"(if pulm_spec_available=1) Among bacteriologically confirmed new and relapse pulmonary TB cases, number of cases with test results for the speciation of the Mycobacterium tuberculosis complex" 490 | prevtx_short_data_available,Policies and services,0=No; 1=Yes; 2=Not applicable,Are data available on the number of patients treated using shorter TB preventive treatment regimens containing rifampicin or rifapentine? 491 | prevtx_short_rifamycin,Policies and services,,(if prevtx_short_data_available=1) Total number of individuals started on shorter TB preventive treatment regimens containing rifampicin or rifapentine in the reporting year 492 | priv_new_dx,Policies and services,,Number of new cases of TB diagnosed according to National Treatment Programme (NTP) guidelines by private providers 493 | ptsurvey_newinc_con_prevtx,Policies and services,,(If prevtx_data_available=61) Number of household contacts of the TB cases surveyed in ptsurvey_newinc who were started on TB preventive treatment. 494 | pub_new_dx,Policies and services,,Number of new cases of TB diagnosed according to National Treatment Programme (NTP) guidelines by non-NTP public providers 495 | pulm_spec_available,Policies and services,0=No; 1=Yes; 2=Not applicable,Are data available on the number of bacteriologically confirmed pulmonary TB cases with test results for the speciation of the Mycobacterium tuberculosis complex in the reporting year? 496 | universal_dst,Policies and services,0=No; 1=yes,Does national policy and the diagnostic algorithm indicate there is universal access to drug susceptibility testing? 497 | wrd_initial_test,Policies and services,0=No; 1=yes,Does national policy and the diagnostic algorithm indicate a WHO-recommended rapid diagnostic as the initial diagnostic test for all people with signs or symptoms of TB? 498 | --------------------------------------------------------------------------------