PAGE)){$this->PAGE=[];} if(!isset($this->PAGE[0])){$this->PAGE[]=[];} return $this->PAGE[array_key_last($this->PAGE)]; }
    function &TRow(){ $last=array_key_last($this->PAGE); if($this->PAGE[$last]==[]) return $this->PAGE[$last]; $this->PAGE[]=[]; return $this->PAGE[$last]; }
    function TFill($k,&$content,$span=null){ $a=&$this->_TRow();if(!isset($a[$k]))$a[$k]="";$a[$k].=$content; $content=''; if($span!=null && $span>1){ $a['span'.$k]=$span; } }
    function TExtra($rowextra){ $a=&$this->_TRow(); $a['extra']=$rowextra; }
    function TAfter(&$content){ $this->AFTER.=$content; $content=''; }
    function TBackup(){ if(!isset($this->PSTACK)){$this->PSTACK=[];}; $this->PSTACK[]=$this->PAGE; $this->PAGE=[]; }
    function TRestore($extra=""){ if(!isset($this->PSTACK) || $this->PSTACK==[]) return "";
        $S=$this->GeneratePage(0,$extra); $this->PAGE=end($this->PSTACK); unset($this->PSTACK[array_key_last($this->PSTACK)]); return $S;
    }
    
    function ReadableTime($id){
        $dt = DateTime::createFromFormat('YmdHis', $id);
        return $dt->format('Y/m/d H:i:s');
    }
    function StandardTime($id){
        $dt = DateTime::createFromFormat('YmdHis', $id);
        return $dt->format('Y-m-d\TH:i:sP');
    }
    function FullURL(){
        return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ?
                "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . 
                $_SERVER['REQUEST_URI'];
    }
    function T($str){
        if(!$this->LanguageAppendix) return $str;
        foreach($this->Translations as $entry){
            if($entry['zh']==$str)
                return $entry[$this->LanguageAppendix];
        }
        return $str;
    }
    function SwitchLanguageAndFont(){ global $LA_GLOBAL_LANG;
        $this->LanguageAppendix = 'zh';
        if(isset($_COOKIE['la_language'])){
            $this->LanguageAppendix = $_COOKIE['la_language'];
        }else{
            if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
                $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
                $lang = substr($lang,0,5);
                if(preg_match("/zh/i",$lang))$this->LanguageAppendix = 'zh';
                else $this->LanguageAppendix = 'en';
            }
        }
        if(isset($LA_GLOBAL_LANG)){
            if($LA_GLOBAL_LANG=='en'){ $this->LanguageAppendix = 'en'; setcookie('la_language','en',time()+3600*24*7,'/'); }
            else if($LA_GLOBAL_LANG=='zh'){ $this->LanguageAppendix = 'zh'; setcookie('la_language','zh',time()+3600*24*7,'/'); }
        }
        if(isset($_COOKIE['la_font'])){
            $this->UseRemoteFont = ($_COOKIE['la_font']!='local');
        }
        if($this->LoggedIn && isset($_COOKIE['la_notes_view'])){ $this->NotesView=$_COOKIE['la_notes_view']; }
    }
    function SwitchWayBackMode(){        
        if(isset($_COOKIE['la_wayback'])){
            $this->WayBack = $_COOKIE['la_wayback'];
        }else $this->WayBack = NULL;
    }
    
    function DisplayRedirectConfig(){
        $s = "";
        if(isset($this->Redirect) && isset($this->Redirect[0])) foreach($this->Redirect as $r){
            if($r['for']=='P'){
                $s.=("P ".$r['format'].":".$r['target'].";".PHP_EOL);
            }else if($r['for']=='S'){
                $s.=("S ".$r['format'].":".$r['domain'].":".$r['target'].";".PHP_EOL);
            }
        }
        return $s;
    }
    
    function DoSiteRedirect(){ global $INDEXPHP;
        if(isset($this->Redirect) && isset($this->Redirect[0])) foreach($this->Redirect as $r){
            if($r['for']=='S'){
                if(preg_match('/'.$r['format'].'/ui', $_SERVER['HTTP_HOST'])){
                    if($_SERVER['REQUEST_URI']=='/'||$_SERVER['REQUEST_URI']==''){
                        header('Location:https://'.$r['domain'].'/'.$INDEXPHP.'?post='.$r['target']); exit;
                    }else{
                        header('Location:https://'.$r['domain'].$_SERVER['REQUEST_URI']); exit;
                    }
                }
            }
        }
    }
    
    function WriteHTACCESS(){
        $conf = fopen('.htaccess','w');
        fwrite($conf,"RewriteEngine on".PHP_EOL.PHP_EOL);
        if(isset($this->Redirect) && isset($this->Redirect[0])) foreach($this->Redirect as $r){
            if($r['for']=='P'){
                if(!preg_match('/[0-9]{14}/',$r['target'])){
                    fwrite($conf,"RewriteRule ^".$r['format'].'$ /index.php?'.$r['target'].' [R=302,L,NC]'.PHP_EOL.PHP_EOL);
                }
                fwrite($conf,"RewriteRule ^".$r['format'].'$ /index.php?post='.$r['target'].' [R=302,L,NC]'.PHP_EOL.PHP_EOL);
            }// do site redirect in php.
        }
        fwrite($conf, 'RewriteCond %{HTTPS} !=on'.PHP_EOL.
                      'RewriteCond %{HTTP_HOST} !=localhost'.PHP_EOL.
                      'RewriteCond %{REQUEST_URI}  !^.*(jpg|png|gif)$'.PHP_EOL.
                      'RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NC]'.PHP_EOL.PHP_EOL);
        fwrite($conf,'
"; }
            $imcount++; if($imcount>=4){ break; }
        }
        
        $text = strip_tags(preg_replace('/<\/(p|blockquote|h[0-9])>/u',"\n\n",$post['html']));
        if(isset($this->HostURL) && $this->HostURL!=""){
            $text.=("\n\n".$this->T('来自').' '.$this->HostURL.'?post='.$post['id']);
        }
        
        $vis = (isset($post['mark_value']) && $post['mark_value']==6)?"private":"public";
        $status_data = [ 'status' => $text, 'visibility' => $vis, 'language' => $this->LanguageAppendix, ];
        if(isset($post['prev']) && ($pp=&$this->GetPost($post['prev']))!=$this->NULL_POST){
            if(isset($pp['mastodon_url'])){ $status_data['in_reply_to_id'] = basename($pp['mastodon_url']); 
            }
        }
        if(isset($media_ids[0])){ $status_data['media_ids']=$media_ids; }
        $status_data = preg_replace('/(media_ids%5B)[0-9]+(%5D)/','$1$2', http_build_query($status_data));
        
        $status_response = $this->MastodonPostStatus($status_data);
        if(isset($status_response['url']) && $status_response['url']){
            $mastodon_post_url = $status_response['url'];
            $post['mastodon_url'] = $mastodon_post_url;
            $this->NeedWritePosts = 1;
        }
        if(isset($status_response['error'])) { $errmsg .= $status_response['error']; }
        
        return $mastodon_post_url;
    }
    
    function __construct() {
        $this->ReadConfig();
        $this->PDE = new ParsedownExtra();
        $this->PDE->SetInterlinkPath('/');
        $this->Posts = [];
        $this->Threads = [];
        $this->VisitedHere = [];
        
        $this->NULL_IMAGE_DUMMY = [];
        $this->NULL_IMAGE_DUMMY['name']=$this->NULL_IMAGE_DUMMY['file']=$this->NULL_IMAGE_DUMMY['thumb']="";
        
        $this->Markers=['●', '○', '✓', '×', '!', 'P', 'E', 'S', 'N'];
        
        $this->PostsPerPage = 40;
        $this->CommentsPerPage = 100;
        $this->HotPostCount = 15;
        
        $this->TIME_STRING = date('YmdHis');
        $this->WayBack = NULL;
        $this->YearBegin = $this->YearEnd = 2000;
        $this->DoneReadPosts = $this->DoneReadImages = $this->DoneReadArchive = false;
        $this->NeedWritePosts= $this->NeedWriteImages= $this->NeedWriteArchive= false;
        $this->UsePosts = &$this->Posts;
        $this->PNUMBER=0;
    }
    
    function DoLogout(){
        $this->LoggedIn = false;
        unset($_SESSION['user_id']);
        $this->RecordToken(true);
    }
    
    function RecordToken($unset_current=false){
        if(isset($unset_current) && isset($_COOKIE['la_token'])){
            $t = $_COOKIE['la_token'];
            setcookie('la_token', null, -1,'/'); unset($_COOKIE['la_token']);
            if (($key = array_search($t,$this->LoginTokens)) !== false) { unset($this->LoginTokens[$key]); }
            $this->WriteTokens();
            return null;
        }else{
            $t = uniqid('la_',true);
            setcookie('la_token',$t,time()+3600*24*7,'/'); $_COOKIE['la_token'] = $t;
            $this->LoginTokens[] = $t;
            $this->WriteTokens();
            return $t;
        }
    }
    
    function LoginThroughToken(){
        if(!isset($_COOKIE['la_token'])) return false;
        $t = $_COOKIE['la_token'];
        if (($key = array_search($t,$this->LoginTokens)) !== false) {
            $_SESSION['user_id']=$this->Admin;
            $this->LoggedIn = true;
            setcookie('la_token',$t,time()+3600*24*7,'/');
            return true;
        }
        return false;
    }
    
    function DoLogin(){
        session_start();
        $redirect=false;
        if(isset($_GET['logout'])){ $this->DoLogout(); header('Location:index.php'); }
        else if(!isset($_SESSION['user_id'])){
            if(isset($_POST['login_button'])){
                $id = trim($_POST['login_id']);
                $pwd = trim($_POST['login_password']);
                if(strtolower($this->Admin)==strtolower($id)&&password_verify($pwd, $this->Password)){
                    $_SESSION['user_id']=$id;
                    $this->RecordToken(false);
                }
                $redirect = true;
            }else if($this->LoginThroughToken()){
                // nothing;
            }
        }else{
            if(strtolower($_SESSION['user_id']) == strtolower($this->Admin)){ $this->LoggedIn = true; }
            else{ $this->DoLogout();}
        }
        if($redirect){
            header('Location:index.php'.(isset($_GET['post'])?("?post=".$_GET['post']):"")
                                       .(isset($_GET['settings'])?"?settings=true":""));
        }
    }
    function SetHereMainImage($im_this){
        if(isset($im_this) && isset($im_this['parent'])){ $this->HereMainImage = &$this->FindImage($im_this['parent'],true);}
    }
    function RecordVisitedHere($image_or_post_name, $image_title){
        $visited_here = $this->InExperimentalMode?"visited_experimental":"visited_here";
        if(!isset($_SESSION[$visited_here])){ $_SESSION[$visited_here] = []; }
        if(!(isset($_SESSION[$visited_here][0]) && in_array($image_or_post_name,$_SESSION[$visited_here]))){
            $_SESSION[$visited_here][] = $image_or_post_name;
        }
        if(isset($image_title)){ $this->HereDisplayTitle=$image_title; }
        $this->HereNumber = array_search($image_or_post_name,$_SESSION[$visited_here])+1;
        $_SESSION['here_number'] = $this->HereNumber;
        $this->VisitedHere = $_SESSION[$visited_here];
    }
    function HereLinkFromNumber($number){
        $number -= 1; if($number<0){ $number=0; }
        if($number>=sizeof($this->VisitedHere)){ $number = sizeof($this->VisitedHere)-1; }
        if(preg_match('/(jpg|jpeg|png|gif)/u',$this->VisitedHere[$number])){ return "?here=images/".$this->VisitedHere[$number]; }
        else{ return "?post=".$this->VisitedHere[$number]; }
    }
    
    function WriteStyles(){
        $this->style="
html{font-size:18px;font-family:'Noto Serif CJK SC','Times New Roman','SimSun', Georgia, serif;}
.page{overflow:none;}
body{background-color:%white%;color:%black%;}
sup,sub{line-height:0;} .lpctrl{display:none;}
blockquote{border-left:2px solid %black%;padding-left:0.3em;}
*{box-sizing:border-box;padding:0;margin:0;font-weight:normal;}
b,strong,th{font-weight:bold;}
select{font-size:inherit;}
.page,.page_gallery{padding:1em;padding-top:0;padding-bottom:0;}
.hidden_on_desktop,.hidden_on_wide{display:none;}
.hidden_on_desktop_force{display:none !important;}
::file-selector-button{background:none;border:none;}
a,button,::file-selector-button{text-decoration:underline;color:%black%;text-decoration-thickness:2px;text-underline-offset:0.15em;}
a:hover,.button:hover,::file-selector-button:hover{text-decoration:none;color:%gray%;}
.button:disabled{background-color:%gray%;pointer-events:none;}
header{position:fixed;top:0;width:calc(100% - 2em);background-color:%white%;z-index:10;padding-top:0.5em;box-shadow: 0.5em 0px %white%;}
header::before{content:'';position:absolute;left:0;right:0;top:0;height:1.95em;box-shadow:-2em 0em 1em -1em inset %white%;pointer-events:none;}
header>div{overflow:auto;white-space:nowrap;}
.header_nav{display:inline;}
header a,.left a,.footer a,.clean_a,.clean_a a{text-decoration:none;}
header a:hover,.button:hover{color:%gray% !important;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:0.15em;}
.exp_h_f{padding-top:0.3em !important;padding-bottom:0.3em !important;line-height:1.5em !important;height:2.1em !important;}
.exp_f{text-align:center;}
.toc_button{position:absolute;top:0.5em;right:0;text-shadow: 0px 0px 10px %white%;background-color:%white%88;}
.footer{background-color:%white%;z-index:10;position:relative;}
.invert_a,.invert_a a{color:%gray%;text-decoration:none;}
.invert_a:hover,.invert_a a:hover{color:%black% !important;}
.gray,.gray a{color:%gray%;}
hr{border:1px solid %gray%;}
header ul,.small_footer ul,.small_footer span,header li,.small_footer li{display:inline-block;vertical-align:text-top;}
header li::before,.small_footer li::before{content:' - '}
header li ul{display:none;}
header:hover li ul{display:inline;}
header li ul li{display:block !important;margin-left:1em;}
header li ul li a{font-size:0.9em;}
//h1,h2,h3,h4,h5{font-size:1em;}
//h1{text-decoration:underline;}
header h1,header h2,header h3,header h4,header h5,header p{display:inline;font-size:1rem;}
.main{position:relative;word-spacing:-1em;top:2em;margin-bottom:2em;}
.main *{word-spacing:initial;}
pre{overflow:auto;display:block;line-break:anywhere;white-space:pre-wrap;}code{font-size:0.83em;}
ul{display:block;}
li{display:block;}
.clean_table{border:none;font-size:1em !important;}.clean_table thead{box-shadow:none;}.clean_table td{vertical-align:top;}
table{width:100%;border-collapse:collapse;border-bottom:2px solid %black%;border-top:3px solid %black%;}
.settings input,.post inpiut{border:none!important;}
.post table img{max-width:10rem !important;}
td{padding-left:0.1em;padding-right:0.1em;}
td:first-child{padding-left:0;}
td:last-child{padding-right:0;}
tbody tr:hover{box-shadow:inset 0 -2px 0 0px %black%;}
thead{box-shadow:inset 0 -1px 0 0px %black%;}
.post table{font-size:0.85em;}
.interesting_tbody{background:linear-gradient(90deg, %white%ff, %white%88 20em);}
.interesting_tbody td{display:contents;}
.interesting_tbody tr{position:relative;scroll-margin:4.5em}
.interesting_tbody td>*{display:table-cell;}
.interesting_tbody td>.wscroll{display:none !important;}
.interesting_tbody .post_access{padding-top:0;}
.interesting_tbody .post_menu_button{top:0;opacity:0;}
.interesting_tbody td>img,.interesting_tbody td>.imd{position:absolute;left:1.4em;z-index:-1;height:1em;width:20em;
display:flex;top:0.2em;object-fit:cover;max-width:calc(100% - 1.4em) !important;overflow:hidden;}
.interesting_tbody td>.imd>a{display:flex;}
.interesting_tbody img{object-fit:cover;width:100%;}
.interesting_tbody .p_row{display:flex;position:absolute;left:1.4em;top:0.25em;z-index:-1;flex-wrap:nowrap;max-width:calc(100% - 1.4em);}
.interesting_tbody .p_thumb{height:1em;}
.interesting_tbody .p_thumb img,.interesting_tbody .p_thumb video{max-height:10rem !important;max-width:20rem !important;}
tr:hover .post_menu_button{opacity:1;}
.post_current_row{background-color:%graybkg%;mix-blend-mode:screen;text-shadow:0px 0px 0.1em %white%;}
.align_right{text-align:right;}
.left{display:inline-block;vertical-align:top;width:25%;padding-right:1.5em;padding-bottom:4rem;position:sticky;top:2em;
overflow:auto;max-height:calc(100vh - 2.6em);}
.center{display:inline-block;vertical-align:top;width:50%;overflow:visible;padding-bottom:4rem;}
.center_slides{display:block;vertical-align:top;width:100%;overflow:visible;padding-bottom:4rem;font-size:5vmin;user-select:none;}
.center_slides .print_column{display:table;position:fixed;top:0;right:0;left:0;bottom:0;width:100%;height:100%;z-index:90;}
.center_slides .print_column .post{display:table-cell;vertical-align:middle;padding:5vmin !important;max-height:100vh;width:100vw;overflow:auto;}
.center_slides .active_post{background-color:%white%;}.center_slides .post{background-color:%white%;}
.center_slides .post_access{display:none;}
.center_slides .post_menu_button{display:none !important;}
.center_slides .post_width{display:block;vertical-align:middle;max-height:100vh;overflow-y:auto;overflow-x:hidden;width:100%;}
.center_slides .linked_posts{display:none;}.center_slides .ref_compact{position:relative!important;display:block!important;}
.slides_buttons{position:fixed;z-index:200;right:0.5rem;bottom:0.5rem;user-select:none;background-color:%white%aa;padding:0.5rem;font-family:monospace;}
.slides_buttons a{text-decoration: none;}
.center_slides .imd{text-align:center;pointer-events:none;}
.imd_float{float:right;width:50% !important;clear:both;margin-left:0.5em !important;}
.center_wide{display:inline-block;vertical-align:top;width:75%;padding-left:0.3em;overflow:visible;padding-bottom:4rem;}
.center_full{display:inline-block;vertical-align:top;width:100%;overflow:visible;padding-bottom:4rem;}
.center_wide .p_thumb{height:12rem;width:12rem;margin:0;margin-right:0.5rem;margin-bottom:0.5rem;box-shadow:5px 5px 15px 2px black;}
.linked_posts{padding:0.5em;background-color:#0004;box-shadow:0px 0.2em 0.2em -0.2em inset %shadow%;}
.active_post .linked_posts{background-color:%highlight_slice%;}
input:checked~.linked_posts,input:checked~a{display:none;}
.bkg_recent>.post,.bkg_section{background:%post_white%;box-shadow:0em 0em 0.5em %shadow%;margin-bottom:0.5em;}
.bkg_recent>.post>.post_width :last-child{margin-bottom:0;}
.sticky_title{position:sticky;top:calc(1.6rem + 2px);z-index:1;background-color:%white%;pointer-events:none;}
.center_exp{display:block;width:80%;margin:0 auto;overflow:visible;padding-bottom:1em;}
.table_top{position:relative;left:calc(-50% - 0.45em);width:calc(200% + 0.6em);background:%white%;z-index:1;
box-shadow:0px 0px 2em 1em %white%;margin-top:2em;margin-bottom:2em;}
textarea,input[type=text],input[type=password]{font-family:monospace;width:100%;display:block;font-family:inherit;max-height:60vh;font-size:inherit;}
select,textarea,input[type=text],input[type=password]{font-family:monospace;background:none;border:none;border-bottom:1px solid %black%;color:%black%;}
.text_highlight input{border-bottom:1px solid %white%;color:%white%;}
.button{background:none;border:none;font-family:inherit;color:%black%;font-size:inherit;font-weight:bold;}
.post{position:relative;scroll-margin:3.5em;}
.active_post{background-color:%highlight_white%;}.active_post .post_access{background-color:%highlight_slice%;}
.center_exp .post{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;}
.post li,.footer_additional li,.footer_additional li,.post_dummy li
{display:list-item;margin-left:1em;list-style:disc;}
.post li li,.footer_additional li li,.footer_additional li li,.post_dummy li li
{list-style:circle;}
ol li{list-style:unset !important;}
.post_width > *,.post_dummy > *,.post_ref > *{margin:0;margin-bottom:0.5rem}
.post > td:nth-child(3) > *{margin:0;margin-bottom:0.5rem}
.post_dummy > *{width:60%;margin:0 auto;margin-bottom:0.5rem}
.post_dummy > p img{display:block;width:100%;margin:0 auto;}
.gallery_left li{display:list-item;margin-left:1em;list-style:none;}
.gallery_left .selected{list-style:'→';}
.bkg_section .post_width{padding-top:0;padding-bottom:0;}
.bkg_section .restart+.post .post_width{padding-top:0.5em;}
.post_width{display:inline-block;margin-left:0.5em;vertical-align:top;}
.opt_compact .post_width,.ref_compact .post_width{padding-top:0;padding-bottom:0;}
.p_thumb .post_menu_button{right:0.3rem;top:0.3em;}
.post_menu_button{position:absolute;display:none;right:0rem;width:1.5rem;box-shadow:0px 0px 3px %shadow%;
text-align:center;border-radius:0.3em;user-select:none;cursor:pointer;z-index:10;background-color:%post_white%aa;}
.pointer{cursor:pointer;}
.post:hover .post_menu_button{display:block;}
.pop_menu{position:absolute;top:0.3rem;z-index:95;background-color:%grayslice%;
padding:0.3em;right:0.3rem;text-align:right;border-radius:0.3em;font-size:1rem;
box-shadow:0px 0px 10px %shadow%;}
.pop_menu li{list-style:none;margin-left:0;}
.pop_menu hr{border:2px solid rgba(0,0,0,0.1);}
.toc{left:60%;width:40%;top:0;position:absolute;}
.paa{width:1.4rem;min-width:1.4rem;}
.opt_compact .post_access,.ref_compact .post_access{border-right:2px solid %gray%;background-color:%post_white%;right:unset;left:-2em;}
.active_post .opt_compact .post_access,.active_post .ref_compact .post_access{background-color:%highlight_white%;}
.post_preview{overflow:hidden;margin-bottom:0.4em;background-color:%white%aa;box-shadow: 0px 0px 0.2em %shadow%;}
.post_preview:hover{filter:contrast(90%);}
.active_post .post_preview:hover{filter:contrast(90%);}
.hide_long{max-height:12em;overflow:hidden !important;}
.post .post_ref{margin:0;padding-left:1.5rem;}
.post_ref_main{display:inline-block;vertical-align:top;max-height:6em;overflow:hidden;margin:0.4em;}
.post_ref_images{overflow:hidden;margin:0.4em;margin-top:0;}
.post_ref_hint{text-align:right;}
.page_selector{padding-top:2rem;text-align:center;}
.smaller{font-size:0.85em;} .bigger{font-size:1.3em;} .block{display:block;}
.restart{text-align:left;padding-top:1rem;padding-bottom:0.5rem;}
.opt_compact{margin-left:2rem;}
.post_box_top{padding-bottom:0.3em;padding-top:0.3em;}
.post_box_fixed_bottom{position:sticky;bottom:0em;background-color:%white%;z-index:5;}
.spacer{height:0.5em;}
.pop_right,.pop_right_big{position:fixed;top:0;right:0;bottom:0;width:30%;z-index:100;background-color:%graybkg%;display:none;
transition-timing-function:ease-out;padding:1rem;overflow:auto;}
@keyframes pop_slide_in{0%{right:-30%;}100%{right:0%;}}
@keyframes pop_slide_out{0%{right:0%;}100%{right:-30%;}}
@keyframes pop_slide_in_big{0%{right:-30%;}100%{right:0%;}}
@keyframes pop_slide_out_big{0%{right:0%;}100%{right:-30%;}}
.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,0.5);transition-timing-function:ease-out;z-index:90;}
@keyframes backdrop_fade_in{0%{opacity:0%;}100%{opacity:100%;}}
@keyframes backdrop_fade_out{0%{opacity:100%;}100%{opacity:0%;}}
.toc_entry_1{font-size:1.1em;}
.toc_entry_2{font-size:1.0em;padding-left:0.5rem;}
.toc_entry_3{font-size:0.9em;padding-left:1rem;}
.toc_entry_4{font-size:0.85em;padding-left:1.5rem;}
.toc_entry_5{font-size:0.8em;padding-left:2rem;}
h1,h2,h3,h4,h5{scroll-margin:2.5em;}
.post h1,.post h2,.post h3,.post h4,.post h5{margin-top:1rem;}
.left ul h1,.left ul h2,.left ul h3,.left ul h4,.left ul h5,.left ul p{font-size:1em;}
.deleted_post{color:%gray%;text-decoration:line-through;}
#file_list{margin-top:0.5em;}
.file_thumb img,.file_thumb video{max-height:100%;max-width:100%;object-fit:cover;min-width:100%;min-height:100%;}
.file_thumb video{border:2px dashed %black%;}f
#file_list li{margin-bottom:0.3em;}
.ref_thumb{white-space:nowrap;overflow:hidden;}
.ref_thumb .file_thumb{width:2em;height:2em;margin:0;margin-right:0.3em}
.side_thumb li{margin:0.4em;display:inline-block;}
.file_thumb{width:4em;height:4em;display:inline-block;line-height:0;vertical-align:middle;overflow:hidden;}
.p_row{display:flex;flex-wrap:wrap;width:100%;}
.p_thumb{display:flex;flex-grow:100;height:6rem;overflow:hidden;position:relative;margin-right:0.5em;margin-bottom:0.5em;}
.p_thumb_narrow{width:1rem !important;flex-grow:1;opacity:0.2;}
.p_thumb img,.p_thumb video{object-fit:cover;max-height:100%;min-width:100%;}.p_thumb a{display:contents;}
.p_thumb:hover .post_menu_button{display:block;}
.p_thumb_selected{color:%black% !important;}
.p_thumb_selected{display:block;}
.post .p_thumb img,.post .p_thumb video{max-height:6rem;}
.p_thumb video{border-bottom:0.4em dashed %black%;border-top:0.4em dashed %black%;}
.p_thumb_end{flex-grow:10000 !important;box-shadow:none;align-items:center;padding:2em !important;}
.p_thumb_end:hover, .p_thumb_end a:hover{background-color:%gray%;cursor:pointer;}
.big_image_box{position:fixed;top:0;bottom:0;left:0;width:75%;z-index:95;text-align:center;pointer-events:none;}
.big_image_box *{pointer-events:auto;}
.big_image_box img,.big_image_box video{position:absolute;margin:auto;top:0;left:0;right:0;bottom:0;cursor:unset;}
.here_image_box{position:relative;width:100%;text-align:center;height:calc(100vh - 4.5em);}
.here_image_box img,.here_image_box video{position:absolute;margin:auto;top:0;left:0;right:0;bottom:0;cursor:unset;}
.big_side_box{position:fixed;top:0;bottom:0;right:0;width:25%;overflow:auto;z-index:98;color:%black%;padding:1rem;pointer-events:none;}
.big_side_box a,.big_side_box hr,#dropping_background{color:%black%;}
.big_side_box a:hover{color:%gray%;}
.big_side_box *{pointer-events:auto;}
.big_side_box .post_preview{border-bottom:1px dotted %black%;background-color:unset;}
.image_nav{pointer-events:none;}
#dropping_background{background-color:rgba(255,255,255,0.4);position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;text-align:center;
box-shadow:0px 0px 500px black inset;display:flex;align-items:center;}
img,video{cursor:pointer;max-height:100%;max-width:100%;vertical-align:middle;}
.post img,.post video{max-height:min(70vh, 20rem);max-width:min(100%, 20rem);}
.post > a > img,.post > a > video{display:block;margin:0.3em auto;}
.post .original_img{max-width:100%;display:inline-block;vertical-align:middle;
margin-left:auto;margin-right:auto;max-width:100%;max-height:90vh;}
.center_exp .post .original_img{display:block;}
.original_img img,.original_img video{max-height:90vh;max-width:100%;}
.p_row .original_img{margin-bottom:0;}
.post_ref .original_img{margin:unset;max-width:unset;max-height:min(70vh, 20rem);max-width:min(100%, 20rem);}
.imbtn{color:rgba(0,0,0,0);display:block;contain:content;padding:0.25em;margin-bottom:0.5em;text-decoration:none;}
.imbtn img{display:block;object-fit:cover;position:absolute;top:0;left:0;bottom:0;right:0;margin:auto;z-index:-1;
min-width:100% !important;min-height:100% !important;filter:opacity(70%);transition:0.1s;}
.imbtn:hover img{filter:opacity(20%) blur(0.2em);} .imbtn:hover{color:%black% !important;}
.imbtn:hover {color:%black%;text-shadow:0px 0px 5px %white%;}
header .imbtn{display:inherit;border:none;padding:0em;height:unset;height:unset;margin:0em;contain:unset;}
header .imbtn:hover{border:none;color:%gray% !important;} header .imbtn img{display:none;}
.b ul{font-size:1.4em;}
no_pop{cursor:unset;}
p{min-height:0.8em;}
.bold,.bold *{font-weight:bold;}
.footer_additional{display:inline-block;width:50%;vertical-align:text-top;white-space:normal;}
.small_footer{background-color:%white%;padding-bottom:0.5em;position:sticky;bottom:0px;z-index:10;box-shadow: 0.5em 0px %white%;}
.small_footer>div{overflow:auto;white-space:nowrap;}
.small_footer::before{content:'';position:absolute;left:0;right:0;bottom:0;height:1.95em;box-shadow:-2em 0em 1em -1em inset %white%;pointer-events:none;}
.top_post_hint{margin-left:0.5em;font-weight:bold;}
.white{color:%white%;}
.full_box{border:1px solid %black% !important;padding:0.3rem;overflow:auto;}
.image_nav_prev,.image_nav_next{z-index:100;position:absolute;line-height:0;height:50%;width:20%;top:25%;display:flex;align-items:center;
transition:background-size .2s ease;padding:0.5em;text-shadow:0px 0px 5px black;user-select:none;pointer-events:auto;}
.image_nav_prev{left:0;justify-content:left;background:linear-gradient(to left, rgba(0,0,0,0), rgba(0,0,0,0.4));
background-repeat:no-repeat;background-size:0% 100%;}
.image_nav_prev:hover,.image_nav_next:hover{background-size:100% 100%;}
.image_nav_next{right:0;justify-content:right;background:linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,0.2));
background-repeat:no-repeat;background-size:0% 100%;transition:background-size .2s ease;background-position-x:100%;}
.inquiry_buttons{position:fixed;left:0;right:25%;text-align:center;bottom:1em;margin:0 auto;width:max-content;
background-color:rgba(0,0,0,0.5);z-index:110;padding:0.2em;padding-left:1em;padding-right:1em;
border-radius:1em;box-shadow:0px 0px 5px;text-shadow:0px 0px 5px black;opacity:1;user-select:none;}
.lr_buttons{background-color:rgba(0,0,0,0.5);padding:0.5em;padding-top:1em;padding-bottom:1em;
border-radius:1em;box-shadow:0px 0px 5px;font-size:1.2rem;text-shadow:0px 0px 5px black;}
.img_btn_hidden{opacity:0;transition:opacity 0.2s;}
.special_alipay{background-color:#027aff;color:white;white-space:nowrap;
font-family:sans-serif;font-weight:bold;border-radius:0.7em;font-size:0.75em;padding:0.25em;}
.special_paypal{background-color:white;color:#253b80;white-space:nowrap;
font-family:sans-serif;font-weight:bold;border-radius:2em;font-size:0.75em;
padding:0.25em;padding-left:0.5em;padding-right:0.65em;font-style: italic;}
.special_paypal_inner{color:#169bd7;}
#waiting_bar{position:fixed;z-index:200;top:0;left:0;right:0;height:0.2em;background-color:%black%;transform:translate(-100%,0);
animation:anim_loading 1s linear infinite;}
@keyframes anim_loading{0%{transform:translate(-100%,0);} 100%{transform:translate(100%,0);}}
.product_ref{width:32%;padding:0.2em!important;display:inline-block;text-align:center;vertical-align:top;margin-bottom:0.8em;}
.product_thumb{max-height:11em;max-width:11em;display:inline-flex;margin-bottom:0.2em;background-color:%graybkg%;}
.product_thumb img,{box-shadow:none;object-fit:contain;max-height:unset;max-width:unset;width:100%;margin:0 auto !important;}
.product_ref p{margin-bottom:0.2em;text-align:left;}
.post_preview .product_thumb{max-height:4em;max-width:6em;}
.purchase_button{background-color:%black%;color:%white%;padding-left:0.5em;padding-right:0.5em;text-decoration:none;font-weight:bold;}
.page_break{page-break-after:always;}
.text_highlight,.text_highlight a,.text_highlight select{background-color:%black%;color:%white%;border:none;}
.gray.text_highlight,.gray.text_highlight a,.gray.text_highlight select{background-color:%gray%;color:%white%;}
.show_on_print{display:none;}.inline_print{display:none;}
.comment{font-size:0.9em;font-family:sans-serif;overflow:auto !important;width:100%;}
.comment tbody tr:hover{box-shadow:none;}
.comment table{border:none;}
.comment li{display:list-item;list-style:'→';padding-left:0.3em;}
.comment ul{padding-left:1em;}
.comment ul li *{margin-bottom:0.5em;}
.history li{display:list-item;list-style:disc;padding-left:0.3em;}
.history li li{list-style:circle;}
.history ul{padding-left:1em;}
.history a{text-decoration:underline;}
.history .list{overflow:auto;white-space:nowrap;}
.diff_table{table-layout:fixed;}
.diff_table thead{font-size:0.9em;text-align:center;}
.diff_table tbody pre{font-size:0.9rem;white-space:pre-line;}
.diff_table td{vertical-align:top;}
.omittable_title{display:block;width:100%;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}
.wayback_close{float:right;}
.wayback_expand{display:inline;}
.post_selecting .post>*>*{pointer-events:none;}
.post_selected{background-color:%graybkg%;}
.small_pad{padding:0.2em;padding-top:0.1em;padding-bottom:0.1em;}
.wscroll{scroll-margin:3.5em;padding-left:0.3em;display:none;font-weight:bold;font-size:0.75em;box-shadow: 13em 0em 4em -8em inset %gray%;color:%white%;}
.wscroll:target{display:block;} .post_ref .wscroll{display:none !important;}
.wayback_link{display:inline;}
.imd{object-fit:cover;width:100%;}
.center_exp .post>.imd,.center_exp .p_row{width:60%;}
.center_exp .p_thumb img,.center_exp .p_thumb video{max-height:3rem;}
.center_exp .p_thumb{max-height:3rem;filter:opacity(40%);}
.center_exp .p_thumb:hover{filter:unset;}
#here_buttons{display:contents;}
.here_buttons_inner{position:absolute;margin:auto;top:0;left:0;right:0;bottom:0;max-height:100%;max-width:100%;}
.here_btn{position:absolute;z-index:110;transform:translate(-50%,-50%);
width:2em;height:2em;display:block;border:1px solid %black%;background-color:rgba(0,0,0,0.5);}
.round_btn{box-shadow: 0px 0px 0px 1px inset %black%;display:inline-block;padding-left:0.4em;padding-right:0.4em;border-radius:0.5em;}
.center .center{width:100%;padding-bottom:unset;}
.center{border:none;}
.center{overflow:auto;}
.center>tbody>tr:hover{box-shadow:none;}
.center>tbody>tr>td{white-space:normal;vertical-align:top;min-width:1em;}
.center>tbody>tr>td:first-child{text-align:center;color:%gray%;padding-left:0.1em;}
.center>tbody>tr>td:nth-child(1)>*{}
.center>tbody>tr>td:nth-child(2){text-align:center;color:%gray%;}
.center>tbody>tr>td:nth-child(2) a{color:%gray%;}
.center>tbody>tr>td:nth-child(2) .marked{color:%black% !important;}
.center>tbody>tr>td:nth-child(3){width:100%;text-align:left;}
.center>tbody>tr>td:nth-child(3)>div{overflow:auto;}
.center>tbody>tr>td:last-child{padding-right:0.5em;}
.main>.center>tbody>tr{border-bottom:1px dotted %black%;}
.ref_count{cursor:pointer;} td .ref_count{text-align:left;display:block;}
.big_side_box .center{width:100%;}
#big_image_upload{max-width:100%;}
label{text-align:left;display:inline-block;}
@media screen and (max-width:1000px) and (min-width:666px){
.left{width:35%;}
.center,.center_wide{width:65%;}
.center_wide .p_thumb{height:8rem;width:8rem;margin-right:0.4rem;margin-bottom:0.4rem;box-shadow:3px 3px 12px 2px black;}
.post_width{width:calc(100% - 1.5rem);padding-left:0.2em;}
.hidden_on_wide{display:unset;}
.pop_right{width:30%;}
.pop_right_big{width:40%;}
@keyframes pop_slide_in{0%{right:-30%;}100%{right:0%;}}
@keyframes pop_slide_out{0%{right:0%;}100%{right:-30%;}}
@keyframes pop_slide_in_big{0%{right:-40%;}100%{right:0%;}}
@keyframes pop_slide_out_big{0%{right:0%;}100%{right:-40%;}}
.big_side_box{width:35%;}
.big_image_box{width:65%;}
.inquiry_buttons{right:35%;}
.table_top{left:calc(-50% - 1.7em);width:calc(154% + 0.5em);}
.post_dummy > *{width:80%;max-width:55rem;}
.center_exp .post>.imd,.center_exp .p_row{width:80%;max-width:55rem;}
.here_btn{width:1.5em;height:1.5em;}
}
@media screen and (max-width:666px){
.main{top:unset;margin-bottom:unset;}
html{font-size:16px;}
pre{max-width:85vw;}
#titlectrl:checked ~ header .mobile_fold{display:block !important;}
#titlectrl:checked ~ .main .mobile_fold{display:block !important;}
#titlectrl:checked ~ header li ul{display:inline;}
.mobile_fold{display:none !important;}
.hidden_m{display:none !important;}
.block_m{display:block !important;}
.hidden_on_desktop{display:inherit;}
.hidden_on_wide{display:inherit;}
header{position:inherit;}
header ul{display:block;}
header li{display:block;}
header li::before{content:''}
header::before{box-shadow:none;display:none;}
.small_footer::before{box-shadow:none;display:none;}
.left{position:relative;width:100%;top:unset;height:unset;max-height:unset;padding-right:0;display:block;}
.center,.center_wide,.center_full{display:block;position:relative;line-break:anywhere;left:0;top:0;width:100%;padding-left:0;}
.center_wide .p_thumb{height:6rem;width:6rem;margin-right:0.3rem;margin-bottom:0.3rem;box-shadow:2px 2px 10px 1px black;}
.pop_right,.pop_right_big{top:unset;right:0;bottom:0;left:0;width:100%;}
.pop_right{height:30%;}
.pop_right_big{height:70%;}
@keyframes pop_slide_in{0%{bottom:-30%;}100%{bottom:0%;}}
@keyframes pop_slide_out{0%{bottom:0%;}100%{bottom:-30%;}}
@keyframes pop_slide_in_big{0%{bottom:-70%;}100%{bottom:0%;}}
@keyframes pop_slide_out_big{0%{bottom:0%;}100%{bottom:-70%;}}
.big_image_box{position:fixed;top:0;bottom:8.5rem;left:0;right:0;width:100%;}
.side_box_mobile_inner{background:linear-gradient(to bottom, rgba(0,0,0,0), rgba(1,1,1,0.9) 20%);
transition:none;background-size:100% 100%;padding:0.5rem;padding-bottom: 5em;}
.side_box_mobile_inner:hover{background-size:100% 100%;}
.big_side_box{position:fixed;top:0;bottom:0;right:0;left:0;width:100%;
height:unset;padding:0;padding-top:calc(100vh - 8.5rem);background:none;}
.p_thumb{height:3rem;}
.center .post{padding-right:0rem;padding-left:0rem;}
.post .p_thumb img,.post .p_thumb video{max-height:3rem;}
.page,.page_gallery{padding:0.2em;padding-top:0;}
header{padding-top:0.3em;}
.toc_button{top:0.3em;}
.small_footer{padding-bottom:0.3em;}
.footer_additional{display:block;width:100%;}
.album_hint{display:block;font-size:1rem;}
.image_nav{position:absolute !important;}
.image_nav_prev,.image_nav_next{width:25%;}
.image_nav_prev:hover,.image_nav_next:hover{background-size:0% 100%;color:%black% !important;}
.inquiry_buttons{position:relative;left:unset;right:unset;text-align:left;bottom:unset;margin:unset;width:unset;
background-color:unset;z-index:unset;padding:unset;padding-left:unset;padding-right:unset;
border-radius:unset;box-shadow:unset;text-shadow:unset;}.img_btn_hidden{opacity:1;}
.lr_buttons{background-color:unset;padding:unset;padding-top:unset;padding-bottom:unset;
border-radius:unset;box-shadow:unset;font-size:1.3rem;text-shadow:unset;}
.opt_compact,.ref_compact{line-break:anywhere;}
.table_top{left:unset;width:100%;overflow:auto;}
.post table img{max-width:30vw !important;}
.product_ref{width:100%;display:block;}
.post_dummy > *{width:100%;max-width:25rem;}
.center_exp .post>.imd,.center_exp .p_row{width:100%;max-width:25rem;}
.center_exp .post .p_thumb img,.center_exp .post .p_thumb video{max-height:2rem;}
.center_exp .p_thumb{height:2rem;filter:opacity(40%);}
.center_exp .p_thumb:hover{filter:unset;}
.sticky_title{top:0;}
.small_footer{position:relative;}
#upload_selector{width:100%;}
.interesting_tbody{background:linear-gradient(90deg, %white%ff, %white%88 10em);}
.wayback_expand{display:block;text-align:center;}
.wayback_link{display:block;}
.center_exp{display:block;width:100%;margin:0 auto;padding-bottom:1em;}
.center_exp .post{overflow:auto;}
.center_exp .imd{width:100%;}
.here_btn{width:1.2em;height:1.2em;}
.exp_h_f{height:unset !important;}
.exp_f{margin-bottom:1em;}
.linked_posts{padding-left:1em;}
.center>tbody>tr>td{min-width:unset;}
.center>tbody>tr>td:last-child{padding-right:0.1em;}
}
@media print{
.small_footer .hidden_on_print{display:none}
header b,.small_footer b{font-weight:normal;}
header{display:table-header-group;box-shadow:none;} .main{display:table-row-group;top:unset;margin-bottom:unset;} .small_footer{text-align:right;}
header::before{box-shadow:none;display:none;} header::after{display:block;height:1em;content:' ';}
.small_footer::before{box-shadow:none;display:block;height:1em;position:relative;}
body,footer,header,.small_footer,a,.clean_a,.invert_a,.clean_a a,.invert_a a{background:none;color:black;}
.bkg_section,.bkg_recent>.post,.active_post{background:none !important;box-shadow:none;}
.post *,.post_dummy *{margin-bottom:0em;}
.p_row,.post table,.post img,.post_ref img,.post_ref .original_img,
.post_width>.original_img,.post pre{margin-top:0.5rem;margin-bottom:0.5rem;text-indent:0;}
pre{white-space:pre-wrap;line-break:anywhere;}
.post p{line-height:1.3;text-indent:2em;} .product_ref p {text-indent:0;}
.post table img{margin:0 !important;}
.post h1+p,.post h2+p,.post img+p,.post video+p,.post .imd+p,.post table+p,.last_wide p:first-of-type{text-indent:0;}
.post ul,.post ol{margin:0.5rem !important;margin-left:1.4rem !important;margin-right: 0rem !important;}
table{border-bottom:2px solid black;border-top:2px solid black;}
.post table img{max-width:5em;max-width:8em !important;max-height:8em !important;}
thead{box-shadow:inset 0 -1px 0 0px black;background:none;}
.linked_posts{display:none;}
.post_width{overflow:clip;left:0;width:100%;padding-left:0em;padding-right:0em;}
.section .post h2{font-size:1.8em;margin:1.5em auto 0 !important;}.list h2,.compact h2{margin:0 !important;}
.section .post h3{font-size:1.5em;margin:1.0em auto 0 !important;}.list h3,.compact h3{margin:0 !important;}
.section .post h4{font-size:1.1em;margin:0.5em auto 0 !important;}.list h4,.compact h4{margin:0 !important;}
.post .post{margin-bottom:0.5rem;margin-top:0.5rem;}
.gray,.gray a,.deleted_post{color:rgba(0,0,0,0.5);}
.left{display:none;}
.center, .center_wide, .center_full{width:100%;padding:0;font-size:16px;line-height:1.3}
hr{border:1px solid black;}
.post_box_top{display:none;}
.post_access{display:none;}
.opt_compact .post_access,.ref_compact .post_access{border-right:none;display:inline;background:unset;}
.text_highlight,.text_highlight a,.gray.text_highlight,.gray.text_highlight a,.purchase_button{background-color:lightgray;color:black;}
.hidden_on_print{display:none !important;}
.print_column{column-count:2;margin-top:0.5rem;margin-bottom:0.5rem;}
.print_column .print_column{column-count:1;margin:unset;}
.opt_compact{margin-left:0;left:1.5em;}
.post .post_ref{padding-left:2rem;}
.section .post h1:first-of-type{column-span:all;display:block;margin-top:1rem !important;margin-bottom:0.5rem !important;}
.bkg_section .restart+.post .post_width{padding-top:0;}
.restart{background-color:unset;padding:unset;}
.opt_compact h1:first-of-type,.ref_compact h1:first-of-type{display:unset;}
.table_top{position:relative;left:0;width:100%;background:none;z-index:1;box-shadow:none;}
.header_nav{display:none;}
.show_on_print{display:block;}.inline_print{display:inline;}
blockquote{border-left:2px solid black;}
.footer_additional{display:none;}
.small_footer{margin-top:1rem;box-shadow:none;}
.page{display:table;width:100%;}
.page_selector{display:none;}
.p_thumb{height:4rem;margin-bottom:0.25rem;}
.post .p_thumb img,.post .p_thumb video{max-height:4rem;}
.sticky_title{box-shadow:none;}
.center_wide .p_thumb{display:inline-flex;height:5.8rem;width:5.8rem;margin-right:0;}
.center_wide .p_row{display:block;}
.interesting_tbody{background:none;}
.interesting_tbody img{display:none !important;}
.imd{margin-top:0.5em;margin-bottom:0.5em;line-height:0px;}
.p_row .imd{margin-top:0em;margin-bottom:0em;}
.center,.center>tbody,.center>tbody>tr,.center>tbody>tr>td{display:block;}
.main>.center>tbody>tr{border:none;}
.center>tbody>tr>td:first-child{display:none;color:rgba(0,0,0,0.5);}
.center>tbody>tr>td:nth-child(2){display:none;color:rgba(0,0,0,0.5);}
.center>tbody>tr>td:nth-child(2) a{display:none;color:rgba(0,0,0,0.5);}
.center>tbody>tr>td:nth-child(3){margin:unset;padding:unset;}
.post > td:nth-child(3) > *{margin:unset;padding:unset;}
.wide_post_print{column-span:all;margin-top:1em;margin-bottom:1em;}
}
";
        //$this->style=preg_replace('/%highlight_white%/','#5b3607',$this->style);
        //$this->style=preg_replace('/%highlight_slice%/','#734307',$this->style);
        //$this->style=preg_replace('/%grayslice%/','#442c0b',$this->style);
        //$this->style=preg_replace('/%post_white%/','#2d2110',$this->style);
        //$this->style=preg_replace('/%white%/','#231a0d',$this->style);
        //$this->style=preg_replace('/%black%/','#f8ca9b',$this->style);
        //$this->style=preg_replace('/%gray%/','#ac7843',$this->style);
        //$this->style=preg_replace('/%graybkg%/','#39270e',$this->style);
        //$this->style=preg_replace('/%shadow%/','#000000cc',$this->style);
        
        $this->style=preg_replace('/%highlight_white%/','#804a06',$this->style);
        $this->style=preg_replace('/%highlight_slice%/','#ae6407',$this->style);
        $this->style=preg_replace('/%grayslice%/','#6a491c',$this->style);
        $this->style=preg_replace('/%post_white%/','#4a3413',$this->style);
        $this->style=preg_replace('/%white%/','#2d2214',$this->style);
        $this->style=preg_replace('/%black%/','#f8ca9b',$this->style);
        $this->style=preg_replace('/%gray%/','#f8ca9b88',$this->style);
        $this->style=preg_replace('/%graybkg%/','#a9270e',$this->style);
        $this->style=preg_replace('/%shadow%/','#000000ee',$this->style);
        $f = fopen('styles/main.css','w');
        fwrite($f,$this->style);
        fclose($f);
    }
    
    function GiveSafeEMail(){
        return preg_replace('/\./u','[dot]',preg_replace('/\@/u','[at]',$this->EMail));
    }
    
    function &FindImage($name, $loose=false){ if(!isset($name) || !$name){ return $this->NULL_IMAGE; }
        if(isset($this->Images[0])) foreach($this->Images as &$im){
            if($loose) { if(preg_match('/'.preg_quote($name).'/u',$im['name'])) return $im; }
            else { if($im['name']==$name) return $im; }
        }
        return $this->NULL_IMAGE;
    }
    
    function &GiveImageInHere($rand=false){
        $this->ReadImages(); $this->DetectPageType();
        $album = $this->PageType=='here'?$this->HereAlbum:$this->ExpAlbum;
        if(!isset($album) || !$album){
            if(isset($this->Images[0])) return $this->Images[0]; else return $this->NULL_IMAGE; }
        $imlist=[]; $imlist_fallback=[];
        if(isset($this->Images[0])){
            foreach($this->Images as &$im){
                if(isset($im['galleries'][0]) && in_array($album,$im['galleries']) && $this->CanShowImage($im)){
                    if(!$rand) return $im; else {
                        $imlist_fallback[] = $im;
                        if(!in_array($im['name'],$this->VisitedHere)) $imlist[] = $im;
                    }
                }
            }
        }
        if(!$rand || !isset($imlist_fallback[0])) return $this->NULL_IMAGE;
        if(sizeof($imlist)){
            $r = random_int(0, sizeof($imlist)-1);
            return $imlist[$r];
        }else{
            $r = random_int(0, sizeof($imlist_fallback)-1);
            return $imlist_fallback[$r];
        }
    }
    
    function ImageTitle($im){
        $imtitle = (isset($im)&&isset($im['title']))?$im['title']:NULL;
        if(isset($im['parent'])&&($imp = &$this->FindImage($im['parent'],true))&&isset($imp['title'])){ $imtitle=$imp['title']; }
        
        return $imtitle;
    }
    
    function ImageHasHere(&$im, $here_name){
        if(!isset($im['here'])||!isset($im['here'][0])) return false;
        foreach($im['here'] as $h) { if($h[0] == $here_name) return true; } return false;
    }
    
    function ReadImages($clear_non_exist = false){
        $path = 'images/list.md';
        if($this->DoneReadImages){ return; }
        if(!file_exists($path)){ $f = fopen($path,'w'); fflush($f); fclose($f); }
        $c = file_get_contents($path);
        if(preg_match_all('/GALLERY\s+(\S+)(.*)$/mu', $c, $ma, PREG_SET_ORDER)) foreach($ma as $m){
            $g=[]; $g['name']=$m[1];//$g['count']=0;
            if(preg_match('/FEATURED([^;]*?);/u', $m[2], $arg)){ $g['featured']=true; }
            if(preg_match('/EXPERIMENTAL([^;]*?);/u', $m[2], $arg)){ $g['experimental']=true; }
            if(preg_match('/DESCRIPTION\s+([^;]+);/u', $m[2], $arg)){ $g['description']=$arg[1]; }
            $this->Galleries[] = $g;
        }
        if(preg_match_all('/^-\s*([^;]+)\s*?;\s*?(.*)$/mu', $c, $ma, PREG_SET_ORDER)) foreach($ma as $m){
            $name = trim($m[1]);
            $item = []; $item['file'] = 'images/'.$name; $item['name'] = $name;
            if(file_exists('images/thumb/'.$name)){$item['thumb']='images/thumb/'.$name;}else{$item['thumb']='images/'.$name;}
            if(preg_match('/REFS\s+([^;]*);/u',$m[2],$refs) && preg_match_all('/[0-9]{14}/u',$refs[1],$rs, PREG_SET_ORDER)){
                $item['refs']=[];
                foreach($rs as $r){ if(!in_array($r[0], $item['refs'])) $item['refs'][] = $r[0]; }
            }
            if(preg_match('/GAL\s+([^;]*);/u',$m[2],$gals) && preg_match_all('/(\S+)/u',$gals[1],$ga, PREG_SET_ORDER)){
                $item['galleries']=[];
                foreach($ga as $g){ if(!in_array($g[0], $item['galleries'])) $item['galleries'][] = $g[0]; }
            }
            if(preg_match('/PRODUCT\s+([^;]*);/u',$m[2],$product)){ $item['product']=$product[1]; }
            if(preg_match('/PARENT\s+([^;]*);/u',$m[2],$parent)){ $item['parent']=$parent[1]; }
            if(preg_match('/TITLE\s+([^;]*);/u',$m[2],$title)){ $item['title']=$title[1]; }
            if(preg_match('/ALIGN\s+([^;]*);/u',$m[2],$align)){ $item['align']=$align[1]; }
            if(preg_match('/HERE\s+([^;]*);/u',$m[2],$heres) && preg_match_all('/(\S+)-(\S+)-(\S+)/u',$heres[1],$here, PREG_SET_ORDER)){
                $item['here']=[];
                foreach($here as $h){ if(!$this->ImageHasHere($item, $h[1])) $item['here'][] = [$h[1],$h[2],$h[3]]; }
            }
            if(preg_match('/\.mp4/u',$item['name'])){
                $item['video']='video/mp4';
            }
            $this->Images[] = $item;
        }
        
        $files = array_merge([],glob('images/*.jpg'));
        $files = array_merge($files,glob('images/*.jpeg'));
        $files = array_merge($files,glob('images/*.png'));
        $files = array_merge($files,glob('images/*.gif'));
        $files = array_merge($files,glob('images/*.mp4'));
        if(isset($files[0]))foreach($files as $file) {
            if(preg_match('/[0-9]{14,}\.(jpg|jpeg|gif|png|mp4)/u', $file, $m)) {
                $name = trim($m[0]);
                if(!$this->FindImage($name)){
                    $item = []; $item['name']=$name; $item['file'] = 'images/'.$name;
                    if(file_exists('images/thumb/'.$name)){$item['thumb']='images/thumb/'.$name;}else{$item['thumb']='images/'.$name;}
                    $this->Images[] = $item;
                }
            }
        }
        if($clear_non_exist){
            if(isset($this->Images[0]) && isset($files[0])){
                foreach($this->Images as &$im){
                    if(!in_array($im['file'],$files)){
                        $im['deleted'] = 1;
                    }
                }
            }
        }
        function cmpf($a, $b){
            if ($a['name'] == $b['name']) return 0;
            return (($a['name'] > $b['name']) ? 1 : -1);
        }
        function cmpaf($a, $b){
            if ($a['name'] == $b['name']) return 0;
            return ($a['name'] > $b['name']) ? -1 : 1;
        }
        if(isset($this->Galleries[0]))usort($this->Galleries,"cmpf");
        if(isset($this->Images[0]))usort($this->Images,"cmpaf");
        $this->DoneReadImages = 1;
    }
    
    function WriteImages(){
        if(isset($this->WayBack)) return;
        $path = 'images/list.md';
        $f = fopen($path,'w');
        if(isset($this->Galleries[0]))foreach($this->Galleries as &$g){
            if(isset($g['deleted'])) continue;
            fwrite($f,'GALLERY '.$g['name']);
            if(isset($g['featured']) && $g['featured']!=false) { fwrite($f,' FEATURED;'); }
            if(isset($g['experimental']) && $g['experimental']!=false) { fwrite($f,' EXPERIMENTAL;'); }
            if(isset($g['description']) && $g['description']!="") { fwrite($f,' DESCRIPTION '.$g['description'].';'); }
            fwrite($f, PHP_EOL);
        }
        if(isset($this->Images[0]))foreach($this->Images as &$im){
            if(isset($im['deleted'])) continue;
            fwrite($f, "- ".$im['name'].'; ');
            if(isset($im['refs']) && isset($im['refs'][0])){ fwrite($f, 'REFS '.implode(" ",$im['refs'])."; "); }
            if(isset($im['galleries']) && isset($im['galleries'][0])){ fwrite($f, 'GAL '.implode(" ",$im['galleries'])."; "); }
            if(isset($im['product']) && $im['product']!=''){ fwrite($f, 'PRODUCT '.$im['product']."; "); }
            if(isset($im['parent']) && $im['parent']!=''){ fwrite($f, 'PARENT '.$im['parent']."; "); }
            if(isset($im['title']) && $im['title']!=''){ fwrite($f, 'TITLE '.$im['title']."; "); }
            if(isset($im['align']) && $im['align']!='' && $im['align']!='middle'){ fwrite($f, 'ALIGN '.$im['align']."; "); }
            if(isset($im['here']) && $im['here']!=''){ fwrite($f, 'HERE ');
                foreach($im['here'] as $here){ fwrite($f, implode('-',$here).' '); } fwrite($f, '; ');
            }
            fwrite($f, PHP_EOL);
        }
        fflush($f);
        fclose($f);
    }
    
    function EditImage($name, $link_gallery, $do_remove = false, $product_link=NULL, $rename=NULL, $parent=NULL, $align=NULL){
        if(!($im = &$this->FindImage($name))) return;
        if(isset($link_gallery)){
            if($do_remove){
                if(!isset($im['galleries']) || !isset($im['galleries'][0])) return;
                foreach($im['galleries'] as $key => $g){ if ($g==$link_gallery) unset($im['galleries'][$key]); }
                $im['galleries'] = array_merge($im['galleries']);
            }else{
                if(!isset($im['galleries'])) $im['galleries']=[];
                foreach($im['galleries'] as &$g){ if ($g==$link_gallery) return; }
                $im['galleries'][]=$link_gallery;
            }
        }
        if(isset($product_link)){
            if($product_link!=''){$im['product']=$product_link;}
            else{unset($im['product']);}
        }
        if(isset($rename) && $rename!=$im['name']){
            $ext=pathinfo($im['file'],PATHINFO_EXTENSION);
            rename($im['file'], 'images/'.$rename.'.'.$ext);
            if(isset($im['thumb'])) rename($im['thumb'], 'images/thumb/'.$rename.'.'.$ext);
            $im['name'] = $rename.'.'.$ext; 
        }
        if(isset($parent) && $parent!=$im['parent']){
            if($parent==''){ unset($im['parent']); }
            else{ $im['parent'] = $parent; }
        }
        if(isset($align) && in_array($align,['top','middle','bottom'])){
            if($align=='middle'){ unset($im['align']); }
            else{ $im['align']=$align; }
        }
        $this->NeedWriteImages = 1;
    }
    
    function RegenerateThumbnails(){
        $glob = glob('images/*.jpg');
        if(!is_dir('images/thumb')) mkdir('images/thumb');
        foreach($glob as $file) {
            $thumb_destination = 'images/thumb/'.basename($file);   
            $img = new Imagick($file); $geo=$img->getImageGeometry();
            $width=$geo['width']; $height=$geo['height'];
            $lim=400;
            $scale = $lim / min($width,$height);
            if($scale<1){
                $img->resizeImage($width*$scale,$height*$scale,imagick::FILTER_GAUSSIAN,0.7);
            }
            $img->setImageFormat('jpeg');
            $img->setInterlaceScheme(Imagick::INTERLACE_PLANE);
            $img->setImageCompressionQuality(90);
            $img->writeImage($thumb_destination);
        }
    }
    function CleanupImageCompression($run=false){
        $glob = glob('images/*.jpg');
        if(!$run){
            echo $this->T("将重新压缩下列文件:")."
".$this->T("链接位置")."
",$replacement); $replacement = preg_replace_callback("/(```|`)([^`]*)(?1)/U", function($matches){ $rep = preg_replace('/-@>/','->',$matches[0]); $rep = preg_replace('/<@-/','<-',$rep); $rep = preg_replace('/=@>/','=>',$rep); $rep = preg_replace('/<@=/','<=',$rep); $rep = preg_replace('/\R@([+]{3,})\R/',PHP_EOL.'$1'.PHP_EOL,$rep); $rep = preg_replace('/\[@-/','[-',$rep); $rep = preg_replace('/\{@/','{',$rep); $rep = preg_replace('/(en|zh|any)@\|(en|zh|any)/','$1|$2',$rep); return $rep; }, $replacement); $replacement = preg_replace_callback("/(\!\[.*?\]\(\s*images\/([0-9]{14,}\.(jpg|jpeg|png|gif))\))(\R*(\R.+){1,})/u", function($matches) use (&$post_for_it_is_here){ $rep = preg_replace("/(-|\*)\s+here\s*:\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s+images\/([0-9]{14,}\.(jpg|jpeg|png|gif))/u","", $matches[4]); return $matches[1].$rep; }, $replacement); return $replacement; } function CanShowPost(&$p){ if(!isset($p) || isset($p['comment_to'])) return false; $is_mark_exp = (isset($p['tid'])&&isset($p['tid']['exp'])&&$p['tid']['exp']) || (isset($p['mark_value'])&&$p['mark_value']==6); $is_mark_slf = (isset($p['tid'])&&isset($p['tid']['slf'])&&$p['tid']['slf']) || (isset($p['mark_value'])&&$p['mark_value']>=7); $is_mark_sln = (isset($p['tid'])&&isset($p['tid']['sln'])&&$p['tid']['sln']) || (isset($p['mark_value'])&&$p['mark_value']==8); if($is_mark_slf && !$this->LoggedIn){ return false; } if(isset($this->WayBack)){ if(isset($p['version'])) { if ($p['version']>$this->WayBack) return false; } else if ($p['id']>$this->WayBack) return false; } if(!$this->InExperimentalMode){ if(!$this->LoggedIn){ if($is_mark_exp) return false; return true; } if($this->NotesView && !$is_mark_sln){ return false; } return true; }else{ if($is_mark_exp) return true; return false; } } function SkipProduct(&$p){ if($this->LoggedIn) return false; return (isset($p['mark_value']) && $p['mark_value']==5); } function GetRedirect($args=NULL, $force_index=NULL){ global $INDEXPHP; $str = (isset($force_index)?$force_index:$INDEXPHP).'?'; if(isset($args['post'])) $str.='&post='.$args['post']; else if(isset($_GET['post'])) $str.='&post='.$_GET['post']; if(isset($args['gallery'])) $str.='&gallery='.$args['gallery']; else if(isset($_GET['gallery'])) $str.='&gallery='.$_GET['gallery']; if(isset($args['pic'])) $str.='&pic='.$args['pic']; else if(isset($_GET['pic'])) $str.='&pic='.$_GET['pic']; if(isset($args['settings'])) $str.='&settings='.$args['settings']; else if(isset($_GET['settings'])) $str.='&settings='.$_GET['settings']; if(isset($args['statistics'])) $str.='&statistics='.$args['statistics']; else if(isset($_GET['statistics'])) $str.='&statistics='.$_GET['statistics']; if(isset($args['extras'])) $str.='&extras='.$args['extras']; else if(isset($_GET['extras'])) $str.='&extras='.$_GET['extras']; if(isset($args['category'])) $str.='&category='.$args['category']; else if(isset($_GET['category'])) $str.='&category='.$_GET['category']; if(isset($args['history'])) $str.='&history='.$args['history']; else if(isset($_GET['history'])) $str.='&history='.$_GET['history']; if(isset($args['version'])) $str.='&version='.$args['version']; else if(isset($_GET['version'])) $str.='&version='.$_GET['version']; if(isset($args['search'])) $str.='&search='.$args['search']; else if(isset($_GET['search'])) $str.='&search='.$_GET['search']; if(isset($args['here'])) $str.='&here='.$args['here']; else if(isset($_GET['here'])) $str.='&here='.$_GET['here']; return $str; } function WriteAsNecessary(){ if(!$this->LoggedIn || isset($this->WayBack)){return;} if($this->NeedWritePosts){ $this->CachePostLinks(); $this->WritePosts(); } if($this->NeedWriteImages){ $this->WriteImages(); } if($this->NeedWriteArchive){ $this->WriteArchive(); } } function APubEnsureWebfinger($name, $host){ if(!is_dir('.well-known')) mkdir('.well-known'); if(!is_dir('.well-known/webfinger')) mkdir('.well-known/webfinger'); $f = fopen('.well-known/webfinger/index.php',"w"); $without_protocol = parse_url($host, PHP_URL_HOST); $finger = ["subject"=>"acct:".$name.'@'.$without_protocol, "links"=>[["rel"=>"self", "type"=>"application/activity+json", "href"=>$host."?apub_actor=1"]]]; fwrite($f, ""); fclose($f); if(!file_exists('.well-known/apub_public_key.pem') || !file_exists('.well-known/apub_private_key.php')){ $res = openssl_pkey_new(); $this->APubPublicKey = openssl_pkey_get_details($res)['key']; openssl_pkey_export($res, $this->APubPrivateKey); $f = fopen('.well-known/apub_public_key.pem',"w"); fwrite($f, $this->APubPublicKey); fclose($f); $f = fopen('.well-known/apub_private_key.php',"w"); fwrite($f, "".PHP_EOL.PHP_EOL.$this->APubPrivateKey); fclose($f); } } function APubInit(){ $kf = file_get_contents('.well-known/apub_private_key.php'); if($kf===false) return; preg_match("/(-----BEGIN PRIVATE KEY-----[\s\S]*)/",$kf,$ma); $this->APubPrivateKey=$ma[1]; } function APubEnsureInfo(){ if(!isset($this->APubID) || !isset($this->HostURL)) return; if(!file_exists('.well-known/apub_public_key.pem')){$this->APubEnsureWebfinger($this->APubID, $this->HostURL);} $pk = file_get_contents('.well-known/apub_public_key.pem'); //$pk = preg_replace('/\n/u','\\n',$pk); $actor = ["@context"=>["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"], "id"=> $this->HostURL."?apub_actor=1", "type"=> "Person", "name"=> $this->DisplayName, "url"=> $this->HostURL, "summary"=> "Lazy... No summary", "preferredUsername"=> $this->APubID, "inbox"=> $this->HostURL."?apub_inbox=1", "outbox"=> $this->HostURL."?apub_outbox=1", "publicKey"=> ["id"=> $this->HostURL."?apub_actor=1#main-key", "owner"=> $this->HostURL."?apub_actor=1", "publicKeyPem"=>$pk]]; $this->APubActor = json_encode($actor, JSON_UNESCAPED_SLASHES); } function APubMakeOutbox(){ $this->ReadPosts();$this->ReadImages(); $obj = ["@context"=>"https://www.w3.org/ns/activitystreams", "id"=>$this->HostURL."?apub_outbox=1", "type"=>"OrderedCollection"]; $items=[]; $i=0; foreach(array_reverse($this->Posts) as &$p){ $this->ConvertPost($p); $text = strip_tags(preg_replace('/<\/(p|blockquote|h[0-9])>/u',"\n\n",$p['html'])); $time = DateTime::createFromFormat('YmdHis', $p['id'], new DateTimeZone('+0800')); $ob = ["@context"=>"https://www.w3.org/ns/activitystreams", "type"=> "Create", "id"=> $this->HostURL."?post=".$p['id']."?apub_object=1", "published"=> $time->format('Y-m-d\TH:i:s\Z'), //"to"=> ["https://chatty.example/ben/"], "actor"=> $this->HostURL."?apub_actor=1", "to"=> ["https://www.w3.org/ns/activitystreams#Public"], "object"=> ["type"=> "Note", "id"=> $this->HostURL."?post=".$p['id'], "published"=> $time->format('Y-m-d\TH:i:s\Z'), "attributedTo"=> $this->HostURL."?apub_actor=1", "to"=> ["https://www.w3.org/ns/activitystreams#Public"], "content"=> $text]]; $items[] = $ob; $i++; if($i>20) break; } $obj['orderedItems'] = $items; $obj["totalItems"] = sizeof($items); return json_encode($obj, JSON_UNESCAPED_SLASHES); } function APubDeliver($body,$target){ $head_digest = base64_encode(hash("sha256",$body,true)); $body_digest = "SHA-256=".$head_digest; // rfc standards require the timezone be declared as GMT and PHP's built-in formats all say UTC // so we gotta do it manually $d = new DateTimeImmutable("now", new DateTimeZone('Asia/Shanghai')); $d=$d->setTimezone(new DateTimeZone('UTC')); $date=$d->format("D, d M Y H:i:s")." GMT"; $data = "(request-target): post ".parse_url($target,PHP_URL_PATH) ."\nhost: ".parse_url($target,PHP_URL_HOST) ."\ndate: $date" ."\ndigest: $body_digest"; if (openssl_sign($data, $signature, $this->APubPrivateKey, OPENSSL_ALGO_SHA256) === FALSE) { http_response_code(500); die('unable to sign'); } $signature = base64_encode($signature); $keyid = 'keyId="'.$this->HostURL.'?apub_actor=1#main-key"'; $algo = 'algorithm="rsa-sha256"'; $headers = 'headers="(request-target) host date digest"'; $signature = "signature=\"$signature\""; $h = array( 'Content-Type: application/activity+json', 'Accept: application/activity+json', //"Content-Length: ".strlen($body), "Host: ". parse_url($target,PHP_URL_HOST), "Date: $date", "Digest: $body_digest", "Signature: $keyid,$algo,$headers,$signature" ); $ch = curl_init($target); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $body); curl_setopt($ch, CURLOPT_HTTPHEADER, $h); curl_setopt($ch, CURLOPT_USERAGENT, "laMDWiki APub"); $result = curl_exec($ch); curl_close($ch); echo "";
        print_r($body); echo "\n\n".$target."\n\n";
        print_r($result); echo "\n\n"; print_r($h);
        echo "\n\n"; print_r(curl_getinfo($ch)); echo ""; exit;
        return $result;
    }
    function APubTestDeliver(){
        $this->APubInit();
        $obj=[];
        $obj['published']=gmdate("Y-m-d\TH:i:s\Z");
        $obj['id']=""; //<-------------------
        $obj['url']=$this->HostURL.""; //<-------------------
        $obj['type']='Note';
		$obj['attributedTo']=$this->HostURL."?apub_actor=1";
		$tag=[]; $tag['type']='Mention'; $tag['name']="@chengdulittlea"; $tag['href']="https://mastodon.art/users/chengdulittlea";
		$obj['tag']=[$tag];
		// must have cc to have notification in mastodon.
		$obj['cc']=["https://mastodon.art/users/chengdulittlea"];
		$obj['content']="@chengdulittlea Hello activitypub from laMDWiki!
"; $obj['to']="https://www.w3.org/ns/activitystreams#Public"; $obj['inReplyTo']=""; //<------------------- $arr=[]; $arr['@context']="https://www.w3.org/ns/activitystreams"; $arr['id']=""; //<------------------- $arr['actor']=$this->HostURL."?apub_actor=1"; $arr['type']="Create"; $arr['to']="https://www.w3.org/ns/activitystreams#Public"; $arr['object']=$obj; $this->APubDeliver(json_encode($arr),"https://mastodon.example/inbox"); //<------------------- } function APubProcessInbox(){ $r = file_get_contents('php://input'); file_put_contents('postdump.txt',$r); } function MakeRSS(){ $this->ReadPosts();$this->ReadImages(); $posts = []; if(isset($this->UsePosts[0])){ $posts = array_reverse($this->UsePosts); $last_updated = $this->StandardTime($posts[0]['id']); }else{ $last_updated= $this->StandardTime("20000101000000"); } $author = "\s*\@.*?<\/p>/mu","",$html); $html = preg_replace("/\{\s*(REVERSED|INTERESTING|HEADER|FOOTER)\s+(.*?)\}/imu","",$html); $html = preg_replace("/\{\s*(REVERSED|NO_TIME|NO_TITLE|SLIDES)\s*\}/imu","",$html); $html = preg_replace("/\{\s*WIDE\s*\}/imu","",$html,-1,$rep_count); if($rep_count){$print_wide=true;} $images = []; $images_noclick = []; $images_orig_src_list = []; $html = preg_replace_callback( "/(
\s*|\s*)?( \s*<\/p>/u',"", $html); if($html==""){$html="   \s*<\/p>/u',"", $html);
            if (preg_match('/ ".$this->T('商品')." [\s]*]*href=[\'\"]\?post=([0-9]{14})[\'\"][^>]*>(.*)<\/a>[\s]*<\/p>/u',
            function($m){
                if(preg_match('/^\s* ".$post['product']['title']." ".$post['product']['short']." ".$post['product']['price']." \s*\{read_more\}\s*<\/p>[\s\S]*/u'," [".$this->T("阅读更多")."] \s*\{read_more\}\s*<\/p>/u',"", $ht);
        }
        if ($strip_tags){
            $ht = strip_tags($ht,' \s*<\/p>/u',"", $ht);
            $ht = $ht;
        }
        else{
            if($generate_refs) $ht = $this->GenerateLinkedPosts($ht);
        }
        if ($strip_tags && $generate_thumbs){
            $ht="  ".$this->T("已关闭评论")."  =$this->T('话题')?> &history=1'>=$this->GetPostTitle($mver)?> =$this->T('并入这里')?>
                     ".$name.":".$mail." =$this->T('分类')?> | ".($c=='none'?$this->T('未分类'):$this->T($c))." "; } ?> =$this->T('引用')?>:   ]*)src=[\'\"])(images\/([0-9]{14,}\.(jpg|png|jpeg|gif|mp4)))([\'\"][^>]*)\/>(\s*<\/p>)?/u",
                    function($m) use (&$images,&$images_noclick,&$images_orig_src_list) {
                        if(isset($m[1])&&$m[1]&&$m[1][1]=='a'){ $height="";
                            if(preg_match("/([0-9]{1,2})em/u",$m[0],$hm)){$height=' style="height:'.$hm[1].'em;"';}
                            return "FindImage($m[5]))!=NULL && isset($im['thumb'])){ 
                            $src = $im['thumb']; $orig_src=$im['file'];
                        }if($im == NULL){ $im = &$this->NULL_IMAGE_DUMMY; }
                        $media_start = $m[2];
                        $media_end = $m[7];
                        $dataset = " data-imgsrc='".$m[5]."'".
                                    (isset($im['product'])?" data-product='".$im['product']."'":"").
                                    (isset($im['parent'])?" data-parent='".$im['parent']."'":"").
                                    (isset($im['align'])?' data-align="'.$im["align"].'" style="object-position:'.$im['align'].';"':"").
                                    ($original?" class='original_img'":"");
                        if(isset($im['video']) && isset($im['video'])!=''){
                            $media_start = "InHereMode){
                            $click = "";
                            $ret=""; if($keep) { $ret = $click; }
                            else { $images[] = $click; }
                            return $ret;
                        }else{
                            $click ="";
                            $images_noclick[]=$media_start.$src.$media_end.">"; $images_orig_src_list[]=$orig_src;
                            $ret = "";
                            if($keep) { $ret = $click; }
                            else { $images[] = $click; }
                            if(isset($m[1])&&isset($m[8])&&$m[1]&&$m[8]) return $ret;
                            else return ((isset($m[1])&&$m[1]?$m[1]:"").$ret.(isset($m[8])&&$m[8]?$m[8]:""));
                        }
                    },$html,-1,$count);
        $html = preg_replace('/
";
        foreach(array_reverse($p['refs']) as &$pr){
            $po = $this->GetPost($pr);
            if(!$this->CanShowPost($po)){ continue; } $count++;
            $this->TBackup();
            $this->MakeSinglePostV2($po, false, true, 0, true, true, false, false, true, false, false);
            $STR.=$this->TRestore(" compact");
        }
        $STR.="";
        $is_wide = (isset($post['wide'])&&$post['wide']) || ($is_thread && isset($post['tid']['wide']) && $post['tid']['wide']);
        if($is_thread){ $th = $post['tid']; $STR.=$this->T('话题'); }else{ $STR.=$this->T('话题');$this->T('详细'); } $STR.="
";
        $this->TFill(2,$STR); $this->TExtra("class='hidden_on_print'"); $this->TRow();
        $cat = NULL;
        if($is_thread) { if(isset($th['categories']) && isset($th['categories'][0])){ $cat = $th['categories']; } }
        else { if(isset($post['categories']) && isset($post['categories'][0])) { $cat = $post['categories']; } }
        $this->MakePostTools();
        if($cat){ $STR=<<
"; $this->TFill(2,$STR); $this->TRow(); $is_reversed=false;
        if($is_thread){ $use_arr = $th['arr']; $hinted=false;
            $last_end_wide = true; $is_reversed=$this->IsReversedThread($th);
            foreach($use_arr as &$p){$use_class="";if($p==$post){$use_class.=" active_post";}
                if($last_end_wide){$use_class.=" last_wide";}
                $make_title = ($p == $post);
                if(isset($p['restart'])){  $STR="{$p['restart']} …
";
                    }
                }
                $last_end_wide = isset($p['end_wide']) && $p['end_wide'];
            }
        }else{
            $this->MakeSinglePostV2($post,true, false,"active_post",false, false, false, true, false, false);
            $STR.='';
            $this->TFill(2,$STR); $this->TRow();
        }
        $STR="";
        $class_add=""; if(isset($post['tid']['first']['no_time'])){ $class_add=' hidden_on_print'; }
        $STR.="
".
                $this->ReadableTime(isset($post['tid']['last']['version'])?$post['tid']['last']['version']:$post['tid']['last']['id'])."
            
{$this->MakePostingFieldsV2($is_thread?$th['last']['id']:$post['id'], true)}".(isset($search_term)?$this->T('搜索'):
                                (isset($category)?("".$this->T('分类')." ".
                                    ($category=='none'?$this->T('未分类'):$this->T($category))):($this->NotesView?$this->T('笔记'):$this->T('最近')).
                                    "")).
                    "
";
        $this->TFill(2,$STR); $this->TRow();
        if(isset($search_term)){
            $STR.="".
            "".
            "";
            $this->TFill(2,$STR); $this->TRow();
        }else if(isset($category)){
            $STR.="";
            $this->TFill(2,$STR); $this->TRow();
        }else if($this->LoggedIn){
            $this->TFill(2,$STR); $this->TRow();
            $this->MakePostingFieldsV2(NULL,false);
        }
        $this->PostsPerPage=20;
        $i = 0; $last_end_wide = true;
        if(isset($this->UsePosts[0])) foreach(array_reverse($this->UsePosts) as &$p){
            if(!$this->CanShowPost($p) || $this->SkipProduct($p)) continue;
            if(isset($p['tid'])){ /* Should always be set. */
                $th = &$p['tid']; if($p['tid']['count']==0) continue;
                if(!isset($search_term)) { $p = &$th['last']; }
            }
            if(isset($search_term)){
                if ($search_term=='' || !preg_match("/".preg_quote($search_term)."/iu", $p['content'])) continue;
            }else if(isset($category)){
                $cat = isset($p['tid'])?(isset($p['tid']['categories'])?($p['tid']['categories']):[]):
                                        (isset($p['categories'])?($p['categories']):[]);
                if ($category=='none') { if($cat!=[]) continue; }
                else{ if ($category=='' || !in_array($category, $cat)) continue; }
                if(isset($p['tid'])){ if(isset($p['tid']['displayed'])) continue; $p['tid']['displayed'] = True; }
            }else{
                if(in_array($p['id'],
                    [$this->SpecialPinned,$this->SpecialPinnedNotes,$this->SpecialFooter,$this->SpecialFooter2,$this->SpecialNavigation,$this->SpecialSidebar])) continue;
                if(isset($p['tid'])){ if(isset($p['tid']['displayed'])) continue; $p['tid']['displayed'] = True; }
            }
            if($i < $this->PostsPerPage * $this->CurrentOffset) {$i++; continue;}
            if($last_end_wide){$use_class="last_wide";}else{$use_class="";}
            $this->MakeSinglePostV2($p, true, false, $use_class, false, !isset($search_term), false, false, false, false, isset($search_term));
            $i++;
            if($i >= $this->PostsPerPage * (1+$this->CurrentOffset)) {break;}
            $last_end_wide = sizeof($p['tid']['arr'])==1 && isset($p['end_wide']) && $p['end_wide']; 
        }
        $STR=""; $EXTRA="class='clean_a'"; $STR.="
".
        "CurrentOffset>0?("href='".$INDEXPHP."?offset=".($this->CurrentOffset-1).
                    (isset($search_term)?"&search=".$search_term:(isset($category)?"&category=".$category:""))."'"):"").
            ($this->CurrentOffset==0?" class='gray'":"").">{$this->T('上一页')} ← ";
        $STR.=" [ ".($this->CurrentOffset+1)." ] ";
        $STR.="".
            " → {$this->T('下一页')}";
        $this->TFill(0,$STR,3); $this->TExtra($EXTRA); $this->TRow();
    }
    function GeneratePage($is_section=false,$extra_classes=""){ $S="";
        $S.=""; 
        foreach($this->PAGE as $r){ $S.="
";
        return $S;
    }
    
    function GenerateLinkedPosts($ht){
        $ht = preg_replace_callback('/"; $spantotal=0; $sp="";
                if(isset($r['span0'])){$sp=" colspan='".$r['span0']."'"; $spantotal+=$r['span0']; }else{ $spantotal++; };
                if($spantotal<=3){ $S.=" ";
        }
        $S.=""; if(isset($r[0])){ $S.=$r[0]; } $S.=" "; }
                if(isset($r['span1'])){$sp=" colspan='".$r['span1']."'"; $spantotal+=$r['span1']; }else{ $spantotal++; };
                if($spantotal<=3){ $S.=""; if(isset($r[1])){ $S.=$r[1]; } $S.=" "; }
                if(isset($r['span2'])){$sp=" colspan='".$r['span2']."'"; $spantotal+=$r['span2']; }else{ $spantotal++; };
                if($spantotal<=3){ $S.=""; if(isset($r[2])){ $S.=$r[2]; } $S.=" "; }
            $S.="GetPost($m[1], false, true);
                $STR=$this->T("未找到该引用。");
                if($rp!==NULL && $this->CanShowPost($rp)){
                    $this->TBackup();
                    $this->MakeSinglePostV2($rp, false, false, false, false, false, false,false, true, false, false);
                    $STR=$this->TRestore(" compact");
                }
                
                $s="".$m[2]."
');
            $ht = preg_replace('/
";
                foreach($post['images'] as $im){
                    $ht.="
".$title."
=$this->T('评论')?>
        CommentEnabled){
            echo "
"; } ?>
        
            SpecialPinned) && ($p = &$this->GetPost($this->SpecialPinned))!=NULL && !$this->CurrentOffset) &&
                   $this->CanShowPost($p)){
                    ?>MakeSinglePost($p, true, false, "active_post", false, true, false, false, false, true, false);
                    ?>
            =isset($search_term)?$this->T('搜索'):
                                (isset($category)?("".$this->T('分类')." ".
                                    ($category=='none'?$this->T('未分类'):$this->T($category))):($this->NotesView?$this->T('笔记'):$this->T('最近')).
                                    " ")?>
            
                
                
                T('搜索')?>
            
                
            LoggedIn){ ?>
                
                UsePosts[0])) foreach(array_reverse($this->UsePosts) as &$p){
                        if(!$this->CanShowPost($p) || $this->SkipProduct($p)) continue;
                        if(isset($p['tid'])){ /* Should always be set. */
                            $th = &$p['tid']; if($p['tid']['count']==0) continue;
                            if(!isset($search_term)) { $p = &$th['last']; }
                        }
                        if(isset($search_term)){
                            if ($search_term=='' || !preg_match("/".preg_quote($search_term)."/iu", $p['content'])) continue;
                        }else if(isset($category)){
                            $cat = isset($p['tid'])?(isset($p['tid']['categories'])?($p['tid']['categories']):[]):
                                                    (isset($p['categories'])?($p['categories']):[]);
                            if ($category=='none') { if($cat!=[]) continue; }
                            else{ if ($category=='' || !in_array($category, $cat)) continue; }
                            if(isset($p['tid'])){ if(isset($p['tid']['displayed'])) continue; $p['tid']['displayed'] = True; }
                        }else{
                            if(in_array($p['id'],
                                [$this->SpecialPinned,$this->SpecialPinnedNotes,$this->SpecialFooter,$this->SpecialFooter2,$this->SpecialNavigation,$this->SpecialSidebar])) continue;
                            if(isset($p['tid'])){ if(isset($p['tid']['displayed'])) continue; $p['tid']['displayed'] = True; }
                        }
                        if($i < $this->PostsPerPage * $this->CurrentOffset) {$i++; continue;}
                        if($last_end_wide){$use_class="last_wide";}else{$use_class="";}
                        $this->MakeSinglePost($p, true, false, $use_class, false, !isset($search_term), false, false, false, false, isset($search_term));
                        $i++;
                        if($i >= $this->PostsPerPage * (1+$this->CurrentOffset)) {break;}
                        $last_end_wide = sizeof($p['tid']['arr'])==1 && isset($p['end_wide']) && $p['end_wide'];
                    }?>
            
            
        GetPost($pr);
                if(!$this->CanShowPost($po)){ continue; } $count++;
                $this->MakeSinglePost($po, false, true, "post_preview invert_a", true, false, false, false, true, false, false);
            } 
            ?>
        
        InExperimentalMode){ ?>
            >=$this->T('链接')?>
            
                =$this->T('没有历史记录')?>
            =$this->T('帖子')?> '>=$title?>
        
            =$this->T('历史记录')?>
            =$this->T('帖子')?> '>=$title?>
            
            
            
GetArchiveHandle($from); if(!isset($fromah)) continue;
                    $ver = &$fromah['list'][sizeof($fromah['list'])-1];?>
                    
                GetArchiveHandle($pm); 
                    $mver = &$this->GetPost($pm); if(!isset($mver) && isset($mah)) $mver = &$mah['list'][sizeof($mah['list'])-1]; ?>
                    GetArchiveHandle($from); if(!isset($fromah)) continue;
                        $ver = &$fromah['list'][sizeof($fromah['list'])-1];?>
                        
=$this->T('版本不存在')?>
            
            =$this->T('差异')?>
            GetArchiveHandle($pm); 
                $mver = &$this->GetPost($pm); if(!isset($mver) && isset($mah)) $mver = &$mah['list'][sizeof($mah['list'])-1]; ?>
                
 =sizeof($this_ver['merged_thread'][0]);?> =$this->T('个帖子')?> 
                    
            
            =$this->T('没有更旧的版本')?>
                        =$this->T('上一个版本')?> 
                        
=$this->ReadableTime($last_ver['version'])?>=$this->T('选择的版本')?> 
=$this->ReadableTime($this_ver['version'])?>=isset($last_ver)?$last_ver['content']:""?>
=$this_ver['content']?>
&set_wayback==isset($this_ver['version'])?$this_ver['version']:$this_ver['id']?>'>=$this->T('前往该版本时间')?> ←
        
    GetArchiveHandle($this->CurrentPostID);
        $p = &$post; if(!isset($post)){ $p=&$ah['list'][0]; }
        $show_latest = isset($ah)?(!isset($ah['list'][sizeof($ah['list'])-1]['merged_into'])):true;
        ?>
        =$this->T('评论')?> (=$comment_count;?>)
            ";
                    foreach($to_post['comments'] as $p){
                        $ht = $this->GenerateSinglePost($p, false, false, false, false, false);
                        $name = isset($p['link'])?("".$p['name']."↗"):$p['name'];
                        $mail = $this->LoggedIn?(""):"";
                        echo "=$this->T('有趣')?>
                '>→
            
                    GetPost($ref);
                        if(isset($post['mark_value']) && $post['mark_value']==5){ $count_product++; continue; }
                        if(!$this->CanShowPost($po)){ continue; }
                        echo "
                LoggedIn && (!$this->InHereMode)){ ?>
                    
                        MakePostingFields($th['last']['id'], true);?>
                    
                     
                ConvertPost($p);
                    $mark_value = isset($p['mark_value'])?$this->Markers[$p['mark_value']]:-1;
                    $ref_count = isset($p['refs'])?sizeof($p['refs']):0;
                    $is_current = $p['id']==$this->CurrentPostID;
                    $is_deleted = (isset($p['mark_delete'])&&$p['mark_delete']);  ?>
                    =$this->T($header);?> 
                ' =$is_deleted?"data-mark-delete='true'":""?>
                        onDblClick='ClickImage(this)'> 
                    0){ ?>
                        
                             
                        GetPost($ref);
                            if(isset($post['mark_value']) && $post['mark_value']==5){ $count_product++; continue; }
                            if(!$this->CanShowPost($po)){ continue; }
                            echo "
            MakeCommentSection($th['first']); ?>
        
Posts) as $p){ if(!isset($p['comment_to'])) continue; if($i < $this->CommentsPerPage * $this->CurrentOffset) {$i++; continue;} $ht = $this->GenerateSinglePost($p, false, false, false, false, false); $name = isset($p['link'])?("".$p['name']."↗"):$p['name']; $post_to = $this->GetPost($p['comment_to']); $post_title = $this->GetPostTitle($post_to); if(!$post_to) $post_title = "?"; $mail = " ". "@ ". (isset($p['ip'])?$p['ip']:"?")." ";
                
                $i++;
            }
        ?>
        
". "(".$post_title.")"; echo "
".$name.":".$mail."
".$ht."