<?php
if (!defined('_GNUBOARD_')) exit;
include_once("{$board_skin_path}/db_update.php");
add_stylesheet('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">', 0);
// 5. 버전 폼 기본값 설정 (이전 게시물 값 가져오기)
if (!$write['x2_ver']) {
$row_ver = sql_fetch(" select x2_ver from {$write_table} order by wr_id desc limit 1 ");
$default_ver = $row_ver['x2_ver'];
} else {
$default_ver = $write['x2_ver'];
}
$file_count = (isset($board['bo_upload_count']) && $board['bo_upload_count']) ? $board['bo_upload_count'] : 0;
?>
<style>
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css');
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=JetBrains+Mono:wght@400;700&display=swap');
:root {
--neon-cyan: #00f2ff;
--neon-pink: #ff007a;
--neon-glow: rgba(0, 242, 255, 0.4);
--bg-black: #05060a;
--panel-bg: rgba(10, 15, 28, 0.85);
--border-color: rgba(0, 242, 255, 0.2);
}
/* 로딩 애니메이션 */
#CYBER_LOADER {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: var(--bg-black); z-index: 10000;
display: flex; flex-direction: column; align-items: center; justify-content: center;
transition: opacity 0.8s ease, visibility 0.8s;
}
.load-text { font-family: 'Orbitron'; color: var(--neon-cyan); letter-spacing: 5px; margin-bottom: 20px; font-size: 1.2rem; }
.load-bar-wrap { width: 300px; height: 2px; background: rgba(0,242,255,0.1); position: relative; overflow: hidden; }
.load-bar { width: 0%; height: 100%; background: var(--neon-cyan); box-shadow: 0 0 15px var(--neon-cyan); animation: loadingProgress 2s forwards; }
@keyframes loadingProgress { 0% { width: 0%; } 50% { width: 70%; } 100% { width: 100%; } }
/* 배경 레이아웃 */
#WRITE_WRAP {
position: relative; min-height: 100vh; background: var(--bg-black);
padding: 60px 0; font-family: 'Pretendard', sans-serif; color: #fff;
background-image:
linear-gradient(rgba(0, 242, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 242, 255, 0.05) 1px, transparent 1px);
background-size: 50px 50px;
animation: gridMove 20s linear infinite;
}
@keyframes gridMove { from { background-position: 0 0; } to { background-position: 0 50px; } }
#space-canvas { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; opacity: 0.4; }
#WRITE {
position: relative; z-index: 2;
width: calc(100% - 100px); /* 폭 100% 마진 좌우 50px */
margin: 0 50px;
animation: slideUp 1s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes slideUp { from { opacity: 0; transform: translateY(40px); filter: blur(10px); } to { opacity: 1; transform: translateY(0); filter: blur(0); } }
#fwrite {
background: var(--panel-bg); backdrop-filter: blur(15px);
border: 1px solid var(--border-color); border-radius: 4px;
box-shadow: 0 0 50px rgba(0,0,0,0.8); position: relative;
}
/* 사이버스틱 코너 장식 */
#fwrite::before, #fwrite::after {
content: ''; position: absolute; width: 20px; height: 20px;
border: 2px solid var(--neon-cyan);
}
#fwrite::before { top: -2px; left: -2px; border-right: 0; border-bottom: 0; }
#fwrite::after { bottom: -2px; right: -2px; border-left: 0; border-top: 0; }
/* 폼 헤더 */
.form-header {
padding: 30px 40px; border-bottom: 1px solid var(--border-color);
display: flex; justify-content: space-between; align-items: center;
background: linear-gradient(90deg, rgba(0, 242, 255, 0.1), transparent);
}
.form-header h2 {
margin:0; font-family: 'Orbitron'; font-size: 1.4rem; color: var(--neon-cyan);
font-weight: 900; letter-spacing: 2px; text-shadow: 0 0 10px var(--neon-glow);
}
/* 입력 UI */
.write-table { width: 100%; border-collapse: collapse; }
.td-label {
width: 200px; padding: 25px 35px; color: var(--neon-cyan);
font-size: 0.85rem; font-family: 'Orbitron'; font-weight: 700;
background: rgba(0, 242, 255, 0.03); border-bottom: 1px solid var(--border-color);
}
.td-label i { margin-right: 10px; filter: drop-shadow(0 0 5px var(--neon-cyan)); }
input[type="text"], input[type="date"], input[type="time"], select, textarea {
background: rgba(0, 0, 0, 0.5) !important;
border: 1px solid rgba(0, 242, 255, 0.2) !important;
color: #fff !important; padding: 12px 18px !important;
border-radius: 2px !important; font-size: 0.9rem;
transition: all 0.3s; font-family: 'JetBrains Mono', monospace;
}
/* 셀렉트 마우스 오버 시 색상 변화 추가 */
select:hover {
border-color: var(--neon-cyan) !important;
background: rgba(0, 242, 255, 0.1) !important;
cursor: pointer;
}
input[type="text"]:focus, select:focus, textarea:focus {
border-color: var(--neon-cyan) !important;
box-shadow: 0 0 15px var(--neon-glow) !important;
outline: none; background: rgba(0, 242, 255, 0.05) !important;
}
/* 버튼 시스템 */
.btn-action {
border: 1px solid var(--neon-cyan); background: transparent;
color: var(--neon-cyan); padding: 10px 25px; border-radius: 0;
font-family: 'Orbitron'; font-weight: 700; cursor: pointer; transition: 0.3s;
text-transform: uppercase; letter-spacing: 1px;
}
.btn-action:hover {
background: var(--neon-cyan); color: #000;
box-shadow: 0 0 20px var(--neon-cyan); transform: skewX(-10deg);
}
.btn-save-main {
background: var(--neon-cyan); color: #000;
padding: 25px 100px; font-size: 1.2rem; font-weight: 900;
margin-top: 50px; border: none; clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
transition: 0.4s;
}
.btn-save-main:hover {
background: #fff; transform: scale(1.05); box-shadow: 0 0 40px #fff;
}
/* 태그/설명 필드 */
.tag-input-wrap {
margin-top: 15px; display: flex; align-items: center; gap: 15px;
background: rgba(0,0,0,0.3); padding: 10px 20px; border: 1px dashed var(--border-color);
}
.tag-icon { color: var(--neon-pink); font-size: 0.9rem; }
.file-row {
display: none; align-items: center; gap: 15px; margin-bottom: 12px;
padding: 15px; background: rgba(255,255,255,0.02); border-left: 3px solid var(--neon-cyan);
}
.file-row.active { display: flex; animation: fadeIn 0.5s; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
/* 에디터 하단 배경 */
#Editor-Area { border-top: 1px solid var(--border-color); background: rgba(0,0,0,0.2); }
/* 스캔라인 효과 */
#WRITE::after {
content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.1) 50%),
linear-gradient(90deg, rgba(255, 0, 0, 0.02), rgba(0, 255, 0, 0.01), rgba(0, 0, 255, 0.02));
background-size: 100% 4px, 3px 100%; pointer-events: none; z-index: 10;
}
</style>
<!-- 로딩 레이어 -->
<div id="CYBER_LOADER">
<div class="load-text">CORE_SYSTEM_SYNCING...</div>
<div class="load-bar-wrap">
<div class="load-bar"></div>
</div>
</div>
<div id="WRITE_WRAP">
<canvas id="space-canvas"></canvas>
<article id="WRITE">
<form name="fwrite" id="fwrite" action="<?php echo $action_url; ?>" onsubmit="return fwrite_submit(this);" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="w" value="<?php echo $w; ?>">
<input type="hidden" name="bo_table" value="<?php echo $bo_table; ?>">
<input type="hidden" name="wr_id" value="<?php echo $wr_id; ?>">
<input type="hidden" name="sca" value="<?php echo $sca; ?>">
<input type="hidden" name="uid" value="<?php echo get_uniqid(); ?>">
<div class="form-header">
<h2><i class="fa-solid fa-microchip"></i> DATA_ENCRYPTION_UNIT</h2>
<div style="display:flex; gap:15px;">
<button type="button" class="btn-action" onclick="window.history.back();">ABORT</button>
<button type="submit" class="btn-action" style="background:var(--neon-cyan); color:#000;">EXECUTE</button>
</div>
</div>
<table class="write-table">
<tr>
<td class="td-label"><i class="fa-solid fa-network-wired"></i> PROTOCOL_SET</td>
<td style="padding:25px 40px;">
<div style="display:flex; flex-wrap:wrap; gap:15px; align-items:center;">
<?php if ($is_category) { ?>
<select name="ca_name" required>
<option value="">CATEGORY</option>
<?php echo $category_option; ?>
</select>
<?php } ?>
<span style="color:var(--neon-pink); font-family:'Orbitron'; font-size:0.7rem;">TYPE</span>
<select name="x2_ca2">
<option value=''>SELECT</option>
<?php
$bo_1_opts = explode("|", $board['bo_1']);
foreach($bo_1_opts as $val) {
$selected = ($write['x2_ca2'] == $val) ? "selected" : "";
echo "<option value='{$val}' {$selected}>{$val}</option>";
}
?>
</select>
<span style="color:var(--neon-pink); font-family:'Orbitron'; font-size:0.7rem;">FORM</span>
<select name="x2_ca3" id="x2_ca3">
<option value=''>SELECT</option>
<?php
$bo_2_opts = explode("|", $board['bo_2']);
foreach($bo_2_opts as $val) {
if (!trim($val)) continue;
$selected = (isset($write['x2_ca3']) && $write['x2_ca3'] == $val) ? "selected" : "";
echo "<option value='{$val}' {$selected}>{$val}</option>";
}
?>
</select>
<span style="color:var(--neon-pink); font-family:'Orbitron'; font-size:0.7rem;">STATUS</span>
<select name="x2_ca4" id="x2_ca4">
<option value=''>SELECT</option>
<?php
$bo_2_opts = explode("|", $board['bo_3']);
foreach($bo_2_opts as $val) {
if (!trim($val)) continue;
$selected = (isset($write['x2_ca4']) && $write['x2_ca4'] == $val) ? "selected" : "";
echo "<option value='{$val}' {$selected}>{$val}</option>";
}
?>
</select>
<span style="color:var(--neon-pink); font-family:'Orbitron'; font-size:0.7rem;">REV</span>
<input type="text" name="x2_ver" value="<?php echo $default_ver; ?>" size="8" placeholder="Ver.">
<div style="margin-left:auto; display:flex; gap:10px; align-items:center;">
<i class="fa-solid fa-clock" style="color:var(--neon-cyan);"></i>
<input type="date" name="wr_date_custom" value="<?php echo substr($write['wr_datetime'],0,10); ?>">
<input type="time" name="wr_time_custom" value="<?php echo substr($write['wr_datetime'],11,8); ?>" step="1">
</div>
</div>
</td>
</tr>
<tr>
<td class="td-label" style="border-bottom:none;"><i class="fa-solid fa-terminal"></i> SUBJECT_CORE</td>
<td style="padding:25px 40px; border-bottom: 1px solid var(--border-color);">
<input type="text" name="wr_subject" value="<?php echo $subject; ?>" required style="width:100%; font-size:1.1rem; font-weight:700;" placeholder="ENTER_SUBJECT_DATA...">
<div class="tag-input-wrap">
<span class="tag-icon"><i class="fa-solid fa-tags"></i> INDEX_TAGS</span>
<input type="text" name="wr_1" value="<?php echo $write['wr_1']; ?>" style="flex:1; border:none !important; background:transparent !important;" placeholder="TAG_STRING_DATA_DIVIDED_BY_COMMA">
</div>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center; padding:15px; background:rgba(0,242,255,0.05);">
<button type="button" class="btn-action" style="font-size:0.75rem;" onclick="$('#Editor-Area').slideToggle(400);">TOGGLE_DATA_EDITOR_&_PAYLOADS</button>
</td>
</tr>
</table>
<div id="Editor-Area" style="<?php echo ($w=='u' || $write['wr_content']) ? 'display:block;' : 'display:none;'; ?>">
<div style="padding:40px; background: rgba(0, 0, 0, 0.4);">
<?php echo $editor_html; ?>
</div>
<div style="padding:30px 40px; border-top:1px solid var(--border-color);">
<h3 style="font-family:'Orbitron'; font-size:0.9rem; color:var(--neon-cyan); margin-bottom:20px;"><i class="fa-solid fa-box-open"></i> ATTACHED_PAYLOADS</h3>
<div id="variableFiles">
<?php for ($i=0; $is_file && $i<$file_count; $i++) {
$is_active = ($i == 0 || (isset($file[$i]['file']) && $file[$i]['file'])) ? "active" : "";
?>
<div class="file-row <?php echo $is_active; ?>" id="file_row_<?php echo $i; ?>">
<label for="bf_file_<?php echo $i; ?>" style="cursor:pointer; font-family:'JetBrains Mono'; color:var(--neon-cyan); font-size:0.8rem;">[FILE_0<?php echo $i+1; ?>]</label>
<input type="file" name="bf_file[<?php echo $i; ?>]" id="bf_file_<?php echo $i; ?>" style="display:none;" onchange="updateFileName(this, <?php echo $i; ?>)">
<span id="file_name_<?php echo $i; ?>" style="color:#aaa; font-size:0.8rem; flex:1;">
<?php if($w == 'u' && isset($file[$i]['file']) && $file[$i]['file']) {
echo $file[$i]['source'];
echo " <label style='color:var(--neon-pink); margin-left:15px; cursor:pointer; font-size:0.7rem;'><input type='checkbox' name='bf_file_del[$i]' value='1'> REMOVE</label>";
} else { echo "READY_FOR_UPLOAD"; } ?>
</span>
<?php if ($board['bo_use_file_content']) { ?>
<input type="text" name="bf_content[<?php echo $i; ?>]" value="<?php echo ($w == 'u') ? stripslashes($file[$i]['bf_content']) : ''; ?>" style="width:300px; font-size:0.8rem !important; background:transparent !important;" placeholder="PAYLOAD_DESCRIPTION">
<?php } ?>
</div>
<?php } ?>
</div>
<button type="button" class="btn-action" style="font-size:0.7rem; margin-top:10px;" onclick="file_add();">+ EXPAND_SLOT</button>
</div>
</div>
<div style="padding:60px 0; text-align:center; border-top:1px solid var(--border-color);">
<button type="submit" class="btn-action btn-save-main">UPLOAD_TO_MAINFRAME</button>
</div>
</form>
</article>
</div>
<script>
window.addEventListener('load', function() {
const loader = document.getElementById('CYBER_LOADER');
setTimeout(() => {
loader.style.opacity = '0';
setTimeout(() => loader.style.visibility = 'hidden', 800);
}, 1500);
});
// 배경 스타 애니메이션
const canvas = document.getElementById('space-canvas');
const ctx = canvas.getContext('2d');
let stars = [];
function initSpace() {
canvas.width = window.innerWidth; canvas.height = window.innerHeight; stars = [];
for(let i=0; i<150; i++) stars.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, size: Math.random() * 1.5, speed: Math.random() * 0.4 });
}
function animateSpace() {
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgba(0, 242, 255, 0.8)";
stars.forEach(star => {
ctx.beginPath(); ctx.arc(star.x, star.y, star.size, 0, Math.PI*2); ctx.fill();
star.y += star.speed; if(star.y > canvas.height) star.y = 0;
});
requestAnimationFrame(animateSpace);
}
window.addEventListener('resize', initSpace);
initSpace(); animateSpace();
function updateFileName(input, index) {
const fileName = input.files[0] ? input.files[0].name : "READY_FOR_UPLOAD";
const display = document.getElementById('file_name_' + index);
display.innerText = fileName;
display.style.color = "var(--neon-cyan)";
}
function file_add() {
var rows = document.querySelectorAll('.file-row:not(.active)');
if (rows.length > 0) rows[0].classList.add('active');
}
function fwrite_submit(f) {
<?php echo $editor_js; ?>
return true;
}
</script>