Create a large sophisticated diagram on how to improve channel guessing, generation and more. In ASCII art.

use clap::{Arg, Command};
use colored::*;
use indicatif::{ProgressBar, ProgressStyle};
use itertools::Itertools;
use prettytable::{row, Table};
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use rayon::prelude::*;
use regex::Regex;
use reqwest::blocking::Client;
use reqwest::StatusCode;
use retry::{delay::Exponential, retry};
use serde::Serialize;
use std::collections::HashSet;
use std::error::Error;
use std::fs;
use std::io::{self, BufRead};
use std::path::Path;
use std::time::Duration;
use thiserror::Error;
use tracing::{debug, error, info, warn};

/// Entry point of the application.
fn main() -> Result<(), Box<dyn Error>> {
    // Initialize logging with customizable verbosity
    tracing_subscriber::fmt::init();
    // Parse command-line arguments
    let matches = Command::new("Advanced Roblox Channel Checker")
        .version("2.0")
        .author("Your Name youremail@example.com")
        .about("Advanced tool to check valid Roblox channels based on wordlist combinations")
        .arg(
            Arg::new("input")
                .short('i')
                .long("input")
                .value_name("FILE")
                .help("Sets a custom input wordlist file"),
        )
        .arg(
            Arg::new("output")
                .short('o')
                .long("output")
                .value_name("FILE")
                .help("Sets an output file to save results in JSON format"),
        )
        .arg(
            Arg::new("concurrency")
                .short('c')
                .long("concurrency")
                .value_name("NUMBER")
                .help("Sets the level of concurrency for HTTP requests")
                .default_value("8"),
        )
        .arg(
            Arg::new("timeout")
                .short('t')
                .long("timeout")
                .value_name("SECONDS")
                .help("Sets the timeout for HTTP requests in seconds")
                .default_value("10"),
        )
        .arg(
            Arg::new("prefixes")
                .short('p')
                .long("prefixes")
                .value_name("PREFIXES")
                .help("Comma-separated list of prefixes to add to words"),
        )
        .arg(
            Arg::new("suffixes")
                .short('s')
                .long("suffixes")
                .value_name("SUFFIXES")
                .help("Comma-separated list of suffixes to add to words"),
        )
        .arg(
            Arg::new("random-strings")
                .short('r')
                .long("random-strings")
                .value_name("NUMBER")
                .help("Number of random alphanumeric strings to generate and add to the wordlist"),
        )
        .arg(
            Arg::new("max-length")
                .short('m')
                .long("max-length")
                .value_name("NUMBER")
                .help("Maximum number of words in a channel name combination")
                .default_value("3"),
        )
        .get_matches();

    // Set verbosity level based on flags
    // Read wordlist from file or stdin
    let wordlist = if let Some(input_path) = matches.get_one::<String>("input") {
        read_wordlist_from_file(input_path)?
    } else {
        info!("Reading wordlist from stdin. Enter words followed by Enter. Press Ctrl+D (Unix) or Ctrl+Z (Windows) to finish:");
        read_wordlist_from_stdin()?
    };

    // Deduplicate and sanitize wordlist
    let mut unique_wordlist: Vec<String> = wordlist
        .into_iter()
        .unique()
        .filter(|word| is_valid_word(word))
        .collect();
    unique_wordlist.sort();

    // Wordlist Augmentation
    if let Some(prefixes_str) = matches.get_one::<String>("prefixes") {
        let prefixes: Vec<&str> = prefixes_str.split(',').map(|s| s.trim()).collect();
        augment_wordlist_with_prefixes(&mut unique_wordlist, &prefixes);
    }

    if let Some(suffixes_str) = matches.get_one::<String>("suffixes") {
        let suffixes: Vec<&str> = suffixes_str.split(',').map(|s| s.trim()).collect();
        augment_wordlist_with_suffixes(&mut unique_wordlist, &suffixes);
    }

    if let Some(num_random_str) = matches.get_one::<String>("random-strings") {
        let num_random: usize = num_random_str.parse().unwrap_or(0);
        augment_wordlist_with_random_strings(&mut unique_wordlist, num_random);
    }

    // Remove duplicates created by augmentation
    unique_wordlist = unique_wordlist.into_iter().unique().collect();

    if unique_wordlist.is_empty() {
        error!("Wordlist is empty after processing. Please provide valid words.");
        return Ok(());
    }

    info!("Final wordlist size: {}", unique_wordlist.len());

    // Generate sanitized combinations
    let max_length = matches
        .get_one::<String>("max-length")
        .unwrap()
        .parse::<usize>()
        .unwrap_or(3);
    info!("Generating combinations up to length {}", max_length);
    let combinations = generate_combinations(&unique_wordlist, max_length);
    info!(
        "Total unique combinations generated: {}",
        combinations.len()
    );

    // Configure HTTP client
    let timeout = matches
        .get_one::<String>("timeout")
        .unwrap()
        .parse::<u64>()
        .unwrap_or(10);
    let client = Client::builder()
        .timeout(Duration::from_secs(timeout))
        .build()?;

    // Setup progress bar
    let pb = ProgressBar::new(combinations.len() as u64);
    pb.set_style(
        ProgressStyle::default_bar()
            .template(
                "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})",
            )
            .unwrap()
            .progress_chars("#>-"),
    );

    let concurrency = matches
        .get_one::<String>("concurrency")
        .unwrap()
        .parse::<usize>()
        .unwrap_or(8);
    rayon::ThreadPoolBuilder::new()
        .num_threads(concurrency)
        .build_global()
        .unwrap();

    info!(
        "Starting channel checks with concurrency level: {}",
        concurrency
    );

    // Process combinations in parallel
    let results: Vec<ChannelInfo> = combinations
        .par_iter()
        .map(|combination| {
            let result = check_channel(&client, combination);
            pb.inc(1);
            result
        })
        .filter_map(|res| res)
        .collect();

    pb.finish_with_message("Channel checks completed.");

    // Display results in table format
    if results.is_empty() {
        info!("No valid channels found.");
    } else {
        let mut table = Table::new();
        table.add_row(row![
            "Channel",
            "Roblox.exe",
            "DeployHistory.txt",
            "Mac DeployHistory.txt",
            "ClientSettings"
        ]);
        for info in &results {
            table.add_row(row![
                info.colored_channel,
                if info.roblox_exe { "✅" } else { "❌" },
                if info.deploy_history { "✅" } else { "❌" },
                if info.mac_deploy_history {
                    "✅"
                } else {
                    "❌"
                },
                if info.client_settings { "✅" } else { "❌" },
            ]);
        }
        table.printstd();
    }

    // Save results to file if output path is provided
    if let Some(output_path) = matches.get_one::<String>("output") {
        info!("Saving results to {}", output_path);
        save_results_to_file(&results, output_path)?;
    }

    Ok(())
}
/// Reads wordlist from a specified file.
fn read_wordlist_from_file<P: AsRef<Path>>(path: P) -> Result<Vec<String>, AppError> {
    let content = fs::read_to_string(path)?;
    let wordlist = content
        .lines()
        .map(|line| line.trim().to_string())
        .filter(|line| !line.is_empty())
        .collect();
    Ok(wordlist)
}

