' .
				'
' .
				'
';
		
		/*
			Draw link
		*/
		$parts = explode("/", $link);
		$clickurl = "";
		
		// remove trailing /
		$c = count($parts) - 1;
		if($parts[$c] == ""){
			
			$parts[$c - 1] = $parts[$c - 1] . "/";
			unset($parts[$c]);
		}
		
		// merge https://site together
		$parts = [
			$parts[0] . $parts[1] . '//' . $parts[2],
			...array_slice($parts, 3, count($parts) - 1)
		];
		
		$c = count($parts);
		for($i=0; $i<$c; $i++){
			
			if($i !== 0){ $clickurl .= "/"; }
			
			$clickurl .= $parts[$i];
			
			if($i === $c - 1){
				
				$parts[$i] = rtrim($parts[$i], "/");
			}
			
			$payload .=
				'
' .
					htmlspecialchars(urldecode($parts[$i])) .
				'';
			
			if($i !== $c - 1){
				
				$payload .= '
';
			}
		}
		
		return $payload . '
 ';
	}
	
	public function getscraperfilters($page){
		
		$get_scraper = isset($_COOKIE["scraper_$page"]) ? $_COOKIE["scraper_$page"] : null;
		
		if(
			isset($_GET["scraper"]) &&
			is_string($_GET["scraper"])
		){
			
			$get_scraper = $_GET["scraper"];
		}else{
			
			if(
				isset($_GET["npt"]) &&
				is_string($_GET["npt"])
			){
				
				$get_scraper = explode(".", $_GET["npt"], 2)[0];
				
				$get_scraper =
					preg_replace(
						'/[0-9]+$/',
						"",
						$get_scraper
					);
			}
		}
		
		// add search field
		$filters =
			[
				"s" => [
					"option" => "_SEARCH"
				]
			];
		
		// define default scrapers
		switch($page){
			
			case "web":
				$filters["scraper"] = [
					"display" => "Scraper",
					"option" => [
						"ddg" => "DuckDuckGo",
						"brave" => "Brave",
						"yandex" => "Yandex",
						"google" => "Google",
						//"google_api" => "Google API",
						"google_cse" => "Google CSE",
						"startpage" => "Startpage",
						"qwant" => "Qwant",
						"ghostery" => "Ghostery",
						"yep" => "Yep",
						"greppr" => "Greppr",
						"crowdview" => "Crowdview",
						"mwmbl" => "Mwmbl",
						"mojeek" => "Mojeek",
						"baidu" => "Baidu",
						"solofield" => "Solofield",
						"marginalia" => "Marginalia",
						"wiby" => "wiby",
						"curlie" => "Curlie"
					]
				];
				break;
			
			case "images":
				$filters["scraper"] = [
					"display" => "Scraper",
					"option" => [
						"ddg" => "DuckDuckGo",
						"yandex" => "Yandex",
						"brave" => "Brave",
						"google" => "Google",
						"google_cse" => "Google CSE",
						"startpage" => "Startpage",
						"qwant" => "Qwant",
						"yep" => "Yep",
						"baidu" => "Baidu",
						"solofield" => "Solofield",
						"pinterest" => "Pinterest",
						"flickr" => "Flickr",
						"fivehpx" => "500px",
						"vsco" => "VSCO",
						"imgur" => "Imgur",
						"ftm" => "FindThatMeme",
						//"sankakucomplex" => "SankakuComplex"
					]
				];
				break;
			
			case "videos":
				$filters["scraper"] = [
					"display" => "Scraper",
					"option" => [
						"yt" => "YouTube",
						//"fb" => "Facebook videos",
						"ddg" => "DuckDuckGo",
						"brave" => "Brave",
						"yandex" => "Yandex",
						"google" => "Google",
						"startpage" => "Startpage",
						"qwant" => "Qwant",
						"baidu" => "Baidu",
						"solofield" => "Solofield"
					]
				];
				break;
			
			case "news":
				$filters["scraper"] = [
					"display" => "Scraper",
					"option" => [
						"ddg" => "DuckDuckGo",
						"brave" => "Brave",
						"google" => "Google",
						"startpage" => "Startpage",
						"qwant" => "Qwant",
						"yep" => "Yep",
						"mojeek" => "Mojeek",
						"baidu" => "Baidu"
					]
				];
				break;
			
			case "music":
				$filters["scraper"] = [
					"display" => "Scraper",
					"option" => [
						"sc" => "SoundCloud"
						//"spotify" => "Spotify"
					]
				];
				break;
		}
		
		// get scraper name from user input, or default out to preferred scraper
		$scraper_out = null;
		$first = true;
		
		foreach($filters["scraper"]["option"] as $scraper_name => $scraper_pretty){
			
			if($first === true){
				
				$first = $scraper_name;
			}
			
			if($scraper_name == $get_scraper){
				
				$scraper_out = $scraper_name;
			}
		}
		
		if($scraper_out === null){
			
			$scraper_out = $first;
		}
		
		include "scraper/$scraper_out.php";
		$lib = new $scraper_out();
		
		// set scraper on $_GET
		$_GET["scraper"] = $scraper_out;
		
		// set nsfw on $_GET
		if(
			isset($_COOKIE["nsfw"]) &&
			!isset($_GET["nsfw"])
		){
			
			$_GET["nsfw"] = $_COOKIE["nsfw"];
		}
		
		return
			[
				$lib,
				array_merge_recursive(
					$filters,
					$lib->getfilters($page)
				)
			];
	}
	
	public function parsegetfilters($parameters, $whitelist){
		
		$sanitized = [];
		
		// add npt token
		if(
			isset($parameters["npt"]) &&
			is_string($parameters["npt"])
		){
			
			$sanitized["npt"] = $parameters["npt"];
		}else{
			
			$sanitized["npt"] = false;
		}
		
		// we're iterating over $whitelist, so
		// you can't polluate $sanitized with useless
		// parameters
		foreach($whitelist as $parameter => $value){
			
			if(isset($parameters[$parameter])){
				
				if(!is_string($parameters[$parameter])){
					
					$sanitized[$parameter] = null;
					continue;
				}
				
				// parameter is already set, use that value
				$sanitized[$parameter] = $parameters[$parameter];
			}else{
				
				// parameter is not set, add it
				if(is_string($value["option"])){
					
					// special field: set default value manually
					switch($value["option"]){
						
						case "_DATE":
							// no date set
							$sanitized[$parameter] = false;
							break;
						
						case "_SEARCH":
							// no search set
							$sanitized[$parameter] = "";
							break;
					}
					
				}else{
					
					// set a default value
					$sanitized[$parameter] = array_keys($value["option"])[0];
				}
			}
			
			// sanitize input
			if(is_array($value["option"])){
				if(
					!in_array(
						$sanitized[$parameter],
						$keys = array_keys($value["option"])
					)
				){
					
					$sanitized[$parameter] = $keys[0];
				}
			}else{
				
				// sanitize search & string
				switch($value["option"]){
					
					case "_DATE":
						if($sanitized[$parameter] !== false){
							
							$sanitized[$parameter] = strtotime($sanitized[$parameter]);
							if($sanitized[$parameter] <= 0){
								
								$sanitized[$parameter] = false;
							}
						}
						break;
					
					case "_SEARCH":
						// get search string
						$sanitized["s"] = trim($sanitized[$parameter]);
				}
			}
		}
		
		// invert dates if needed
		if(
			isset($sanitized["older"]) &&
			isset($sanitized["newer"]) &&
			$sanitized["newer"] !== false &&
			$sanitized["older"] !== false &&
			$sanitized["newer"] > $sanitized["older"]
		){
			
			// invert
			[
				$sanitized["older"],
				$sanitized["newer"]
			] = [
				$sanitized["newer"],
				$sanitized["older"]
			];
		}
		
		return $sanitized;
	}
	public function s_to_timestamp($seconds){
		
		if(is_string($seconds)){
			
			return "LIVE";
		}
		
		return ($seconds >= 60) ? ltrim(gmdate("H:i:s", $seconds), ":0") : gmdate("0:s", $seconds);
	}
	
	public function generatehtmltabs($page, $query){
		
		$html = null;
		
		foreach(["web", "images", "videos", "news", "music"] as $type){
			
			$html .= '' .
					'
' . htmlspecialchars($filter_values["display"]) . '
';
			
			if(is_array($filter_values["option"])){
				
				$tmp .= '
';
			}else{
				
				switch($filter_values["option"]){
					
					case "_DATE":
						$tmp .= '
 $value){
			
			if(
				$value == null ||
				$value == false ||
				$key == "npt" ||
				$key == "extendedsearch" ||
				$value == "any" ||
				$value == "all" ||
				$key == "spellcheck" ||
				(
					$ommit === true &&
					$key == "s"
				)
			){
				
				continue;
			}
			
			if(
				$key == "older" ||
				$key == "newer"
			){
				
				$value = date("Y-m-d", (int)$value);
			}
			
			$out[$key] = $value;
		}
		
		return http_build_query($out);
	}
	
	public function htmlimage($image, $format){
		
		if(
			preg_match(
				'/^data:/',
				$image
			)
		){
			
			return htmlspecialchars($image);
		}
		
		return "/proxy?i=" . urlencode($image) . "&s=" . $format;
	}
	
	public function htmlnextpage($gets, $npt, $page){
		
		$query = $this->buildquery($gets);
		
		return $page . "?" . $query . "&npt=" . $npt;
	}
}