messier - 오늘 관측 가능한 메시에 천체(저녁 시간대별) PHP/8.0.22

... Loading ...

소스닫기 | 24절기 계산 | 음양력변환, 일출몰, 월출몰, 별자리, 일월식 계산 | 메시에 관측정보(실시간) | 메시에 관측정보(오늘전체) | deltaT 계산 | 부활절 날짜 계산
<?php
##
function moon_pos_simple($JD$loc$yet_pos='')
{
  list(
$malt,$mpos) = moon_pos($JD,$loc);

  
// yet rise, 8/60 == moon_zenith
  
if($malt < (8/60)) { $mposp '-'$mpos $yet_pos; }
  else 
$mposp $mpos.round($malt);

  return array(
$mposp,$mpos);
}

function 
moon_today_prenext($JD0$JD12$rs_today$rs_prenext)
{
  
## input JD0 is midnight JD0 00:00
  ## todayJD0  is real today JD0
  ##
  
if($JD12 $JD0)
  {
    
$todayJD0 $JD0;
    
$JD1 $JD12 1;  // 이전날 정오 12:00
    
$JD2 $JD12;      // 당일 정오 12:00
    
$nextJD0 $JD0 1;
  }
  else
  {
    
$todayJD0 $JD0 1;
    
$JD1 $JD12;
    
$JD2 $JD12 1;
    
$nextJD0 $JD0;
  }

  list(
$todayJD)   = $rs_today;
  list(
$prenextJD) = $rs_prenext;

  
$rsJD = ($todayJD===NULL OR ($prenextJD>$JD1 && $prenextJD<$JD2)) ? $prenextJD $todayJD;
  
$rs   calendar::jd2hm($rsJD);
  
$rsp  = ($rsJD $todayJD0) ? '-' : (($rsJD >= $nextJD0) ? '+' '');

  return array(
$rsp,$rs,$rsJD);
}

//if(preg_match('/gzip/',$_SERVER['HTTP_ACCEPT_ENCODING']) && !headers_sent()) @ini_set('zlib.output_compression','On');

require_once '_lib/class.calendar.php';
require_once 
'_lib/class.astro.php';
require_once 
'_lib/class.meeus.php';
require_once 
'_lib/class.de405.php';
require_once 
'_lib/class.stellar.php';
require_once 
'_lib/func.array.php';
require_once 
'_lib/func.debug.php';

DE405::set_datadir($_SERVER['DOCUMENT_ROOT'].'/_lib');

## rstime/footer.php
$_js_utils_php 1;
$_js_jquery_min_php 1;
$_js_jquery_tablesorter_min_php 1;
$_js_jquery_metadata_php 1;

$_uri  $_SERVER['REQUEST_URI'];
$_self $_SERVER['SCRIPT_NAME']; //basename($_SERVER['SCRIPT_NAME']);
$_baseurl $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['SCRIPT_NAME']).'/';
$_tablewidth 820// px
$title 'messier - 오늘 관측 가능한 메시에 천체(저녁 시간대별)';

if(isset(
$_SERVER['PATH_INFO']))
{
  
$_datetime str_replace('/','',$_SERVER['PATH_INFO']);
  
$_date explode('.',$_datetime);
  
$_time $_date[1] ?? '';
  
$_date $_date[0];

  
$_d substr($_date,-2);
  
$_m substr($_date,-4,2);
  
$_y preg_replace("/${_m}${_d}$/",'',$_date);
  
$_h substr($_time,0,2);
  
$_i substr($_time,2,2);
}

## locations
##
$_locs astro::location_kr(NULL);
$seluloc $seldloc = array('','');
$loc  = array();
$uidx $didx 0;
$uloc $_COOKIE['uloc'] ?? '';

if(
$uloc)
{
  list(
$sidx,$uloc) = explode('|',trim(urldecode($uloc)));
  if(
$sidx 100)
  {
    if(isset(
$_locs[$sidx]))
    {
        
$didx $sidx;
        
$loc  $_locs[$sidx];
    }
  } else
  {
    list(
$ulon,$ulat) = explode(',',$uloc);
    
$loc[0] = $ulondeg astro::minmax(astro::dms2deg($ulon,2),-180,180);
    
$loc[1] = $ulatdeg astro::minmax(astro::dms2deg($ulat,2),-57,57);
    
$loc[2] = '사용자입력';
    
$uidx 1;
  }
}
else 
$loc $_locs[0];