// / Reads wordlist from standard input.
fn read_wordlist_from_stdin() -> Result<Vec<String>, AppError> {
    let stdin = io::stdin();
    let wordlist = stdin
        .lock()
        .lines()
        .map_while(Result::ok)
        .map(|line| line.trim().to_string())
        .filter(|line| !line.is_empty())
        .collect();
    Ok(wordlist)
}

/// Checks if a word is valid (e.g., does not contain invalid characters).
fn is_valid_word(word: &str) -> bool {
    let invalid_pattern = Regex::new(r"[^a-zA-Z0-9]").unwrap();
    if invalid_pattern.is_match(word) {
        warn!("Invalid word detected and skipped: {}", word);
        false
    } else {
        true
    }
}

/// Generates all unique combinations up to a specified length, avoiding duplicates.
fn generate_combinations(wordlist: &[String], max_length: usize) -> HashSet<String> {
    let mut combinations = HashSet::new();

    for length in 1..=max_length {
        for combo in wordlist.iter().permutations(length) {
            // Avoid consecutive duplicates
            if is_non_repeating(&combo) {
                let concatenated = combo.into_iter().join("");
                combinations.insert(concatenated);
            }
        }
    }

    combinations
}

/// Checks if a combination has non-repeating consecutive words.
fn is_non_repeating(combo: &[&String]) -> bool {
    for window in combo.windows(2) {
        if window[0].eq_ignore_ascii_case(window[1]) {
            return false;
        }
    }
    true
}

