diff --git a/config.toml b/config.toml
index 6144703..4725f8a 100644
--- a/config.toml
+++ b/config.toml
@@ -1,4 +1,4 @@
-[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc]
+[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc_CONUS]
 from = "https://mrms.ncep.noaa.gov/data/2D/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
 needs_gzip = true
 valid_for = 120
@@ -13,4 +13,72 @@ Color:  70   255  255  255    128 128 128
 Color:  80   128  128  128
 """
 missing = -99.0
+no_coverage = -999.0
+
+[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc_ALASKA]
+from = "https://mrms.ncep.noaa.gov/data/2D/ALASKA/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
+needs_gzip = true
+valid_for = 120
+palette = """
+Color:  10   164  164  255    100 100 192
+Color:  20    64  128  255     32  64 128
+Color:  30     0  255    0      0 128   0
+Color:  40   255  255    0    255 128   0
+Color:  50   255    0    0    160   0   0
+Color:  60   255    0  255    128   0 128
+Color:  70   255  255  255    128 128 128
+Color:  80   128  128  128
+"""
+missing = -99.0
+no_coverage = -999.0
+
+[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc_CARIB]
+from = "https://mrms.ncep.noaa.gov/data/2D/CARIB/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
+needs_gzip = true
+valid_for = 120
+palette = """
+Color:  10   164  164  255    100 100 192
+Color:  20    64  128  255     32  64 128
+Color:  30     0  255    0      0 128   0
+Color:  40   255  255    0    255 128   0
+Color:  50   255    0    0    160   0   0
+Color:  60   255    0  255    128   0 128
+Color:  70   255  255  255    128 128 128
+Color:  80   128  128  128
+"""
+missing = -99.0
+no_coverage = -999.0
+
+[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc_GUAM]
+from = "https://mrms.ncep.noaa.gov/data/2D/GUAM/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
+needs_gzip = true
+valid_for = 120
+palette = """
+Color:  10   164  164  255    100 100 192
+Color:  20    64  128  255     32  64 128
+Color:  30     0  255    0      0 128   0
+Color:  40   255  255    0    255 128   0
+Color:  50   255    0    0    160   0   0
+Color:  60   255    0  255    128   0 128
+Color:  70   255  255  255    128 128 128
+Color:  80   128  128  128
+"""
+missing = -99.0
+no_coverage = -999.0
+
+[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc_HAWAII]
+from = "https://mrms.ncep.noaa.gov/data/2D/HAWAII/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
+needs_gzip = true
+valid_for = 120
+palette = """
+Color:  10   164  164  255    100 100 192
+Color:  20    64  128  255     32  64 128
+Color:  30     0  255    0      0 128   0
+Color:  40   255  255    0    255 128   0
+Color:  50   255    0    0    160   0   0
+Color:  60   255    0  255    128   0 128
+Color:  70   255  255  255    128 128 128
+Color:  80   128  128  128
+"""
+missing = -99.0
 no_coverage = -999.0
\ No newline at end of file
diff --git a/wxbox-tiler/src/sources/grib2.rs b/wxbox-tiler/src/sources/grib2.rs
index 2781aed..d3ab883 100644
--- a/wxbox-tiler/src/sources/grib2.rs
+++ b/wxbox-tiler/src/sources/grib2.rs
@@ -1,7 +1,7 @@
 use std::collections::{BTreeMap, HashMap};
 use std::f64::consts::PI;
 use std::io::{BufWriter, Cursor, Read};
-use std::ops::{Add, Mul, Sub};
+use std::ops::{Add, Div, Mul, Sub};
 use std::sync::Arc;
 use std::time::SystemTime;
 use actix_web::error::UrlencodedError::ContentType;
@@ -19,7 +19,7 @@ use wxbox_grib2::GribMessage;
 use wxbox_grib2::wgs84::LatLong;
 use wxbox_pal::{Color, ColorPalette, Palette};
 use crate::AppState;
-use tracing::debug;
+use tracing::{debug, info};
 use crate::config::Grib2Source;
 use crate::pixmap::Pixmap;
 
@@ -75,7 +75,7 @@ pub async fn reload_if_required(from: &str, needs_gzip: bool, valid_for: u64, lu
 const TWO_PI: f64 = PI * 2.0;
 const HALF_PI: f64 = PI / 2.0;
 
-pub async fn render(xtile: f64, ytile: f64, z: i32, tilesize: usize, pal: Palette, map: &Arc<RwLock<GribMessage>>, missing: Option<f64>, range_folded: Option<f64>, no_coverage: Option<f64>) -> Pixmap {
+pub async fn render(xtile: f64, ytile: f64, z: i32, tilesize: usize, pal: Palette, map: &Arc<RwLock<GribMessage>>, missing: Option<f64>, range_folded: Option<f64>, no_coverage: Option<f64>, options: &TileRequestOptions) -> Pixmap {
     let mut image: Pixmap = Pixmap::new();
 
     let denominator = 2.0_f64.powi(z) * tilesize as f64;
@@ -98,11 +98,24 @@ pub async fn render(xtile: f64, ytile: f64, z: i32, tilesize: usize, pal: Palett
                 }).map(|u| u as f64);
 
                 let color = match nearest {
-                    Some(c) if Some(c) == no_coverage => Color { red: 0, green: 0, blue: 0, alpha: 255 },
+                    Some(c) if Some(c) == no_coverage => Color { red: 0, green: 0, blue: 0, alpha: 30 },
                     Some(c) if Some(c) == missing => Color { red: 0, green: 0, blue: 0, alpha: 0 },
-                    Some(c) if Some(c) == range_folded => Color { red: 141, green: 0, blue: 160, alpha: 255 },
+                    Some(c) if Some(c) == range_folded => {
+                        if options.show_range_folded {
+                            let color_raw = options.range_folded_color.to_be_bytes();
+                            Color { red: color_raw[0], green: color_raw[1], blue: color_raw[2], alpha: color_raw[3] }
+                        } else {
+                            Color { red: 0, green: 0, blue: 0, alpha: 0 }
+                        }
+                    },
                     Some(value_at_pos) => {
-                        pal.colorize(value_at_pos)
+                        let mut c = pal.colorize(value_at_pos);
+                        if c.red == 0 && c.green == 0 && c.blue == 0 {
+                            c.alpha = 0;
+                        } else {
+                            c.alpha = coloru8(options.data_transparency);
+                        }
+                        c
                     },
                     None => Color { red: 0, green: 0, blue: 0, alpha: 30 }
                 };
@@ -214,22 +227,48 @@ impl Mul for ColorF64 {
         }
     }
 }
+impl Div for ColorF64 {
+    type Output = ColorF64;
+
+    fn div(self, rhs: Self) -> Self::Output {
+        Self {
+            red: self.red / rhs.red,
+            green: self.green / rhs.green,
+            blue: self.blue / rhs.blue,
+            alpha: self.alpha / rhs.alpha
+        }
+    }
+}
+impl Div<f64> for ColorF64 {
+    type Output = ColorF64;
+
+    fn div(self, rhs: f64) -> Self::Output {
+        Self {
+            red: self.red / rhs,
+            green: self.green / rhs,
+            blue: self.blue / rhs,
+            alpha: self.alpha / rhs
+        }
+    }
+}
 
 
-pub fn merge(base: Pixmap, data: Pixmap, settings: &TileRequestOptions) -> Pixmap {
+pub fn merge(base: Pixmap, data: Pixmap) -> Pixmap {
     let mut new = Pixmap::new();
 
     for x in 0..256 {
         for y in 0..256 {
             let mut c_b: ColorF64 = base.get(x, y).into();
-            let a_b = 1.0;
             let mut c_s: ColorF64 = data.get(x, y).into();
-            let a_s = settings.data_transparency;
 
-            let mut co = c_s * a_s + c_b * a_b * (1.0 - a_s);
-            co.alpha = 1.0;
+            if c_s.red == 0.0 && c_s.green == 0.0 && c_s.blue == 0.0 && c_s.alpha == 0.0 {
+                new.set(x, y, c_b.into());
+            } else {
+                let mut co = (c_s * c_s.alpha + c_b * c_b.alpha * (1.0 - c_s.alpha)) / (c_s.alpha + c_b.alpha * (1.0 - c_s.alpha));
+                co.alpha = 1.0;
 
-            new.set(x, y, co.into());
+                new.set(x, y, co.into());
+            }
         }
     }
 
@@ -289,7 +328,7 @@ pub async fn source(path: actix_web::web::Path<(i32, u32, u32)>, req: Query<Quer
             ).await;
             let lct_reader = data.grib2_cache_timestamps.read().await;
             if let Some(grib2) = data.grib2_cache.read().await.get(&settings.data) {
-                crate::sources::grib2::render(path.1 as f64, path.2 as f64, path.0, 256, wxbox_pal::parser::parse(&known_source.palette).unwrap(), grib2, known_source.missing, known_source.range_folded, known_source.no_coverage).await
+                crate::sources::grib2::render(path.1 as f64, path.2 as f64, path.0, 256, wxbox_pal::parser::parse(&known_source.palette).unwrap(), grib2, known_source.missing, known_source.range_folded, known_source.no_coverage, &settings).await
             } else {
                 debug!("not found grib2 after reload in base cache");
                 return HttpResponse::new(StatusCode::NOT_FOUND)
@@ -303,8 +342,7 @@ pub async fn source(path: actix_web::web::Path<(i32, u32, u32)>, req: Query<Quer
         return HttpResponse::new(StatusCode::NOT_FOUND)
     };
 
-    let image = merge(base_layer, data_layer, &settings);
-    //let image = base_layer;
+    let image = merge(base_layer, data_layer);
 
     let mut buf: Vec<u8> = vec![];
     // borrow checker insanity
diff --git a/wxbox_client/src/lib.rs b/wxbox_client/src/lib.rs
index b3db134..5d53d54 100644
--- a/wxbox_client/src/lib.rs
+++ b/wxbox_client/src/lib.rs
@@ -1,14 +1,20 @@
+mod toggle_switch;
+
 use std::collections::HashMap;
 use std::env::var;
-use egui::{Align2, Frame, Window};
+use egui::{Align2, CollapsingHeader, Color32, Frame, UiBuilder, Window};
 use egui::Context;
 use walkers::{HttpOptions, HttpTiles, MapMemory, Position, TileId, Tiles};
 use walkers::sources::{Attribution, TileSource};
 use wxbox_common::TileRequestOptions;
+use crate::toggle_switch::toggle;
 
 pub struct WxboxApp {
     provider: HttpTiles,
-    map_memory: MapMemory
+    map_memory: MapMemory,
+    tile_request_options: TileRequestOptions,
+
+    rf_color: Color32
 }
 
 pub struct DynamicUrlSource {
@@ -45,15 +51,19 @@ impl TileSource for DynamicUrlSource {
 impl WxboxApp {
     pub fn new(ctx: Context) -> Self {
         egui_extras::install_image_loaders(&ctx);
+
+        let req_options = TileRequestOptions {
+            baselayer: "osm".to_string(),
+
+            data: "grib2/noaa_mrms_merged_composite_reflectivity_qc_CONUS".to_string(),
+            data_transparency: 0.9,
+            show_range_folded: false,
+            range_folded_color: 0x8d00a0ff,
+        };
         
         Self {
             provider: HttpTiles::with_options(
-                DynamicUrlSource::new_from(&TileRequestOptions {
-                    baselayer: "osm".to_string(),
-
-                    data: "grib2/noaa_mrms_merged_composite_reflectivity_qc".to_string(),
-                    data_transparency: 0.9,
-                }),
+                DynamicUrlSource::new_from(&req_options),
                 HttpOptions {
                     cache: if cfg!(target_arch = "wasm32") {
                         None
@@ -64,7 +74,9 @@ impl WxboxApp {
                 },
                 ctx.clone()
             ),
-            map_memory: MapMemory::default()
+            map_memory: MapMemory::default(),
+            tile_request_options: req_options,
+            rf_color: Color32::from_hex("#8d00a0ff").unwrap()
         }
     }
 }
@@ -79,12 +91,19 @@ impl eframe::App for WxboxApp {
         egui::CentralPanel::default()
             .frame(rimless)
             .show(ctx, |ui| {
+                let Self {
+                    provider,
+                    map_memory,
+                    tile_request_options,
+                    rf_color
+                } = self;
+
                 let position = Position::from_lat_lon(44.967243, -103.771556);
 
-                let tiles = &mut self.provider;
+                let tiles = provider;
                 let attribution = tiles.attribution();
 
-                let map = walkers::Map::new(Some(tiles), &mut self.map_memory, position);
+                let map = walkers::Map::new(Some(tiles), map_memory, position);
 
                 ui.add(map);
 
@@ -100,9 +119,82 @@ impl eframe::App for WxboxApp {
                     });
 
                 Window::new("wxbox")
+                    .resizable(false)
                     .show(ui.ctx(), |ui| {
                         ui.label("Welcome to wxbox!")
-                    })
+                    });
+
+                let mut need_to_reset_for_next_frame = false;
+
+                Window::new("Datasource")
+                    .resizable(false)
+                    .show(ui.ctx(), |ui| {
+                        ui.collapsing("NOAA", |ui| {
+                            ui.collapsing("Multi-Radar Multi-Sensor", |ui| {
+                                for location in ["CONUS", "ALASKA", "CARIB", "GUAM", "HAWAII"] {
+                                    ui.collapsing(location, |ui| {
+                                        ui.collapsing("Composite Reflectivity", |ui| {
+                                            if ui.radio_value(&mut tile_request_options.data, format!("grib2/noaa_mrms_merged_composite_reflectivity_qc_{}", location), "Composite Reflectivity (QCd)").changed() {
+                                                need_to_reset_for_next_frame = true;
+                                            }
+                                        });
+                                    });
+                                }
+                            });
+                        });
+                    });
+
+                Window::new("Datasource Settings")
+                    .resizable(false)
+                    .show(ui.ctx(), |ui| {
+                        let mut ui_builder = UiBuilder::new();
+                        ui.scope_builder(ui_builder, |ui| {
+                            egui::Grid::new("dsconfig_grid")
+                                .num_columns(2)
+                                .spacing([40.0, 4.0])
+                                .striped(true)
+                                .show(ui, |ui| {
+                                    ui.label("Data opacity");
+                                    if ui.add(egui::Slider::new(&mut tile_request_options.data_transparency, 0.0..=1.0).suffix("%").custom_formatter(
+                                        |u, v| {
+                                            egui::emath::format_with_decimals_in_range(u * 100.0, v)
+                                        }
+                                    )).changed() {
+                                        need_to_reset_for_next_frame = true;
+                                    }
+                                    ui.end_row();
+
+                                    ui.label("Show range folded areas");
+                                    if ui.add(toggle(&mut tile_request_options.show_range_folded)).changed() {
+                                        need_to_reset_for_next_frame = true;
+                                    }
+                                    ui.end_row();
+
+                                    ui.label("Range folded color");
+                                    if ui.color_edit_button_srgba(rf_color).changed() {
+                                        let color = rf_color.to_array();
+                                        let single_number = u32::from_be_bytes(color);
+                                        tile_request_options.range_folded_color = single_number;
+                                        need_to_reset_for_next_frame = true;
+                                    }
+                                })
+                        })
+                    });
+
+                if need_to_reset_for_next_frame {
+                    *tiles = HttpTiles::with_options(
+                        DynamicUrlSource::new_from(tile_request_options),
+                        HttpOptions {
+                            cache: if cfg!(target_arch = "wasm32") {
+                                None
+                            } else {
+                                Some(".cache".into())
+                            },
+                            user_agent: None,
+                        },
+                        ctx.clone()
+                    );
+                }
             });
     }
 }
\ No newline at end of file
diff --git a/wxbox_client/src/toggle_switch.rs b/wxbox_client/src/toggle_switch.rs
new file mode 100644
index 0000000..f14b75b
--- /dev/null
+++ b/wxbox_client/src/toggle_switch.rs
@@ -0,0 +1,111 @@
+//! Source code example of how to create your own widget.
+//! This is meant to be read as a tutorial, hence the plethora of comments.
+
+/// iOS-style toggle switch:
+///
+/// ``` text
+///      _____________
+///     /       /.....\
+///    |       |.......|
+///     \_______\_____/
+/// ```
+///
+/// ## Example:
+/// ``` ignore
+/// toggle_ui(ui, &mut my_bool);
+/// ```
+pub fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
+    // Widget code can be broken up in four steps:
+    //  1. Decide a size for the widget
+    //  2. Allocate space for it
+    //  3. Handle interactions with the widget (if any)
+    //  4. Paint the widget
+
+    // 1. Deciding widget size:
+    // You can query the `ui` how much space is available,
+    // but in this example we have a fixed size widget based on the height of a standard button:
+    let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0, 1.0);
+
+    // 2. Allocating space:
+    // This is where we get a region of the screen assigned.
+    // We also tell the Ui to sense clicks in the allocated region.
+    let (rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
+
+    // 3. Interact: Time to check for clicks!
+    if response.clicked() {
+        *on = !*on;
+        response.mark_changed(); // report back that the value changed
+    }
+
+    // Attach some meta-data to the response which can be used by screen readers:
+    response.widget_info(|| {
+        egui::WidgetInfo::selected(egui::WidgetType::Checkbox, ui.is_enabled(), *on, "")
+    });
+
+    // 4. Paint!
+    // Make sure we need to paint:
+    if ui.is_rect_visible(rect) {
+        // Let's ask for a simple animation from egui.
+        // egui keeps track of changes in the boolean associated with the id and
+        // returns an animated value in the 0-1 range for how much "on" we are.
+        let how_on = ui.ctx().animate_bool_responsive(response.id, *on);
+        // We will follow the current style by asking
+        // "how should something that is being interacted with be painted?".
+        // This will, for instance, give us different colors when the widget is hovered or clicked.
+        let visuals = ui.style().interact_selectable(&response, *on);
+        // All coordinates are in absolute screen coordinates so we use `rect` to place the elements.
+        let rect = rect.expand(visuals.expansion);
+        let radius = 0.5 * rect.height();
+        ui.painter()
+            .rect(rect, radius, visuals.bg_fill, visuals.bg_stroke);
+        // Paint the circle, animating it from left to right with `how_on`:
+        let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
+        let center = egui::pos2(circle_x, rect.center().y);
+        ui.painter()
+            .circle(center, 0.75 * radius, visuals.bg_fill, visuals.fg_stroke);
+    }
+
+    // All done! Return the interaction response so the user can check what happened
+    // (hovered, clicked, ...) and maybe show a tooltip:
+    response
+}
+
+/// Here is the same code again, but a bit more compact:
+#[allow(dead_code)]
+fn toggle_ui_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
+    let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0, 1.0);
+    let (rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
+    if response.clicked() {
+        *on = !*on;
+        response.mark_changed();
+    }
+    response.widget_info(|| {
+        egui::WidgetInfo::selected(egui::WidgetType::Checkbox, ui.is_enabled(), *on, "")
+    });
+
+    if ui.is_rect_visible(rect) {
+        let how_on = ui.ctx().animate_bool_responsive(response.id, *on);
+        let visuals = ui.style().interact_selectable(&response, *on);
+        let rect = rect.expand(visuals.expansion);
+        let radius = 0.5 * rect.height();
+        ui.painter()
+            .rect(rect, radius, visuals.bg_fill, visuals.bg_stroke);
+        let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
+        let center = egui::pos2(circle_x, rect.center().y);
+        ui.painter()
+            .circle(center, 0.75 * radius, visuals.bg_fill, visuals.fg_stroke);
+    }
+
+    response
+}
+
+// A wrapper that allows the more idiomatic usage pattern: `ui.add(toggle(&mut my_bool))`
+/// iOS-style toggle switch.
+///
+/// ## Example:
+/// ``` ignore
+/// ui.add(toggle(&mut my_bool));
+/// ```
+pub fn toggle(on: &mut bool) -> impl egui::Widget + '_ {
+    move |ui: &mut egui::Ui| toggle_ui(ui, on)
+}
\ No newline at end of file
diff --git a/wxbox_common/src/lib.rs b/wxbox_common/src/lib.rs
index a839f83..d1e8ed0 100644
--- a/wxbox_common/src/lib.rs
+++ b/wxbox_common/src/lib.rs
@@ -5,5 +5,8 @@ pub struct TileRequestOptions {
     pub baselayer: String,
 
     pub data: String,
-    pub data_transparency: f64
+    pub data_transparency: f64,
+
+    pub show_range_folded: bool,
+    pub range_folded_color: u32
 }
\ No newline at end of file