$seluloc[$uidx] = 'CHECKED';
$seldloc[$didx] = 'SELECTED';

$_locsp '';
foreach(
$_locs AS $k=>$arr)
{
  
$_locsp .= "<option value='$k' ".($seldloc[$k] ?? '').">$arr[0]$arr[1] ($arr[2])</option>\n";
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE><?=$title?></TITLE>
<base href="<?=$_baseurl?>" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript">
<!--
var starttime = (new Date()).getTime();
//-->
</SCRIPT>
<STYLE TYPE="text/css">
<!--
  * { font-family:NanumGothic,'나눔고딕','Malgun Gothic',Dotum,'돋움',Gulim,'굴림',Helvetica,Apple-Gothic; }
  body { font-size:10pt; /* background: url(/images/_N8D20.jpg) no-repeat 100% 0% fixed; */ }
  td { font-size:9pt; vertical-align:middle; }

  th.header { background-image: url(/images/sort.default4.gif);
    background-repeat:no-repeat;
    background-position:100% 50%;
    cursor:pointer;
    border:1px solid #cccccc;
    padding-left:2px; /* 1px */
    padding-right:2px; } /* 5px */
  th.headerSortUp { background-image: url(/images/sort.desc4.gif);
    background-repeat:no-repeat; color:#ff00ff; }
  th.headerSortDown { background-image: url(/images/sort.asc4.gif);
    background-repeat:no-repeat; color:#ff00ff; }

  .ttcl, .tbcl, .tim { font-size:8pt; text-align:center; border-collapse:collapse; width:<?=$_tablewidth?>px; }
  .tbcl td, .tbclt td { border:1px solid #cccccc; vertical-align:middle; height:30px; }
  .thcl { font-weight:bold; height:40px; /* background-color:#cccccc; */ }
  .tbclt { font-size:8pt; text-align:center; border-collapse:collapse; width:<?=$_tablewidth?>px; }
  .ttcl td, .tim td { border:1px solid #cccccc; vertical-align:middle; height:30px; }
  .tim td { text-align:center; font-size:8pt; }

  .bold { font-weight:bold; }
  .warn { border: 1px solid #ff0000; }
  .tohide { color:#ffffff; font-size:0em; }
  .pointer { cursor:pointer; }

  input { font-size:9pt; background-color:#ffffff; border:solid 1px #4f7292; margin:0 0 0 0; height:30px; }

  .pagewait { position:absolute; text-align:center; vertical-align:middle;
    width:400; height:200; border:0; background-color:transparent;
    left:200; top:185; color:#0000ff; }

  .vmiddle { vertical-align:middle; }

  #box { position:absolute;
    width:380px; height:250px; text-align:center; vertical-align:middle;
    margin:0px; padding:0px;
    left:200; top:100;
    border:1px solid #4f7292; font-family:Tahoma; font-size:11px; background-color:#ffffff; }
  #box td { font-size:11px; }
  #box input { margin:3px 0 3; }  /* 상, 우, 하, 좌 */ /* 바깥쪽 여백임 */
  span#box:hover { text-decoration:underline; }

  #boxclose { cursor:pointer; text-align:right; padding-right:15px; padding-top:8px; color:#0000ff; }

  #setloc, .totop, .showhide { cursor:pointer; font-size:11px; color:#0000ff; text-decoration:underline; }
  .tbloc { font-size:8pt; border-collapse:collapse; margin:0px auto; }  /* table center align to margin:0px auto */
  .tbloc td { border:1px solid #cccccc; vertical-align:middle; height:50px; }
  .radio { border:0; vertical-align:middle; }
  .toactive { cursor:pointer; }
  #errmsg { color:#ff0000; }
  .viewlimg { cursor:pointer; }
  #viewlimg { position:absolute; text-align:center; vertical-align:middle;
    left:150; width:750; height:800; border:0; }

  .code {
    /* display: block | table-cell | inline-table; */
    display: table-cell; vertical-align: middle; 
    padding: 10px;
    margin: 10px 5px 20px 5px;  /* 상, 우, 하, 좌 */ /* 바깥쪽 여백임 */
    background: #eeeeee;
    border-radius: 0.5em / 0.5em;
    font-family: Dotumche,monospace; white-space: pre;
    width:800px; }
  .pre-fontspace  { font-family:Dotumche,Helvetica,monospace; white-space: pre; }
  .pre-font  { font-family:Dotumche,Helvetica,monospace; }
  .pre-space { white-space: pre; }
  .solidbox {
    display: table-cell; vertical-align: middle;
    padding: 10px;
    margin: 10px 5px 20px 5px;  /* 상, 우, 하, 좌 */ /* 바깥쪽 여백임 */
    background: #eeeeee;
    border-radius: 0.5em / 0.5em; } /* 모서리 둥글게 */

  .thin-line           { border-top: 1px solid #ddd; margin: 0px 0px; }
  .tabs                { display: inline-block; width: <?=$_tablewidth?>px; margin: 0 auto; }
  .tabs .menu          { background: none; width: 57px; text-align: center; color: #111; display: inline-block; padding: 15px 10px; cursor: pointer; }
  .tabs .menu:hover    { background: #eee; }
  .tabs .menu.current  { background: #eee; font-weight: bold; } /* border-radius:  0.5em / 0.5em; */
  .tab-content         { display: none; padding: 0px; }
  .tab-content.current { display: inherit; }
//-->
</STYLE>
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript" SRC='/_lib/js.utils.php'></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript" SRC='/_lib/js.jquery.min.php'></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript" SRC='/_lib/js.jquery.tablesorter.min.php'></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript" SRC='/_lib/js.jquery.metadata.php'></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" type="text/JavaScript">
<!--
function enable_sortable(tid)
{
  var trnum = $('#'+tid+' tbody > tr').length;
  if(trnum < 2) return;

  $("#"+tid).tablesorter
  ({
    headers:
    {
        0: { sorter: "text" },
        1: { sorter: "numberic" },
        2: { sorter: "text" },
        3: { sorter: "text" },
        4: { sorter: "numberic" },
        5: { sorter: "text" },
        6: { sorter: "text" },
        7: { sorter: "text" },
        8: { sorter: "text" },
        9: { sorter: "text" },
        10:{ sorter: "text" },
        11:{ sorter: "text" },
        12:{ sorter: "text" }
    },
    sortMultiSortKey: 'altKey'
  });

  return;
}

function echo(s)
{
  document.write(s);
}

function dms2deg(dms)
{
  dms = dms.replace(/[^\d.+-]+/g,' ',dms);
  dms = dms.replace(/^\s+/,'').replace(/\s+$/,''); // trim()
  var d = dms.split(' '); // Array

  if(!d[0]) d[0] = 0;
  if(!d[1]) d[1] = 0;
  if(!d[2]) d[2] = 0;

  if(d[0].match(/^-/)) var deg = Number(d[0]) - Number(d[1]/60) - Number(d[2]/3600);
  else var deg = Number(d[0]) + Number(d[1]/60) + Number(d[2]/3600);

  deg = Math.round(deg*100) / 100;

  return deg;
}

$(window).bind('load',function()
{
  $('img').each(function()
  {
    if((typeof this.naturalWidth != "undefined" && this.naturalWidth == 0 ) || this.readyState == 'uninitialized')
    {
        //$(this).attr('src', '/images/n.gif');
        this.src = '/images/n.gif';
        this.border = 1;
        this.width = 28;
        this.height = 30;
        this.alt = 'no image';
    }
  });
});

$(document).ready(function()
{
  $.tablesorter.addParser
  ({
    id: "toint",
    is: function(s)
    {
        return true;
    },
    format: function(s)
    {
        s = s.replace(/[^\d]+/,'');
        if(s == '') s = 100;
        return s;
    },
    type: "numeric"
  });

  enable_sortable('tsorttodayAll');

  var boxshow = 0;
  $('#setloc, #boxclose').click(function()
  {
    if(boxshow) $('#box').hide();
    else $('#box').show();

    boxshow ^= 1;
    return;
  });

  /*
  var showhides = new Array();
  $('.showhide').click(function()
  {
    var tid = this.id.replace(/close$/,'');

    if(!showhides[tid])
    {
        $('#'+tid).hide();
        $('#'+tid+'close').html('&laquo;보기');
    } else
    {
        $('#'+tid).show();
        $('#'+tid+'close').html('&laquo;감추기');
    }

    showhides[tid] ^= 1;
    return;
  });
  */

  $('#saveuloc').click(function()
  {
    var loc = v = p = '';
    var t = $(':input:radio[name=radiouloc]:checked').val();

    if(t == 1)
    {
        var warnclass = $('#ulon').attr('class') + $('#ulat').attr('class');
        if(warnclass.match(/warn/)) return false;

        var lon = $('#ulon').val();
        var lat = $('#ulat').val();
        v = 101 + '|' + lon + ',' + lat;
        p = dms2deg(lon) + ', ' + dms2deg(lat) + ' (사용자입력)';
    } else
    {
        var idx = $("#ploc option:selected").val();
        var txt = $("#ploc option:selected").text();
        v = idx + '|' + txt;
        p = txt;
    }

    $('#loc').text(p);
    //setcookie('uloc',encodeURI(v)); // save cookie
    setcookie('uloc',encodeURI(v),365); // save cookie
    //$('#errmsg').html('<font color=blue>OK</font>');

    $('#box').hide();
    boxshow = 0;

    return;
  });

  $('#ulon, #ulat').bind("keydown keyup click focus blur",function(e)
  {
    var errmsg = '';
    $('#uloc1').attr("checked", "checked");

    var v = $('#ulon').val();
    if(v.length>0 && v.match(/^[\d\s+-.'"dms]+$/))
    {
        $('#ulon').removeClass('warn');
        if(this.id == 'ulon') $('#ulondeg').text(dms2deg(v));
    } else
    {
        $('#ulon').addClass('warn');
        if(v.length > 0) errmsg = '경도';
    }

    var v = $('#ulat').val();
    if(v.length && v.match(/^[\d\s+-.'"dms]+$/))
    {
        $('#ulat').removeClass('warn');
        if(this.id == 'ulat') $('#ulatdeg').text(dms2deg(v));
    } else
    {
        $('#ulat').addClass('warn');
        if(v.length > 0) errmsg += ' 위도';
    }

    if(errmsg) errmsg = errmsg.replace(/^\s+/,'') + ' 입력 에러';
    $('#errmsg').text(errmsg);

    return;
  });

  $('#viewlimg').click(function()
  {
    $('#viewlimg').hide();
    //alert(this.src);
  });

  $('.viewlimg').click(function()
  {
    var imgsrc = $(this).attr('SRC').replace(/-s\.gif/,'.jpg');

    if(imgsrc.match(/n\.gif$/)) return false;

    if(imgsrc.match(/G[\d]+\.jpg$/))
    {
        imgsrc = imgsrc.replace(/G([\d]+\.jpg)/,"NGC$1");
        //alert(imgsrc);
    }

    var cpos = $(window).scrollTop() + 10; // current scroll position
    $('#viewlimg').css('top',cpos);
    $('#viewlimg').html('<img src='+imgsrc+' border=0 alt="click to close">');
    $('#viewlimg').fadeIn(1500);
    return;
  });

  $('.tabs .menu').click(function()
  {
    var tab_id = $(this).attr('tabidx');

    $('.tabs .menu').removeClass('current');
    $('.tab-content').removeClass('current');

    $(this).addClass('current');
    $('#'+tab_id).addClass('current');
  });

  $('#pagewait').hide(); // last
});

//-->
</SCRIPT>
</HEAD>
<BODY>
<H2><?=$title.' PHP/'.PHP_VERSION?></H2>
<div id='pagewait' class='pagewait'><H1>... Loading ...</H1></div>
<div id='box' style='display:none'>
<div align=right id=boxclose>[close]</div>
<br>
관측지 설정/변경하기
<table width=97% class=tbloc>
<form name=ploc>
<tr><td valign=middle width=80><input type=radio name=radiouloc class=radio id=uloc0 value=0 <?=$seluloc[0]?>>
<span class=toactive id=to0>기본값</span></td>
<td><select id=ploc><?=$_locsp?></select></td></tr>
<tr><td valign=middle>
<input type=radio name=radiouloc class=radio value=1 id=uloc1 <?=$seluloc[1]?>>
<span class=toactive id=to1>직접입력</span>
</td><td>
<input type=text value='<?=$ulondeg??''?>' id=ulon> 경도 <span id=ulondeg><?=$ulondeg??''?></span><br>
<input type=text value='<?=$ulatdeg??''?>' id=ulat> 위도 <span id=ulatdeg><?=$ulatdeg??''?></span> (-57 ~ +57)
</td></tr>
<tr><td colspan=2 align=center><input type=button id=saveuloc value=' 저장(Cookie) '><br><span id=errmsg>&nbsp;</span></td></tr>
</form>
</table>
</div>
<div id='viewlimg' style='display:none'></div>
<?php
$_menuindex 
= array
(
  
'solar.php'         => '24절기 계산',
  
'lunar.php'         => '음양력변환, 일출몰, 월출몰, 별자리, 일월식 계산',
  
'messier.php'       => '메시에 관측정보(실시간)',
  
'messier.today.php' => '메시에 관측정보(오늘전체)',
  
'deltat.php'        => 'deltaT 계산',
  
'easter.php'        => '부활절 날짜 계산'
);

$menu '';
foreach(
$_menuindex AS $k=>$v)  $menu .= " | <A HREF='$k'>$v</A>";

if(isset(
$_GET['view']))
{
  echo 
'<A HREF="'.$_self.'">소스닫기</A>'.$menu.'<HR>'."\n";
  
highlight_file(basename($_self));
  return;
}

echo 
'<A HREF="'.$_self.'?view=1">소스보기</A>'.$menu.'<HR>'."\n";
echo 
"<H2>데모 - 오늘은 어떤 천체를 볼 수 있는지(시간대별) ...</H2>\n";

list(
$JD,$_y,$_m,$_d,$_h,$_i) = calendar::curr_datetime();
$_i floor($_i/5) * 5// rewrite

$stellar_today stellar::today($loc);  // array
$twJDs $stellar_today['h']['w']; // twJDs
$stellar_today_t array_keys($stellar_today['t']);
$vpos "$loc[0]$loc[1] ($loc[2])";

/*
echo '<pre>';
print_r($stellar_today);
exit;
*/

/*** same as messier.php ***/
## sun rise/set/tw
##
$sunriseset, , , $twriseset ] = sun_riseset($JD,$loc);  // all
[ [$sunrJD,$sunr], [$sunsJD,$suns] ] = $sunriseset;
[ [
$twrJD ,$twr ], [$twsJD ,$tws ] ] = $twriseset;

## moon rise/set
##
[ [$moonrise_today,$moonset_today], $mcult ] = moon_riseset($JD,$loc);
$mcul $mcult[0] ? ($mcult[1].'('.$mcult[3].round($mcult[2]).')') : '';

$mrp  $msp '';
$JD0  calendar::jd2jd0($JD);
$JD12 $JD0 0.5;


## 이전 날 저녁 + 당일 새벽
##
if($_h 7)
{
  
$printw[0]    = '이전 날('.  calendar::date('m/d,l',$JD-1).')';
  
$printw[1]    = '관측 당일('.calendar::date('m/d,l',$JD).')';
  
$todaymark[1] = 'class=todaymark';

  [ 
$sunriseset, , , $twriseset ] = sun_riseset($JD-1,$loc);  // all
  
[ [$moonrise_yesterday,$moonset_yesterday], $mcul_yesterday ] = moon_riseset($JD-1,$loc);
  [ ,[
$sunsJD,$suns] ] = $sunriseset;
  [ ,[
$twsJD ,$tws ] ] = $twriseset;

  if(!
$mcul$mcul '-'.$mcul_yesterday[1].'('.$mcul_yesterday[3].round($mcul_yesterday[2]).')';
  list(
$mrp,$mrise,$mriseJD) = moon_today_prenext($JD0,$JD12,$moonrise_today,$moonrise_yesterday);  // moon rise
  
list($msp,$mset ,$msetJD)  = moon_today_prenext($JD0,$JD12,$moonset_today ,$moonset_yesterday);   // moon set
}

## 당일 저녁 + 다음 날 새벽
##
else
{
  
$printw[0]    = '관측 당일('.calendar::date('m/d, l',$JD).')';
  
$printw[1]    = '다음 날('.  calendar::date('m/d, l',$JD+1).')';
  
$todaymark[0] = 'class=todaymark';
  
$JD0 += 1;

  [ 
$sunriseset, , , $twriseset ] = sun_riseset($JD+1,$loc);  // all
  
[ [$moonrise_tomorrow,$moonset_tomorrow], $mcul_tomorrow ] = moon_riseset($JD+1,$loc);
  [ [
$sunrJD,$sunr] ] = $sunriseset;
  [ [
$twrJD ,$twr ] ] = $twriseset;

  if(!
$mcul$mcul '+'.$mcul_tomorrow[1].'('.$mcul_tomorrow[3].round($mcul_tomorrow[2]).')';
  list(
$mrp,$mrise,$mriseJD) = moon_today_prenext($JD0,$JD12,$moonrise_today,$moonrise_tomorrow);
  list(
$msp,$mset ,$msetJD)  = moon_today_prenext($JD0,$JD12,$moonset_today ,$moonset_tomorrow);
}

## 월령 계산(local 0시기준)
##
$lunar    tolunar($JD0);
$moonage  $JD0 $lunar[2][2];
$moonage  = ($moonage<0) ? 30.0 sprintf('%.1f',$moonage);
$moonagep = (int)$moonage;

## dark time
##
$dark   = ($twrJD $twsJD) * 24// total dark hour times
$darkh  astro::h2hm($dark);
$moon_visible = (int)(($msetJD $twsJD) || ($mriseJD $twsJD));
$mdark  = ($mriseJD $twsJD) ? max($twrJD-$msetJD,0) : (min($mriseJD,$twrJD) - $twsJD);
$mdark *= 24;  // to hours
/*** end same as messier.php ***/

if($moon_visible)
{
  
// 1=>twr 2=>tws 3=>22:00 4=>00:30 5=>03:00
  
list($mtwrp,$mtwrpos) = moon_pos_simple($twJDs[1],$loc,'');
  list(
$mtwsp,$mtwspos) = moon_pos_simple($twJDs[2],$loc,'');
  list(
$mevp ,$mevpos)  = moon_pos_simple($twJDs[3],$loc,'');
  list(
$mmdp ,$mmdpos)  = moon_pos_simple($twJDs[4],$loc,'');
  list(
$mdwp ,$mdwpos)  = moon_pos_simple($twJDs[5],$loc,'');

  
$mooninfo = array
  (
    
'Moon',        // messier
    
"<img src=moonage/moonage-$moonagep.gif>",
    
0,        // marathon
    
'-',        // 별자리
    
'위성',        // type
    
'-',        // 밝기
    
$mtwsp,        // 달의 위치 tws    k=0
    
$mevp,        // 달위 위치 22:00  k=1
    
$mmdp,        // 달위 위치 00:30  k=2
    
$mdwp,        // 달위 위치 03:00  k=3
    
$mtwrp,        // 달위 위치 twr    k=4
    
$mcul        // 남중시간, 고도
  
);

  
array_insert($stellar_today['m'],0,array($mooninfo));
  if(
$mtwspos)
  {
    
$k $stellar_today_t[0]; // k=0
    
array_insert($stellar_today['t'][$k][$mtwspos],0,"Moon($mtwsp)");
  }
  if(
$mevpos)
  {
    
$k $stellar_today_t[1]; // k=1
    
array_insert($stellar_today['t'][$k][$mevpos],0,"Moon($mevp)");
  }
  if(
$mmdpos)
  {
    
$k $stellar_today_t[2]; // k=2
    
array_insert($stellar_today['t'][$k][$mmdpos],0,"Moon($mmdp)");
  }
  if(
$mdwpos)
  {
    
$k $stellar_today_t[3]; // k=3
    
array_insert($stellar_today['t'][$k][$mdwpos],0,"Moon($mdwp)");
  }
  if(
$mtwrpos)
  {
    
$k $stellar_today_t[4]; // k=4
    
array_insert($stellar_today['t'][$k][$mtwrpos],0,"Moon($mtwrp)");
  }
}

echo 
"<div class=solidbox>";
echo 
"<b>관측 위치:</b> <span id=loc>$vpos</span> <span id=setloc>[&laquo;변경하기] <img class=vmiddle src=/images/acc1.gif border=0 align=middle></span><br>\n";
echo 
"<b>관측 날짜:</b> ".calendar::date('Y-m-d (D) T',$JD); //$_y-$_m-$_d";
echo "</div><p>\n";

echo 
"<div class='tabs'>\n";
echo 
"<div class='current menu' tabidx='tab-1'>오늘전체</div>\n";

$i 2;
foreach(
$stellar_today_t AS $tt)
{
  echo 
"<div class=menu tabidx='tab-${i}'>$tt</div>\n";
  
$i++;
}
echo 
"<div class=thin-line></div>\n";

$tdw floor($_tablewidth/sizeof($stellar_today['h']['m']));
$thd $stellar_today['h']['m'];
array_insert($thd,1,'pic');

$thd "<TR class=thcl><TH width=${tdw}>".implode("</TH><TH width=${tdw}>",$thd)."</TH></TR>\n";

echo 
"<div id='tab-1' class='tab-content current'><p>";
echo 
'<b>오늘 관측 가능한 메시에 천체(지정한 관측지의 당일과 익일 새벽 기준) '.sizeof($stellar_today['m'])."개</b>\n";
echo 
"<p>\n";
echo 
"<TABLE BORDER=1 WIDTH=$_tablewidth class=tbcl id=tsorttodayAll>\n";
echo 
"<THEAD>$thd</THEAD>\n<TBODY>";
foreach(
$stellar_today['m'] AS $arr)
{
  if(
is_numeric($arr[1]))  // skip moon, aleray done
  
{
    
$tryfile 'messier/'.$arr[0].'-s.gif';
    
$imgsrc  file_exists($tryfile) ? "<img src='$tryfile' class=viewlimg>" '-';
    
array_insert($arr,1,$imgsrc);
  }
  echo 
"<TR><TD>".implode("</TD><TD>",$arr)."</TD></TR>\n";
}
echo 
"</TBODY>\n";
echo 
"</TABLE>\n";
echo 
"</div>\n";

$tdw floor($_tablewidth/sizeof($stellar_today['h']['t']));
$tdh "<TABLE BORDER=1 WIDTH=$_tablewidth class=ttcl><TR><TD width=${tdw}>".implode("</TD><TD width=${tdw}>",$stellar_today['h']['t'])."</TD></TR>\n";

$rows sizeof($stellar_today['t']['00:30']['E']);
$i 2;
foreach(
$stellar_today['t'] AS $at=>$poss)
{
  echo 
"<div id='tab-{$i}' class='tab-content'><p><b>{$at}에 볼수 있는 메시에 천체</b><p>\n";
  echo 
$tdh;
  for(
$k=0$k<$rows$k++)
  {
    echo 
"<TR>";
    foreach(
$stellar_today['h']['t'] AS $pos) echo '<TD>'.($poss[$pos][$k] ?? '-').'</TD>';
    echo 
"</TR>\n";
  }
  echo 
"</TABLE></div>\n";
  
$i++;
}

echo 
"</div><p>\n";  // end tabs
echo "</body></html>";

return;
?>

Page loading: 0.01(server) + (network) + (browser) seconds