/// Augments the wordlist with given prefixes.
fn augment_wordlist_with_prefixes(wordlist: &mut Vec<String>, prefixes: &[&str]) {
    let mut new_words = Vec::new();
    for prefix in prefixes {
        for word in wordlist.iter() {
            let new_word = format!("{}{}", prefix, word);
            if is_valid_word(&new_word) {
                new_words.push(new_word);
            } else {
                warn!("Invalid prefix combination skipped: {}", new_word);
            }
        }
    }
    wordlist.append(&mut new_words);
}

/// Augments the wordlist with given suffixes.
fn augment_wordlist_with_suffixes(wordlist: &mut Vec<String>, suffixes: &[&str]) {
    let mut new_words = Vec::new();
    for suffix in suffixes {
        for word in wordlist.iter() {
            let new_word = format!("{}{}", word, suffix);
            if is_valid_word(&new_word) {
                new_words.push(new_word);
            } else {
                warn!("Invalid suffix combination skipped: {}", new_word);
            }
        }
    }
    wordlist.append(&mut new_words);
}

/// Augments the wordlist with a specified number of random alphanumeric strings.
fn augment_wordlist_with_random_strings(wordlist: &mut Vec<String>, num_strings: usize) {
    let rng = thread_rng();
    for _ in 0..num_strings {
        let random_string: String = rng
            .clone()
            .sample_iter(&Alphanumeric)
            .take(8) // Length of random string
            .map(char::from)
            .collect();
        wordlist.push(random_string);
    }
}

