I have a pdf file on my server. I want to create such link that, user can click on it and download that pdf file. I am using Zend frame work with Php.
place this code inside a php file and call it f.e. "download.php":
<?php
$fullPath = "path/to/your/file.ext";
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
?>
Example: place this kind of link into the document where the file download is offered:
Download here
More Detail:
http://www.finalwebsites.com/forums/topic/php-file-download
I assume there is a reason you can't just link to the pdf directly, such as the need to authenticate the user. In that case, you will need to set the correct headers, and, as others have noted, you can use get_file_contents to serve the pdf. However, using get_file_contents requires that you read the file into memory before you send the response. If the file is large, or if you receive many requests at once, you can easily run out of memory. A great solution if you're using Apache or Lighttpd is to use XSendFile. With XSendFile you set the X-Sendfile response header to the file's path, and your web server serves the file directly from disk - without revealing the file's location on disk.
The problem with this solution is that the module must be installed on Apache, and it must be configured to work with Lighttpd.
Once XSendFile is installed, your Zend Framework action code would look something like the following:
// user auth or other code here -- there has to be a reason you're not
// just pointing to the pdf file directly
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->getResponse()->setHeader('Content-type', 'application/pdf')
->setHeader('X-Sendfile', 'path-to-file')
->sendResponse();
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=filename.pdf");
$pdfiledata = file_get_contents($filename);
echo $pdfiledata;
I have been using this reusable action helper for sending files to users. It works well and is better than messing around with headers yourself.
I don't know if Zend provides a class for this. In general this is achieved by using the header function. have a look at the PHP site:
http://php.net/manual/en/function.header.php
There are some examples of downloading files.
Good luck!
I've always used the become_file_download function from the open source BalPHP library which you can plug and play (stick) into your project right away. It allows for:
Instant download of the file
Easily specify params like content-type, cache life, buffer size.
Supports multi-part transactions allowing for faster downloads which won't kill your server for big file transfers.
Supports pause/resume functionality.
And etags for caching:
You can find the latest version here:
http://github.com/balupton/balphp/blob/master/trunk/lib/core/functions/_files.funcs.php#L75
And here it is copy and pasted as of 27 August, 2010:
/**
* Become a file download, should be the last script that runs in your program
*
* http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
*
* #version 3, July 18, 2009 (Added suport for data)
* #since 2, August 11, 2007
*
* #author Benjamin "balupton" Lupton <contact#balupton.com> - {#link http://www.balupton.com/}
*
* #param string $file_path
* #param string $content_type
* #param int $buffer_size
* #param string $file_name
* #param timestamp $file_time
*
* #return boolean true on success, false on error
*/
function become_file_download ( $file_path_or_data, $content_type = NULL, $buffer_size = null, $file_name = null, $file_time = null, $expires = null ) {
// Prepare
if ( empty($buffer_size) )
$buffer_size = 4096;
if ( empty($content_type) )
$content_type = 'application/force-download';
// Check if we are data
$file_descriptor = null;
if ( file_exists($file_path_or_data) && $file_descriptor = fopen($file_path_or_data, 'rb') ) {
// We could be a file
// Set some variables
$file_data = null;
$file_path = $file_path_or_data;
$file_name = $file_name ? $file_name : basename($file_path);
$file_size = filesize($file_path);
$file_time = filemtime($file_path);
$etag = md5($file_time . $file_name);
} elseif ( $file_name !== null ) {
// We are just data
$file_data = $file_path_or_data;
$file_path = null;
$file_size = strlen($file_data);
$etag = md5($file_data);
if ( $file_time === null )
$file_time = time();
else
$file_time = ensure_timestamp($file_time);
} else {
// We couldn't find the file
header('HTTP/1.1 404 Not Found');
return false;
}
// Prepare timestamps
$expires = ensure_timestamp($expires);
// Set some variables
$date = gmdate('D, d M Y H:i:s') . ' GMT';
$expires = gmdate('D, d M Y H:i:s', $expires) . ' GMT';
$last_modified = gmdate('D, d M Y H:i:s', $file_time) . ' GMT';
// Say we can go on forever
set_time_limit(0);
// Check relevance
$etag_relevant = !empty($_SERVER['HTTP_IF_NONE_MATCH']) && trim(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']), '\'"') === $etag;
$date_relevant = !empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $file_time;
// Handle download
if ( $etag_relevant || $date_relevant ) {
// Not modified
header('HTTP/1.0 304 Not Modified');
header('Status: 304 Not Modified');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
return true;
} elseif ( !empty($_SERVER['HTTP_RANGE']) ) {
// Partial download
/*
* bytes=0-99,500-1499,4000-
*/
// Explode RANGE
list($size_unit,$ranges) = explode($_SERVER['HTTP_RANGE'], '=', 2);
// Explode RANGES
$ranges = explode(',', $ranges);
// Cycle through ranges
foreach ( $ranges as $range ) {
// We have a range
/*
* All bytes until the end of document, except for the first 500 bytes:
* Content-Range: bytes 500-1233/1234
*/
// Set range start
$range_start = null;
if ( !empty($range[0]) && is_numeric($range[0]) ) {
// The range has a start
$range_start = intval($range[0]);
} else {
$range_start = 0;
}
// Set range end
if ( !empty($range[1]) && is_numeric($range[1]) ) {
// The range has an end
$range_end = intval($range[1]);
} else {
$range_end = $file_size - 1;
}
// Set the range size
$range_size = $range_end - $range_start + 1;
// Set the headers
header('HTTP/1.1 206 Partial Content');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Content-Range: bytes ' . $range_start . '-' . $range_end . '/' . $file_size);
header('Content-Length: ' . $range_size);
header('Content-Type: ' . $content_type);
if ( $content_type === 'application/force-download' )
header('Content-Disposition: attachment; filename=' . urlencode($file_name));
// Handle our data transfer
if ( !$file_path ) {
// We are using file_data
echo substr($file_data, $range_start, $range_end - $range_start);
} else {
// Seek to our location
fseek($file_descriptor, $range_start);
// Read the file
$remaining = $range_size;
while ( $remaining > 0 ) {
// 0-6 | buffer = 3 | remaining = 7
// 0,1,2 | buffer = 3 | remaining = 4
// 3,4,5 | buffer = 3 | remaining = 1
// 6 | buffer = 1 | remaining = 0
// Set buffer size
$buffer_size = min($buffer_size, $remaining);
// Output file contents
echo fread($file_descriptor, $buffer_size);
flush();
ob_flush();
// Update remaining
$remaining -= $buffer_size;
}
}
}
} else {
// Usual download
// header('Pragma: public');
// header('Cache-control: must-revalidate, post-check=0, pre-check=0');
// header('Expires: '. gmdate('D, d M Y H:i:s').' GMT');
// Set headers
header('HTTP/1.1 200 OK');
header('Pragma: public');
header('Cache-Control: private');
header('ETag: "' . $etag . '"');
header('Date: ' . $date);
header('Expires: ' . $expires);
header('Last-modified: ' . $last_modified);
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Content-Length: ' . $file_size);
header('Content-Type: ' . $content_type);
if ( $content_type === 'application/force-download' )
header('Content-Disposition: attachment; filename=' . urlencode($file_name));
// Handle our data transfer
if ( !$file_path ) {
// We are using file_data
echo $file_data;
} else {
// Seek to our location
// Read the file
$file_descriptor = fopen($file_path, 'r');
while ( !feof($file_descriptor) ) {
// Output file contents
echo fread($file_descriptor, $buffer_size);
flush();
ob_flush();
}
}
}
// Close the file
if ( $file_descriptor )
fclose($file_descriptor);
// Done
return true;
}
It also depends on another plug and play function called ensure_timestamp which you can find here:
http://github.com/balupton/balphp/blob/master/trunk/lib/core/functions/_datetime.funcs.php#L31
/**
* Gets the days between two timestamps
* #version 1, January 28, 2010
* #param mixed $value
* #return timestamp
*/
function ensure_timestamp ( $value = null ) {
$result = null;
if ( $value === null ) $result = time();
elseif ( is_numeric($value) ) $result = $value;
elseif ( is_string($value) ) $result = strtotime($value);
else throw new Exception('Unknown timestamp type.');
return $result;
}
Related
I am currently having a problem with my PHP code as it corrupts the data/xlsx file when exporting it from HTML.
i am viewing PHP Mailer scripts which has multiple pages connected to it.
This is my PHP XLS Function.
this->_request->download ? true : false;
$htmlPath = realpath(dirname(__FILE__) . "/../../public/reports/html/") . "/" . $fileName;
$fileSource = file_get_contents($htmlPath);
preg_match('!<title>([^<]+)!', $fileSource, $title);
$title = trim($title[1]);
if (stristr($fileSource, '<graph>')) {
$fileSource = preg_replace('!<graph>[^<]+</graph>!is', '', $fileSource);
file_put_contents($htmlPath, $fileSource);
}
file_put_contents($htmlPath,preg_replace('!<title>[^<]+</title>!is','',$fileSource));
$reader = new PHPExcel_Reader_HTML;
$content = $reader->load($htmlPath);
// Pass to writer and output as needed
$objWriter = PHPExcel_IOFactory::createWriter($content, 'Excel2007');
$download = 1;
// Redirect output to a client’s web browser (Excel5)
//header('Content-Type: application/vnd.ms-excel');
$fileName = str_replace(' ', '-', ($title . "-" . date('Y-m-d')));
if ($download) {
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
// header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
header('Content-Disposition: attachment;
filename=' . $fileName . ".xlsx")
this is my caller function
if ($reportRow->reportString) {
$reportRow->reportString = stripslashes($reportRow->reportString);
if (!stristr($reportRow->reportString, '</body>'))
$reportRow->reportString = $reportRow->reportString . "</table></body></html>";
$fileName = time() . rand(111, 222);
$htmlPath = realpath(dirname(__FILE__) . "/../../public/reports/html/") . "/" . $fileName;
if ($headerPath) {
$reportRow->html_string = preg_replace('!(\s*</htmlpageheader>)!', '$1<img width="100%" style="clear:both" id="headerPath" src="' . $headerPath . '" />', $reportRow->html_string);
}
$corp_name = preg_replace('!\s+!',' ',$userSessionData->corp_name);
$reportRow->reportString = preg_replace_callback(
'!<title>([^<]+)!is',
function($matches) use ($corp_name){
return '<title>' . $corp_name . '_' . preg_replace('!\s+!',' ',$matches[1]);
},
$reportRow->reportString
);
file_put_contents($htmlPath, $reportRow->reportString);
$kilobites = filesize($htmlPath);
$kilobites = $kilobites / 1024;
$kilobites = 0;
if ($ifXLS) {
echo json_encode(array(
'reportPath' => '/helper/file-To-xls/fileName/' . $fileName,
'error' => false
));
would anyone have any ideas on how to fix this issue?
you can use CSV functions or PHPExcel to do it straight forward
or you can try like below
<?php
$file="1.xls";
$html="<table><tr><td>Col1</td><td>Col2</td></tr></table>";
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=$file");
echo $html;
?>
The header for .xlsx files is Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet if you prefer to export it as .xlsx
Provides file downloads with PHP.
It works fine on the web, but it does not work properly in the app.
What is the reason why the header of the file is normally displayed but the file is not downloaded?
android webview download
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setMimeType(mimetype);
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Downloading file");
request.setTitle(URLUtil.guessFileName(url,contentDisposition,mimetype));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url,contentDisposition,mimetype));
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
headers
header('Content-Type: ' . $this->mimetype);
header('Content-Disposition: attachment; filename="' . $this->dl_filename . '"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']) && !$this->force_single){
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range = intval($range);
if(!$range_end){
$range_end = $size - 1;
}else{
$range_end = intval($range_end);
}
$new_length = $range_end - $range + 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . $new_length);
header('Content-Range: bytes ' . $range . '-' . $range_end . '/' . $size);
//set the offset range
$this->mt_range = $range;
}else{
$new_length = $size;
header("Content-Length: " . $size);
}
download file
if($file = fopen($filename, 'r')){
if(isset($_SERVER['HTTP_RANGE']) && !$this->force_single){
fseek($file, $this->mt_range);
}
//write the data out to the browser
while(!feof($file) && !connection_aborted() && $bytes_send < $block_size){
$buffer = fread($file, $chunksize);
echo $buffer;
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
}
I want to paste one script in all my client machine which call php file which is on my server.
Let say my server path is www.google.com/support/lokesh.php
So that I want to put one file to all my client machine at location where it call php file(for example if it call from /home/lalu/myscript.sh) then my php code will put one file(additional.sh) to /home/lalu/additional.sh
below is my code to download file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('google.com/support/lokesh.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('/home/lokesh/lalu.txt'));
readfile('/home/lokesh/lalu.txt');
//for sending mail fif only one user is available
exit;
I want to paste one file location at client machine from where it call server file.
One attempt, with a progress bar.
#!/usr/bin/php
<?php
if (#$argv[1] != null){
echo "Retrieving http header...";
$header = get_headers("$argv[1]");
$pp = "0";
echo json_encode($header, JSON_PRETTY_PRINT);
$key = key(preg_grep('/\bLength\b/i', $header));
$type = key(preg_grep('/\bType\b/i', $header));
$http = substr($header[0], 9, 3);
$tbytes = #explode(" ",$header[$key])[1];
$type = #explode("/",explode(" ",$header[$type])[1])[1];
echo " Target size: ".floor((($tbytes / 1000)/1000))." Mo || ".floor(($tbytes/1000))." Kb";
$t = explode("/",$argv[1]);
$remote = fopen($argv[1], 'r');
$nm = $t[count($t)-1].".$type";
$local = fopen($nm, 'w');
$read_bytes = 0;
echo PHP_EOL;
while(!feof($remote)) {
$buffer = fread($remote, intval($tbytes));
fwrite($local, $buffer);
$read_bytes += 2048;
$progress = min(100, 100 * $read_bytes / $tbytes);
$progress = substr($progress,0 , 6) *4;
$shell = 10; /* Progress bar width */
$rt = $shell * $progress / 100;
echo " \033[35;2m\e[0m Downloading: [".round($progress,3)."%] ".floor((($read_bytes/1000)*4))."Kb ";
if ($pp === $shell){$pp=0;};
if ($rt === $shell){$rt=0;};
echo str_repeat("█",$rt).str_repeat("=",($pp++)).">#\r";
usleep(1000);
}
echo " \033[35;2m\e[0mDone [100%] ".floor((($tbytes / 1000)/1000))." Mo || ".floor(($tbytes/1000))." Kb \r";
echo PHP_EOL;
fclose($remote);
fclose($local);
}
The file is build directly into the current folder, not in the temp directory.
This mean the file can be read while downloading.
If the file type is made to handle that, like most media format do.
To use, pass an url as first argument in the command line.
./pget https://site.download.mp4
You know you want to tweek it ;)
In my opinion, the easiest way is:
$fileContent = file_get_contents('/home/lokesh/lalu.txt');
If I correctly understood.
Try this code. In your download file :
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/".$extension); // you can put here MIME type of your file
header("Content-Disposition: attachment; filename=\"" . basename($filePath) . "\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filePath));
set_time_limit(0);
readfile("$filePath");
I currently test script an pseudo-streaming for read mp4 files, when I reading everything works fine, but I can not move the timeline? probleme ?
my coding (mp4 metadata) is correct because when reading without this code in the player, I can move in the timeline. I use fplayer for read the mp4.
// ----- NO CACHE -----
session_cache_limiter('nocache');
// General header for no caching
$now = gmdate('D, d M Y H:i:s') . ' GMT';
header('Expires: ' . $now); // rfc2616 - Section 14.21
header('Last-Modified: ' . $now);
header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
header('Pragma: no-cache'); // HTTP/1.0
// ----- Seek position -----
$seekat = 0;
if (isset($_GET["pos"])) {
$position = $_GET["pos"];
if (is_numeric ($position)) {
$seekat = $position;
}
if ($seekat < 0) $seekat = 0;
}
$filename = 'test.mp4';
$ext = strrchr($filename, ".");
$prefix = "";
$file = $prefix . $filename;
if (($filename != "") && (file_exists($file)) && ($ext==".mp4")) {
header("Content-Type: video/x-mp4");
if ($seekat > 0) header('Content-Length: ' . (filesize($file)-$seekat));
else header('Content-Length: ' . filesize($file));
if ($seekat != 0) {
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
$fh = fopen($file, "rb");
fseek($fh, $seekat);
while (!feof($fh)) {
print (fread($fh, 16384));
// print (fread($fh, filesize($file)));
}
fclose($fh);
}
Can you help me thank you.
header("Content-Type: video/x-mp4");
i currently use the same code but even when i stream an mp4 i let the header content as for a flv
Content-Type: video/x-flv
hope it's will help
Thanks to the users community on this forum, I wrote a very simple web form that allows my user to view text files from within their Internet browser.
I have now two functions whereby the text files returned by the search are compressed into a ZIP. Here's my code
function getFilesFromSite() {
$result = null;
$ZIPresult = null;
if (empty($_POST['DBSite'])) { return null; }
$mydir = MYDIR;
$dir = opendir($mydir);
$DBSite = $_POST['DBSite'];
$getfilename = mysql_query("select filename from search_table where site='" . $DBSite . "'") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
shell_exec("/bin/rm -f SearchResult.zip;/usr/bin/zip -9 SearchResult.zip ". $ZIPresult ." > /dev/null ");
//header for forced download
header("Pragma: public");
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
$fileName = 'SearchResult.zip';
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header('Content-type: application/zip');
header("Content-length: " . filesize($fileName));
header('Content-Disposition: attachment; filename="' . $fileName . '"');
ob_start(); // Starts output buffering.
readfile($fileName); // "Outputs" the file.
$content = ob_get_flush(); // Grabs the output and assigns it to a variable.
print base64_encode($content);
}
function getFilesFromError() {
//Just a copy paste from above with different input parameter...
}
The problem is that the ZIP file with the contents from whatever search was done first gets downloaded over and over again. For instance, the results from getFilesFromSite() will always get downloaded even though I did a search with getFilesFromError() afterwards.
I suspect my headers are incorrectly set but I am not sure where.
PS: The new ZipArchive() library/class is not available on our production environment so I chose to use the Unix utility ZIP instead.
Using Base64 was actually not working for reasons well stated here. Instead, I turned zlib compression off and reverted back to using binary as output format. Finally, I set Content-Type to application/octet-stream in my header. Everything is working fine now ; here's my code:
function getFiles() {
ini_set('zlib.output_compression', 'Off');
$result = null;
$ZIPresult = null;
$cleanup = null;
$output = null;
$fileName = null;
//remove old zip if any
$cleanup = shell_exec("/bin/rm -f SearchResult.zip");
error_log("SHELL OUTPUT=>" . $cleanup, 0);
//test
if (empty($_POST['DBRIDs'])) { return null; }
$mydir = MYDIR; // set from the CONSTANT
$dir = opendir($mydir);
$DBRIDs = $_POST['DBRIDs'];
$getfilename = mysql_query("select /*! SQL_CACHE */ filename from automation where rid in (" . $DBRIDs . ")") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
$output = shell_exec("/usr/bin/zip SearchResult.zip ". $ZIPresult ." ");
error_log("SHELL OUTPUT=>" . $output, 0);
$fileName = 'SearchResult.zip';
error_log("ZIP FILENAME=>" . $fileName, 0);
if (file_exists($fileName)) {
//header for forced download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit;
}
}
return $result;
}
Thanks to all for taking the time!!