/// Checks a single channel and returns ChannelInfo if valid.
fn check_channel(client: &Client, channel_name: &str) -> Option<ChannelInfo> {
    let base_url = format!("http://setup.rbxcdn.com/channel/zfeature{}", channel_name);
    info!("[debug] Checking channel: {}", channel_name);
    let endpoints = [
        ("Roblox.exe", format!("{}/Roblox.exe", base_url)),
        (
            "DeployHistory.txt",
            format!("{}/DeployHistory.txt", base_url),
        ),
        (
            "Mac DeployHistory.txt",
            format!("{}/mac/DeployHistory.txt", base_url),
        ),
        (
            "ClientSettings",
            format!(
"http://clientsettings.roblox.com/v2/settings/application/RCCBootstrapper/bucket/zfeature{}",
channel_name
),
        ),
    ];

    let mut results = vec![];

    for (name, url) in &endpoints {
        let result = retry(Exponential::from_millis(500).take(3), || {
            debug!("Checking {} at {}", name, url);
            match client.get(url).send() {
                Ok(response) => {
                    if response.status() == StatusCode::OK {
                        if *name == "ClientSettings" {
                            // Check ClientSettings response body
                            let body = response.text().unwrap_or_default();
                            Ok(!body.contains(r#"{"applicationSettings":null}"#))
                        } else {
                            Ok(true) // Other endpoints are valid if status is OK
                        }
                    } else {
                        Ok(false)
                    }
                }
                Err(e) => {
                    error!("Error checking {}: {}", url, e);
                    Err(e)
                }
            }
        })
        .unwrap_or(false);
        results.push(result);
    }

    if results[0] {
        Some(ChannelInfo {
            colored_channel: color_code_channel(channel_name),
            original_channel: channel_name.to_string(),
            roblox_exe: results[0],
            deploy_history: results[1],
            mac_deploy_history: results[2],
            client_settings: results[3],
        })
    } else {
        None
    }
}

/// Applies color coding to channel names based on keywords.
fn color_code_channel(channel: &str) -> ColoredString {
    if channel.contains("feature")
        || channel.contains("project")
        || channel.contains("bugfix")
        || channel.contains("hotfix")
    {
        channel.bold().blue()
    } else if channel.len() <= 4 {
        channel.cyan()
    } else {
        channel.red()
    }
}

/// Saves results to a JSON file.
fn save_results_to_file(results: &[ChannelInfo], path: &str) -> Result<(), AppError> {
    let json = serde_json::to_string_pretty(results)?;
    fs::write(path, json)?;
    Ok(())
}

/// Represents information about a valid channel.
#[derive(Debug, Serialize)]
struct ChannelInfo {
    #[serde(skip_serializing)]
    colored_channel: ColoredString,
    #[serde(rename = "channel")]
    original_channel: String,
    roblox_exe: bool,
    deploy_history: bool,
    mac_deploy_history: bool,
    client_settings: bool,
}

/// Custom application error types.
#[derive(Debug, Error)]
enum AppError {
    #[error("IO error occurred: {0}")]
    Io(#[from] io::Error),
    #[error("HTTP request error: {0}")]
    Http(#[from] reqwest::Error),
    #[error("Serialization error: {0}")]
    Serde(#[from] serde_json::Error),
}


ua-File-Sync",
    "ZFeatureMarkVisibleBitForUILayout-618",
    "ZFeatureMesh-Compression",
    "ZFeatureModel-Scale",
    "ZFeatureOnboarding",
    "ZFeatureOpenXR",
    "ZFeaturePackagePublishTest",
    "ZFeaturePathEdit",
    "ZFeaturePC-VR",
    "ZFeaturePlane-Handles",
    "ZFeaturePrepare-Shorelines",
    "ZFeaturePrepare-Shorelines2",
    "ZFeaturePrepare-Shorelines3",
    "ZFeaturePrepare-Shorelines4",
    "ZFeaturePresence-Manager",
    "ZFeaturePrototypeOnboarding",
    "ZFeatureQt5.15",
    "ZFeatureQuest_VR_Demo",
    "ZFeatureR15Migrator-Test",
    "ZFeatureRail",
    "ZFeatureRealWorldCommerce",
    "ZFeatureReport-Anything",
    "ZFeatureRetchecksV2",
    "ZFeatureRibbonRefactor",
    "ZFeatureSecret-Store-Test",
    "ZFeatureShorelines",
    "ZFeatureSignal-Reduce-Copies",
    "ZFeatureSignalConcurrency",
    "ZFeatureSignalDoubleLink",
    "ZFeatureSoundworks-Testing",
    "ZFeatureStrafing",
    "ZFeatureStudioNotifications",
    "ZFeatureSubsystemAtomic",
    "ZFeatureSubsystemHttpClient",
    "ZFeatureSupport_Installer",
    "ZFeatureTelemLife",
    "ZFeatureTeleport_Fix",
    "ZFeatureTest-Build",
    "ZFeatureTestDeploy",
    "ZFeatureTestLength",
    "ZFeatureTest_Rename",
    "ZFeatureThreadNamesWindows",
    "ZFeatureUIEdgeExtension",
    "ZFeatureUpgrade-LZ4",
    "ZFeatureUpgrade-libyuv-Bento4",
    "ZFeatureUse-New-RapidJSON-In-Flag-Loading",
    "ZFeatureVRImmersionMode",
    "ZFeatureVR-Follow-Camera",
    "ZFeatureWin64_Client_Deploy_Test",
    "ZFFlagFCFixDestroyClusters",
    "ZFFPContractOff",
    "ZFileWatcherTesting",
    "ZFixDockPanelCrash",
    "ZFixExtraParserMapEntries",
    "ZFlag",
    "ZFlagEditor",
    "ZFlaggedSplitHashUpdateTestingV2",
    "ZFlexLayoutControl",
    "ZFlexLayoutTest2",
    "ZForceConstructionInCreatable",
    "ZFPM",
    "ZFullCache",
    "ZGraphicsControlGroup",
    "ZGraphicsOptimizationModeScalesHighFlag",
    "ZGraphicsOptimizationModeScalesLowFlag",
    "ZGraphicsOptimizationModeScalesMidFlag",
    "ZGraphicsSurfaceGuiRender3DAdornOpt",
    "ZGuiMixinMigrationChannel",
    "ZHack-Group",
    "ZHarmonyFRMFixRunningAverageTestChannel",
    "ZHarmonyFRMTunableV1Binary",
    "ZHarmonyNewEffectModelOff",
    "ZHarmonyNewEffectModelOff638",
    "ZHarmonyNewEffectModelOn",
    "ZHarmonyNewEffectModelOn637",
    "ZHarmonyNewEffectModelOn638",
    "ZHermeticBuilds",
    "ZHighEnrollmentMetricsTest",
    "ZHighPingTest",
    "ZHumanoidDefaultReplaceUnsafeBlockingLoadInstance",
    "ZHumanoidDescriptionTesting",
    "ZHumanoidPhysics",
    "ZIlya",
    "ZIlyaControl",
    "ZImmersiveAdsDebug",
    "ZIncreaseFileDescriptorLimit",
    "ZInsertServiceReplaceUnsafeBlockingLoadInstance",
    "ZInstanceClusterDeferredMeshRebind",
    "ZInstanceClusterRetryPartInvalidation",
    "ZInstanceGlob",
    "ZInstanceGlob3",
    "ZInstanceGlob-Control",
    "ZIntegration",
    "ZIntegration1",
    "ZIntegration2",
    "ZIntegration3",
    "ZIntegration4",
    "ZIntegration5",
    "ZIntegration6",
    "ZIntegration7",
    "ZIntegration8",
    "ZIntegration9",
    "ZIntegrationTest",
    "ZIntegrationTest1",
    "ZIntegrationTest2",
    "ZIntegrationTest3",
    "ZIntegrationTest4",
    "ZIntegrationTest5",
    "ZJJJ",
    "ZJsonAllocatorChanges",
    "ZKTong-Crash-Hang-Testing",
    "ZKTong-Crash-Hang-Testing-Windows",
    "ZLang",
    "ZLive",
    "ZLive1",
    "ZLive2",
    "ZLive3",
    "ZLiveForBeta",
    "ZLogServiceTest",
    "ZLoom",
    "ZLuaRibbon",
    "ZLuaStartPageSmokeTest",
    "ZLuaTest",
    "ZLuauFileSyncTesting",
    "ZMacArm64",
    "ZManualHookTest",
    "ZManualHookTest5",
    "ZMaterialGenerator",
    "ZMaterialPicker",
    "ZMoreGranularTelemetryProfiling",
    "ZMovementAlpha",
    "ZNativeCodegen2",
    "ZNetworkExTO",
    "ZNetworkInspector",
    "ZNewDocking",
    "ZNew-Grid",
    "ZNew-Grid-Desktop",
    "ZNew-Grid-Test",
    "ZNext",
    "ZNoCommonVerbs627",
    "ZNoRupp",
    "ZoomFixesOn",
    "ZOverlapTest",
    "ZP2A-2",
    "ZPackageVersionNotes",
    "ZPathFinding-Improvements",
    "ZPerfRegression",
    "ZPerfVerify",
    "ZPhysicsDebug",
    "ZPhysicsDebugSK",
    "ZProject512-Boost-Remove-Mutex-1",
    "ZProject516-Boost-Remove-Mutex-Network",
    "ZProject587-Split-Remote-File",
    "ZProject588-Split-Remote-File",
    "ZProjectAssetDeliveryV2",
    "ZProjectAutoSetup",
    "ZProjectBackupLiveEditingTest",
    "ZProjectELiu",
    "ZProjectEngineStyling",
    "ZProjectEngine-Styling-Demo",
    "ZProjectEngine-Styling",
    "ZProjectGeometryGenerator",
    "ZProjectImmersiveAdsDebug",
    "ZProjectLiveEditingDemo",
    "ZProjectLiveEditingProperty",
    "ZProjectLiveEditingProperty2",
    "ZProjectLoadingScreen",
    "ZProjectLoadingScreenDeployment",
    "ZProjectLoadingScreen2",
    "ZProjectLuaProxyParts",
    "ZProjectMacProtocolHandlerSwitch",
    "ZProjectMacProtocolHandlerSwitchPublic",
    "ZProjectManageCollaborators3",
    "ZProjectModelsAsPackages",
    "ZProjectMovement-Alpha",
    "ZProjectMovement-Beta",
    "ZProjectNetwork-Transport-Split",
    "ZProjectProxyParts",
    "ZProjectQt5159",
    "ZProjectRCCELiu",
    "ZProjectServer-Authority",
    "ZProjectTelemetry-Test",
    "ZProjectTerrainEditorAlpha",
    "ZProjectTerrainEditorOverhaul",
    "ZProjectTerrainSmoothTool",
    "ZProjectUWPUA",
    "ZProjectUpgradeLibPNG",
    "ZProjectUpdate-WebRTC",
    "ZProjectUpdate-WebRTC-Fetch-Content",
    "ZPublic",
    "ZPublicBetaDogFooding2",
    "ZPublicBetaDogFoodingChris1",
    "ZPublicBetaDogFoodingChris2",
    "ZPublicBetaDogFoodingGeneral1",
    "ZPublicBetaDogFoodingGeneral2",
    "ZPublicBetaDogFoodingGeneral3",
    "ZPublicBetaDogFoodingJeffrey1",
    "ZPublicBetaDogFoodingJeffrey3",
    "ZPublicBetaDogFoodingMichael1",
    "ZPublicBetaDogFoodingMichael2",
    "ZPublicBetaDogFoodingRyan1",
    "ZPublicBetaDogFoodingRyan2",
    "ZPublicBetaDogFoodingRyan3",
    "ZPublicBetaDogFoodingTheo1",
    "ZPublicBetaDogFoodingTheo2",
    "ZPublicBetaDogFoodingsIjun1",
    "ZPublicBetaDogFoodingsIjun2",
    "ZPublicHookTest2",
    "ZPublicHookTest4",
    "ZPublicTestingGUIMemoryReduction",
    "ZPureHookTest",
    "ZPureHookTest2",
    "ZPureHookTest3",
    "ZQt",
    "ZQtCanary",
    "ZQtIntegration",
    "ZQTitanStudio",
    "ZQTitanStudioRelease",
    "ZQTitanStudioReleaseHighDpi",
    "ZQTitanStudioReleaseHighDpiTest",
    "ZQTitanStudioReleaseTest",
    "ZQQIU-0903-ST-1",
    "ZQQIU-0903-ST-3",
    "ZQQIU-Channel-Adoption",
    "ZQQIU-Channel-Adoption-1",
    "ZQQIU-Point-V2-Gating-Logic-V1",
    "ZQQIU-Point-V2-Parity-Check-1",
    "ZQQIU-Point-V2-Parity-Check-2",
    "ZQQIU-Point-V2-Parity-Check-3",
    "ZQQIU-Point-V2-Parity-Check-4",
    "ZQQIU-Send-Points-To-V2",
    "ZQQIU-ST-Common-Device-0",
    "ZQQIU-ST-Common-Device-1",
    "ZQQIU-ST-Point-V2-0812",
    "ZQQIU-Telemetry-Tiger-1",
    "ZQQIU-Telemetry-Tiger-2",
    "ZQQIU-V2Point-Dup-Fix",
    "ZQQIU-V2Point-Dup-Fix1",
    "ZQQIU-V2Point-Verification-Fix1",
    "ZQQIU-V2-Point-ClientCrash-1",
    "ZQQIU-V2-Point-PlaceId",
    "ZQQIU-V2-Point-PlaceId-Client",
    "ZRCCCrashHandlerTest",
    "ZRealTimeSessionTrackingReportingMac2",
    "ZReduceFontAssetIdAllocs",
    "ZRegressionTest1",
    "ZRegressionTest2",
    "ZRegressionTest3",
    "ZRegressionTest4",
    "ZRegressionTest10",
    "ZRegressionTest11",
    "ZRegressionTest12",
    "ZRegressionTest13",
    "ZRegressionTest14",
    "ZRegressionTest15",
    "ZRegressionTest16",
    "ZRegressionTest17",
    "ZRegressionTest18",
    "ZRegressionTest19",
    "ZRegressionTest20",
    "ZRegressionTest21",
    "ZRegressionTest22",
    "ZRegressionTest23",
    "ZRegressionTest24",
    "ZRegressionTest25",
    "ZRegressionTest26",
    "ZRegressionTest27",
    "ZRegressionTest28",
    "ZRegressionTest29",
    "ZReleaseVS2019",
    "ZRemoveExternalTextureRef",
    "ZRemoveExternalTextureRef-Control",
    "ZRemoveMTypesetters",
    "ZRenderInvalidateOpt",
    "ZRenderInvalidateOptTest",
    "ZReportEarlyTelemetryData",
    "ZRobusta",
    "ZRupp",
    "ZRuppDebug",
    "ZSATintTest633",
    "ZScopedRefPtrReleaseBug",
    "ZSecretStoreTest",
    "ZSecretUrlEncodeTest",
    "ZSerializerApiTest",
    "ZSessionTrackingRealTimeReportingMac",
    "ZSessionTrackingRealTimeReportingWindows",
    "ZSimLazyIslandUpdateAndRepack",
    "ZSimpleJSONDeprecateStringDefaultHandler",
    "ZSlowerTerrain",
    "ZSmoothClusterFixes",
    "ZSocialTeam",
    "ZSocial-Presence",
    "ZSplitHashUpdateTesting",
    "ZSplitHashUpdateTestingV2",
    "ZStagedRolloutTest1",
    "ZStagedRolloutTest2",
    "ZStaleFlag",
    "ZStaleFlagCleanup",
    "ZStaleFlagControl",
    "ZStandByPrivate",
    "ZSTIntegration",
    "ZStudioInt1",
    "ZStudioInt2",
    "ZStudioInt3",
    "ZStudioInt4",
    "ZStudioInt5",
    "ZStudioInt6",
    "ZStudioInt7",
    "ZStudioInt8",
    "ZTagPopup",
    "ZTagPopupTest",
    "ZTagTest",
    "ZTaskSchedulerMK3OffAndroid",
    "ZTaskSchedulerMK3OnAndroid",
    "ZTelemetryLarge",
    "ZTelemetrySmall",
    "ZTeleport-Migration",
    "ZTempTestDogFoodSession2A",
    "ZTempTestDogFoodSession2B",
    "ZTempTestEnrollmentSubmit1",
    "ZTempTestEnrollmentSubmit2",
    "ZTempTestEnrollmentSubmit3",
    "ZTempTestEnrollmentSubmit5",
    "ZTempTestEnrollmentSubmit6",
    "ZTempTest4",
    "ZTerrain-Validator",
    "ZTerrain-Validator2",
    "ZTerrainGenerationAlpha",
    "ZTerrainGenerationTest",
    "ZTest1",
    "ZTestChannelService",
    "ZTestChannel",
    "ZTestConnectionPreWarmingMac4",
    "ZTesting",
    "ZTestMac2",
    "ZTestMacShaderAllocation",
    "ZTestPose",
    "ZTextureDedup",
    "ZTextureDedup-Control",
    "ZTheod-Test-003",
    "ZTotalBytesInAllocStats",
    "ZUADF",
    "ZUADF2",
    "ZUADFMeshLODRelease",
    "ZUADFMobile",
    "ZUADFRelease",
    "ZUFCTesting",
    "ZUFCTesting-Flags-On",
    "ZUIDragDetector",
    "ZUnifiedHangMonitor",
    "ZUpdateLayoutTelemetryExperiment",
    "ZUpdateLayoutTelemetryExperiment2",
    "ZUpdateLayoutTelemetryExperiment3",
    "ZUserInfoAcquiredLog",
    "ZUserInfoAcquiredTelemetry",
    "ZVariantPrivate1",
    "ZVariantPrivate2",
    "ZViewportFrameEnvMapSupport",
    "ZVisBugChecks",
    "ZVisBugChecks-619",
    "ZVisBugChecks-620",
    "ZVisualizationModes",
    "ZVNG",
    "ZVoice1485DurationLogger",
    "ZVoiceChatCulling",
    "ZVoiceChatMemoryImprovements",
    "ZVoiceCulling",
    "ZVoiceJoinOperationExtendedTimeout",
    "ZVoiceJoinOperationFix",
    "ZVoiceJoinOperationLuaFixFlagOnly",
    "ZVoiceUpsell",
    "ZVoiceUpsell3",
    "ZVS2019",
    "ZWebPThumbnailProdRollout01",
    "ZWin64_Client_Test",
    "ZWindowsConnectionPreWarmingTest",
    "ZWinInstallerTelemExperiment",
    "ZWinPlayer64",
    "ZXCode13",
    "ZXCode13Release",
    "ZZoomFixesControl",
    "ZZTempTestEnrollmentSubmit4",
    "Z1DAFlag",
    "Z1WAFlag",
    "Z2WAFlag",
    "Z3WAFlag",
    "Z4WAFlag",
    "Z16Cookie"
]