๐ฅ
๐
๐ป
Z
U
๐f
(โฆ)
๐n
(โฆ)
โฐ
๐พS
๐ฅ
๐C
๐
๐
ฦ
yE
Fn
St
Fi
Hd
<?php // ๋ฒ์ : 2.3.0 ์ด๋ฏธ0๊ฐ์ ์ฉ 1๊ฐ์ ์ฉ ๋ฒํผ ํ๋จ์ผ๋ก ์ด๋. // ๋ฒ๋ฒ : 2.3.1 ์๋จ ๋ฉ๋ด ๋ฌ๋ ฅ๋ณด์ด๋๊ฒ ์จ๊น ๊ธฐ๋ฅ , ๊ฐ๋ก ํฌ๊ธฐ ๋ณด์ด๊ฒ. // ๋ฒ๋ฒ : 2.3.2 ํธ์ง๊ธฐ ๋ฐ์ดํธ์ // ๋ฒ๋ฒ : 2.3.3 ์ ์ฅ๋ฒํผ ์์ ๋๋ฉด ํ์ฑํํ์ ๋ณต์. // ๋ฒ๋ฒ : 2.3.4 ๋๋กญ ์์ํ์ผ yyy_view ์ด๋ URL์์ view ๊ฒฝ๋ก raw ํ์. // ๋ฒ์ : 2.3.5 ZIP ์ ์ฉ ์ธ์ ๋ฒํธ์ yyy_view ๋๋กญ ์์ํด๋ ์ธ์ ๋ฒํธ ๊ณต์ . // ๋ฒ์ : 2.3.6 ๋๋กญ ์ธ์ ๋ช ์ 4์๋ฆฌ ์งง์ ์๊ตฌ ์ธ์ ์ผ๋ก ๋จ์ํ. // ์์ ์ ๋ฐ์ดํธ ๊ฒ์์ด. ๋ฐ๊ฟ๋ง ์ ๋ ฅ์ ํ๋จ์ byte๊ณ์ฐ ์ค์๊ฐ์ผ๋ก ํ์. define("_CMD_", true); error_reporting(E_ALL); if (!defined('G5_SET_TIME_LIMIT')) define('G5_SET_TIME_LIMIT', 0); include_once "yyy_allowed_ips.php"; // <!-- // yyy-used-files-exclude:start --> include_once __DIR__ . "/yyy_config_host.php"; include_once __DIR__ . "/yyy_func.php"; // <!-- // yyy-used-files-exclude:end --> // yyy_host_link.php function yy_view_drop_json($data, $code = 200) { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } function yy_view_drop_backup_root() { if (defined('BACKUP_ROOT') && trim((string)BACKUP_ROOT) !== '') { return rtrim((string)BACKUP_ROOT, '/') . '/yyy_view'; } return '/data/_bak/yyy_view'; } function yy_view_drop_zip_session_root() { if (defined('BACKUP_ROOT') && trim((string)BACKUP_ROOT) !== '') { return rtrim((string)BACKUP_ROOT, '/') . '/yyy_zip'; } return '/data/_bak/yyy_zip'; } function yy_view_drop_safe_session_id($sid) { $sid = strtolower(trim((string)$sid)); return preg_match('/^[a-f0-9]{4}$/', $sid) ? $sid : ''; } function yy_view_drop_make_session_id() { return substr(md5(date('YmdHis') . microtime(true) . mt_rand()), 0, 4); } function yy_view_drop_ensure_zip_session($sid) { $sid = yy_view_drop_safe_session_id($sid); if ($sid === '') return false; $dir = yy_view_drop_zip_session_root() . '/' . $sid . '/unzip'; return is_dir($dir) || @mkdir($dir, 0775, true) || is_dir($dir); } function yy_view_drop_safe_name($name) { $name = str_replace(array("\0", '/', '\\'), '_', (string)$name); $name = trim($name); if ($name === '' || $name === '.' || $name === '..') $name = 'drop_file.txt'; return $name; } function yy_view_drop_unique_path($dir, $name) { $name = yy_view_drop_safe_name($name); $path = rtrim($dir, '/') . '/' . $name; if (!file_exists($path)) return $path; $pi = pathinfo($name); $stem = isset($pi['filename']) ? $pi['filename'] : $name; $ext = isset($pi['extension']) && $pi['extension'] !== '' ? '.' . $pi['extension'] : ''; for ($i = 1; $i <= 999; $i++) { $try = rtrim($dir, '/') . '/' . $stem . '_' . sprintf('%03d', $i) . $ext; if (!file_exists($try)) return $try; } return rtrim($dir, '/') . '/' . $stem . '_' . date('His') . $ext; } function yy_view_drop_files_array($files) { $out = array(); if (!isset($files['name'])) return $out; if (is_array($files['name'])) { foreach ($files['name'] as $i => $name) { $out[] = array( 'name' => $name, 'type' => isset($files['type'][$i]) ? $files['type'][$i] : '', 'tmp_name' => isset($files['tmp_name'][$i]) ? $files['tmp_name'][$i] : '', 'error' => isset($files['error'][$i]) ? $files['error'][$i] : UPLOAD_ERR_NO_FILE, 'size' => isset($files['size'][$i]) ? $files['size'][$i] : 0, ); } } else { $out[] = $files; } return $out; } if (isset($_POST['action']) && $_POST['action'] === 'drop_view_upload') { $uploads = yy_view_drop_files_array(isset($_FILES['drop_files']) ? $_FILES['drop_files'] : array()); if (!$uploads) { yy_view_drop_json(array('ok' => false, 'error' => '์ ๋ก๋ ํ์ผ ์์'), 400); } $sid = yy_view_drop_safe_session_id(isset($_POST['sid']) ? $_POST['sid'] : ''); if ($sid === '') { $sid = yy_view_drop_make_session_id(); } yy_view_drop_ensure_zip_session($sid); $dir = yy_view_drop_backup_root() . '/' . $sid; if (!is_dir($dir) && !@mkdir($dir, 0775, true) && !is_dir($dir)) { yy_view_drop_json(array('ok' => false, 'error' => '์์ ํด๋ ์์ฑ ์คํจ', 'dir' => $dir), 500); } $saved = array(); foreach ($uploads as $up) { if (!isset($up['error']) || $up['error'] !== UPLOAD_ERR_OK) { $saved[] = array('ok' => false, 'name' => isset($up['name']) ? $up['name'] : '', 'error' => 'upload_error_' . (isset($up['error']) ? $up['error'] : 'unknown')); continue; } $dest = yy_view_drop_unique_path($dir, isset($up['name']) ? $up['name'] : 'drop_file.txt'); if (!@move_uploaded_file($up['tmp_name'], $dest)) { $saved[] = array('ok' => false, 'name' => isset($up['name']) ? $up['name'] : '', 'error' => 'move_uploaded_file ์คํจ'); continue; } @chmod($dest, 0664); $saved[] = array('ok' => true, 'name' => basename($dest), 'path' => $dest, 'size' => @filesize($dest)); } $first = ''; foreach ($saved as $row) { if (!empty($row['ok']) && !empty($row['path'])) { $first = $row['path']; break; } } if ($first === '') { yy_view_drop_json(array('ok' => false, 'error' => '์ ์ฅ ์ฑ๊ณต ํ์ผ ์์', 'files' => $saved), 500); } yy_view_drop_json(array( 'ok' => true, 'sid' => $sid, 'dir' => $dir, 'files' => $saved, 'view_path' => $first, 'view_url' => 'yyy_view.php?view=' . $first . '&drop_sid=' . $sid, )); } /* =============================== ๊ธฐ์กด POST / GET ์ฒ๋ฆฌ (์๋ณธ ์ ์ง) =============================== */ $R = $_REQUEST; $req_bool = function($k){ return isset($_REQUEST[$k]) && $_REQUEST[$k] == '1'; }; // (์ค๊ฐ ๋ก์ง ์ ๋ถ ์๋ณธ ๊ทธ๋๋ก ์ ์ง) if (isset($_REQUEST['save_file']) && $_REQUEST['save_file'] == '1') { $file_path = $_REQUEST['file_path'] ?? ''; $content = $_REQUEST['content'] ?? ''; $no_bak = $_REQUEST['no_bak'] ?? false; $save_mode = trim((string)($_REQUEST['save_mode'] ?? 'quick')); if (!$file_path) die("โ ํ์ผ ๊ฒฝ๋ก๊ฐ ์์ต๋๋ค."); // ๋๋ ํ ๋ฆฌ๊ฐ ์์ผ๋ฉด ์์ฑ $dir = dirname($file_path); if (!is_dir($dir)) { if (!mkdir($dir, 0755, true)) { die("โ ๋๋ ํ ๋ฆฌ ์์ฑ ์คํจ: " . htmlspecialchars($dir)); } } // save_as : ๊ธฐ์กด ํ์ผ ๋จผ์ ๋ฐฑ์ ํ ์ ์ฅ if ($save_mode === 'save_as') { if (file_exists($file_path)) { if (!createBackup($file_path, $no_bak)) { $err = getBackupLastError(); if ($err) { echo ("yy71:[{$err['code']}] {$err['message']}\n"); } else { echo ("[UNKNOWN] ์ ์ ์๋ ์ค๋ฅ\n"); } exit; } } } $result = file_put_contents($file_path, $content); if ($result === false) die("โ ํ์ผ ์ ์ฅ์ ์คํจํ์ต๋๋ค."); // quick : ์ ์ฅ๋ ์ต์ ๋ณธ์ ๋ค์ ๋ฐฑ์ ํด์ 2์ค ์ ์ฅ if ($save_mode === 'quick') { if (!createBackup($file_path, $no_bak)) { $err = getBackupLastError(); if ($err) { echo ("yy72:[{$err['code']}] ์ต์ ๋ฐฑ์ ์คํจ: {$err['message']}\n"); } else { echo ("yy72:[UNKNOWN] ์ต์ ๋ฐฑ์ ์คํจ\n"); } exit; } } echo "โ ์ ์ฅ ์ฑ๊ณต: " . htmlspecialchars($file_path) . " (" . number_format($result) . " bytes)"; } $file_path = $_GET['view'] ?? ''; $filename = ($file_path !== '') ? basename($file_path) : ''; $target_line = (int)($_GET['line'] ?? 0); $file_exists = ($file_path !== '' && file_exists($file_path) && is_file($file_path)); $file_size = ($file_exists ? filesize($file_path) : 0); $content = ''; if ($file_exists) { $max = 1024 * 1024; $content = ($file_size > $max) ? file_get_contents($file_path, false, null, 0, $max) : file_get_contents($file_path); } $file_ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); $language_map = [ 'php'=>'php','phtml'=>'php','inc'=>'php','bak'=>'php', 'js'=>'javascript','ts'=>'javascript','jsx'=>'javascript','tsx'=>'javascript', 'css'=>'css','scss'=>'css','sass'=>'css','less'=>'css', 'html'=>'htmlmixed','htm'=>'htmlmixed','xml'=>'xml','xhtml'=>'htmlmixed','ejs'=>'htmlmixed', 'sql'=>'sql','py'=>'python', 'sh'=>'shell','bash'=>'shell','zsh'=>'shell','htaccess'=>'shell','csv'=>'shell', 'hlp'=>'properties','ini'=>'properties','env'=>'properties','conf'=>'properties','cnf'=>'properties', 'json'=>'javascript','yaml'=>'yaml','yml'=>'yaml','toml'=>'toml', 'md'=>'markdown','txt'=>'plaintext','log'=>'plaintext' ]; $language = $language_map[$file_ext] ?? 'plaintext'; if (in_array($file_ext,['html','htm','xml','phtml'],true) && strpos($content,'<?php')!==false) $language='php'; if ($file_ext==='htaccess' || basename($file_path)==='.htaccess') $language='shell'; $has_pair = false; if ($file_path !== '') { $filename = basename($file_path); $dir_path = dirname($file_path); if (preg_match('/^(.+?)(?:_s)?\.(php|py|js|css|html|htm|ejs|sql|txt|md|conf|ini|sh)$/i',$filename,$m)) { $base=$m[1]; $ext=strtolower($m[2]); if (file_exists("{$dir_path}/{$base}.{$ext}") && file_exists("{$dir_path}/{$base}_s.{$ext}")) $has_pair=true; } } $ye_file_path = ''; $ye_exists = false; if ($file_path !== '') { $ye_src_dir = dirname($file_path); $ye_src_file = basename($file_path); if (!defined('YE_ROOT_FS')) define('YE_ROOT_FS', '/data/yE'); $ye_file_path = YE_ROOT_FS . $ye_src_dir . '/yE_' . $ye_src_file . '.html'; $ye_exists = (file_exists($ye_file_path) && is_file($ye_file_path)); } $title_name = ($file_path !== '' ? basename($file_path) : 'YYY Editor'); $cm_wrap = (isset($_COOKIE['cm_wrap']) && $_COOKIE['cm_wrap']==='1') ? 1 : 0; $YY_VIEW_SELF = basename($_SERVER['SCRIPT_NAME'] ?? 'yyy_view.php'); $YY_VIEW_JS = preg_replace('/\.php$/i', '.js', $YY_VIEW_SELF); if (!is_file(__DIR__ . '/' . $YY_VIEW_JS)) { $YY_VIEW_JS = 'yyy_view.js'; } ?> <!DOCTYPE html> <html lang="ko" data-bs-theme="<?= htmlspecialchars($_COOKIE['theme'] ?? 'light', ENT_QUOTES) ?>"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=yes"> <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='0.9em' font-size='90'>๐พ</text></svg>"> <title><?php echo htmlspecialchars($title_name); ?></title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet"> <?php include "yyy__theme_style.php"; ?> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/dracula.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/xml/xml.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/javascript/javascript.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/css/css.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/htmlmixed/htmlmixed.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/clike/clike.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/php/php.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/sql/sql.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/python/python.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/shell/shell.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/properties/properties.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/yaml/yaml.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/markdown/markdown.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/scroll/scrollpastend.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/foldgutter.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/foldcode.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/foldgutter.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/xml-fold.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/brace-fold.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/fold/indent-fold.min.js"></script> <link rel="stylesheet" href="yyy_view.css?v=2.12.8"> <style> @media (max-width: 1200px){ .my-date-input{ display:none !important; } } </style> <!-- style> body { margin:0; } #editor-wrap{ background:var(--panel); } html[data-bs-theme="dark"] #editor-wrap{ background:#1e1e1e; } html[data-bs-theme="light"] #editor-wrap, html:not([data-bs-theme]) #editor-wrap{ background:#fff; } </style --> </head> <body data-file-path="<?= htmlspecialchars($file_path, ENT_QUOTES, 'UTF-8') ?>" data-target-line="<?= (int)$target_line ?>" data-language="<?= htmlspecialchars($language, ENT_QUOTES, 'UTF-8') ?>" > <div id="yyy-view-shell0"> <div id="yyy-view-shell"> <!-- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ํด๋ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ --> <div class="toolbar"> <!-- โโ ์ข์ธก ๊ทธ๋ฃน: ํธ์ง ๊ธฐ๋ณธ ๊ธฐ๋ฅ โโ --> <button class="btn tb-btn icon-only" id="yyUndoBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์คํ ์ทจ์ Ctrl+Z"> <i class="bi bi-arrow-counterclockwise"></i> </button> <button class="btn tb-btn icon-only" id="yyRedoBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ค์ ์คํ Ctrl+Y"> <i class="bi bi-arrow-clockwise"></i> </button> <div class="tb-sep"></div> <!-- โโ ์ข์ธก ๊ทธ๋ฃน: ํ ๊ธ๋ฅ + ํ์ผ๋ช โโ --> <!-- Split ํ ๊ธ (์์ด์ฝ ๋ฒํผ) --> <button class="btn tb-btn icon-only" id="splitBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํ๋ฉด ๋ถํ (์/์๋)"> <i class="bi bi-layout-split"></i> </button> <!-- Wrap ํ ๊ธ (์์ด์ฝ ๋ฒํผ) --> <button class="btn tb-btn icon-only" id="wrapBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์ฝ๋ ์๋์ค๋ฐ๊ฟ Wrap"> <i class="bi bi-text-wrap"></i> </button> <!-- ์๋จ ํด๋ฐ ์ค๋ฐ๊ฟ ํ ๊ธ --> <button class="btn tb-btn icon-only" id="yyToolbarWrapBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์๋จ ๋ฉ๋ด ์ค๋ฐ๊ฟ"> <i class="bi bi-text-wrap"></i> </button> <div class="tb-sep"></div> <!-- // yyy-used-files-exclude:start --> <a class="tb-btn icon-only" href="yyy_find.php?path=<?=dirname($file_path)?>" target="yyy" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์ <?=dirname($file_path)?>">๐ฅ</a> <a class="tb-btn icon-only" href="yyy_view.php?view=yyy_view.php&line=1" target="yyy_view" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์ด ํ์ผ ์ด๊ธฐ">๐</a> <a class="tb-btn icon-only" href="yyy_cmd.php?command=ls -al <?=dirname($file_path);?>" target="yyy_cmd" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํฐ๋ฏธ๋ <?=dirname($file_path);?>">๐ป</a> <a class="tb-btn icon-only" href="yyy_zip_apply.php" target="yyy_zip_apply" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="ZIP ์์ถํ๊ธฐ <?=dirname(__FILE__);?>">Z</a> <a class="tb-btn icon-btn" href="yyy_used_files.php" target="yyy_used_files" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="yyy_used_files">U</a> <!-- // yyy-used-files-exclude:end --> <div class="tb-sep"></div> <?php $LINK_ECHO=1; if(file_exists("yyy_host_link.php")) include_once "yyy_host_link.php"; //ai_help๋ณด๋ด์ฃผ๊ธฐ๋ณต์ฌ $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) ? 'https' : 'http'; $web_url2 = get_web_url('ai_help.php').'?token='.YYY_TOKEN; $filePath = get_fulllpath($file_path); ?> <!-- โโ ์ฐ์ธก ๊ทธ๋ฃน: ์ก์ ๋ฒํผ โโ --> <div class="tb-sep"></div> <script src="_docs/yy_alarm_ds2gt_final_fulld.js.php?v=1.23"></script> <div class="icon-btn" id="yy-alarm-icon-here">โฐ</div> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"> <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script> <script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ko.js"></script> <?php $now=date("Y-m-d H:i"); ?> <input type="text" id="dateTime" class="tb-btn" value="<?=$now?>"> <script src="yy_drag_resize.js?v=1.7.4"></script> <script src="yy-clip-board.js?v=1.0"></script> <script src="yy-color-picker.js?v=4.3"></script> <div style="color:#000;" id="yy-color-picker" data-yy-scope="<?= htmlspecialcharsX($filename, ENT_QUOTES) ?>" data-yyDragHandle=".card-header" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs title="์นผ๋ฌ ํผ์ปค"></div> <script> document.addEventListener("DOMContentLoaded", function() { flatpickr("#dateTime", { enableTime: true, // ๐ฅ ์๊ฐ ํ์ฑํ time_24hr: true, // 24์๊ฐ์ dateFormat: "Y-m-d H:i", // ๐ฅ ์๋ฒ๊ฐ๊ณผ ๋์ผ ํ์ altInput: true, altFormat: "Y-m-d (D) H:i", // ๐ฅ ํ๋ฉด ํ์์ฉ (์์ผ ํฌํจ) locale: "ko", // ๐ฅ ์ด๊ฒ ํต์ฌ disableMobile: true, // ๐ฅ ๋ชจ๋ฐ์ผ ๋ค์ดํฐ๋ธ ์ฐจ๋จ altInputClass: "my-date-input", }); }); </script> <div class="tb-sep"></div> <button class="btn tb-btn green icon-only" id="saveBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์ ์ฅ (ํ์ผ๋ช ์์ ๊ฐ๋ฅ)">๐พS</button> <button class="btn tb-btn orange icon-only" id="downloadBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํ์ฌ์ฐฝ ๋ค์ด๋ก๋">๐ฅ</button> <button class="btn tb-btn blue icon-only" id="copyBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํธ์ง๊ธฐ ๋ด์ฉ ํด๋ฆฝ๋ณด๋ ๋ณต์ฌ">๐C</button> <button class="btn tb-btn icon-only <?php echo $has_pair?'orange':'gray'; ?>" id="diffBtn" data-bs-placement="bottom" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํ์ผ ๋น๊ต">๐</button> <div class="tb-sep"></div> <div id="themeToggle" class="tb-btn icon-only pointer" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋คํฌ๋ชจ๋ ํ ๊ธ"></div> <button class="tb-btn btn icon-only" id="searchPanelBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ด์ฉ๊ฒ์ ํจ๋">๐</button> <div id="funcBtn" class="tb-btn icon-only pointer" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํจ์/ํด๋์ค ๋ชฉ๋ก">ฦ</div> <!-- button class="btn tb-btn gray icon-only" id="closeBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="ํ์ฌ์ฐฝ ๋ซ๊ธฐ">๐</button --> <button class="btn tb-btn <?php echo $ye_exists ? 'orange' : 'gray'; ?>" id="openYeBtn" data-ye-file="<?= htmlspecialchars($ye_file_path."&Me=1", ENT_QUOTES, 'UTF-8') ?>" data-ye-exists="<?= $ye_exists ? '1' : '0' ?>" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="yE ๋ณด๊ด/๋ฉ๋ชจ ํ์ <?= htmlspecialchars($ye_file_path, ENT_QUOTES, 'UTF-8') ?>">yE</button> <!-- div class="btn-group yy-mini-toggles flex-shrink-0" role="group" aria-label="ํ์ ํ ๊ธ"> <input class="btn-check" type="checkbox" id="text-truncate" data-toggle-class="text-truncate" checked> <label class="btn tb-btn yy-tg yy-tg-tr" for="text-truncate" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํจ์๋ช ํ์">tr</label> <input class="btn-check" type="checkbox" id="text-yyCopySel" data-toggle-class="yyCopySel" checked> <label class="btn tb-btn yy-tg yy-tg-cs" for="text-yyCopySel" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true" data-bs-custom-class="yy-tip-left yy-tip-st" data-bs-title="A: ํฐํธยท์คํ <br>Lh: ์ค๊ฐ๊ฒฉยท์คํ <br>cc.top: ์ปค์ Y<br>info.top: ์คํฌ๋กค Y<br>info.cH: ๋ณด์ด๋ ๋์ด<br>info.cW: ๋ณด์ด๋ ๋๋น<br>Y: ํ๋ฉด ์ปค์ ์ธ๋ก ์์น<br>F: ํ๋ฉด ์ปค์ ์ธ๋ก ๋น์จ<br>V: ๋ณด์ด๋ ๋ผ์ธ ๋ฒ์<hr>X: ํ๋ฉด ์ปค์ ๊ฐ๋ก ์์น<hr>Split: ์ํ ๋ถํ ๋น">Cs</label> <input class="btn-check" type="checkbox" id="text-yyFile" data-toggle-class="yyFile" checked> <label class="btn tb-btn yy-tg yy-tg-fi" for="text-yyFile" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํ์ผ ์ ๋ณด ํ์ ํ ๊ธ">Fi</label> </div --> <div class="yySeg flex-shrink-0" id="yyTopMiniToggles"> <label class="yyTopMiniToggles" data-key="dk-fn" data-position="left" data-color="info" data-target="#cm-sticky-text" data-mode="show" data-on="1" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํจ์๋ช ํ์ ํ ๊ธ">Fn</label> <label class="yyTopMiniToggles" data-position="center" data-key="dk-st" data-color="success" data-target=".yyCopySel" data-mode="show" data-on="1" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true" data-bs-custom-class="yy-seg-tip-left" data-bs-title="A: ํฐํธยท์คํ <br>Lh: ์ค๊ฐ๊ฒฉยท์คํ <br>cc.top: ์ปค์ Y<br>info.top: ์คํฌ๋กค Y<br>info.cH: ๋ณด์ด๋ ๋์ด<br>info.cW: ๋ณด์ด๋ ๋๋น<br>Y: ํ๋ฉด ์ปค์ ์ธ๋ก ์์น<br>F: ํ๋ฉด ์ปค์ ์ธ๋ก ๋น์จ<br>V: ๋ณด์ด๋ ๋ผ์ธ ๋ฒ์<hr>X: ํ๋ฉด ์ปค์ ๊ฐ๋ก ์์น<hr>Split: ์ํ ๋ถํ ๋น">St</label> <label class="yyTopMiniToggles" data-position="center" data-key="dk-fi" data-color="primary" data-target=".yyFile" data-mode="show" data-on="1" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํ์ผ์ ๋ณด ํ์ ํ ๊ธ">Fi</label> <span id="yySelLiveMarkSentinel" style="display:none;"></span> <label id="yyStickyHideBtn" class="yyTopMiniToggles" data-position="right" data-key="dk-hd" data-color="warning" data-mode="custom" data-on="0" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํ๋จ ์ํ๋ฐ ํ์ ํ ๊ธ">Hd</label> </div EndOf="#yyTopMiniToggles"> </div EndOf=".toolbar"> <div id="editor-wrap"> <textarea id="code-editor" style="display:none;"><?php echo htmlspecialchars($content, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8'); ?></textarea> </div> <div id="cm-sticky-func"> <div id="cm-sticky-text" class="text-truncate" style="min-width:0;"></div> <div id="cm-sticky-tools" class="d-flex gap-1 align-items-center"> <!-- ํ์ผ๋ช --> <div class="title yyFile"> <?php $yy_ai_files_json = json_encode([get_fulllpath($file_path)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $yy_ai_files_b64 = rtrim(strtr(base64_encode($yy_ai_files_json), '+/', '-_'), '='); $yy_file_json_url = HTTPS_HOST_443 . '/y/batch_files.php' . '?token=' . rawurlencode(defined('YYY_TOKEN') ? YYY_TOKEN : 'ABC1234XYZ') . '&action=zip_json' . '&flat_zip=1' . '&files_b64=' . rawurlencode($yy_ai_files_b64); ?> <span class="file-path" role="button" tabindex="0" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํ์ฌ ํ์ผ AI๋ค์ด URL ๋ณต์ฌ" onclick='copyToClipboard(<?= json_encode($yy_file_json_url, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>)' >โจ<?= htmlspecialchars($file_path, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?></span> <small> <span id="yy-file-bytes"><?php echo $file_exists ? (number_format($file_size).' bytes') : 'NOFILE'; ?></span> :: <b><?php echo htmlspecialchars($language, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?></b> </small> </div> <span id="cur-height" class="tb-btn small yyCopySel" style="opacity:.75;">Y:0px 0%</span> <span id="cur-width" class="tb-btn small yyCopySel" style="opacity:.75;">X:0px 0%</span> <span id="cur-split" class="tb-btn small yyCopySel" style="opacity:.70;">Split:--</span> <span id="cur-line" class="tb-btn small yyCopySel" style="opacity:.85;">Line:1</span> <button class="btn tb-btn icon-only" id="fontResetBtn" data-bs-toggle="tooltip" data-bs title="๊ธ์ ํฌ๊ธฐ ๊ธฐ๋ณธ๊ฐ">A0</button> <button class="btn tb-btn icon-only" id="fontMinusBtn" data-bs-toggle="tooltip" data-bs title="๊ธ์ ์๊ฒ">Aโ</button> <button class="btn tb-btn icon-only" id="fontPlusBtn" data-bs-toggle="tooltip" data-bs title="๊ธ์ ํฌ๊ฒ">A+</button> <span class="tb-sep" style="height:16px;"></span> <button class="btn tb-btn icon-only" id="lhResetBtn" data-bs-toggle="tooltip" data-bs title="์ค๊ฐ๊ฒฉ ๊ธฐ๋ณธ๊ฐ">Lh0</button> <button class="btn tb-btn icon-only" id="lhMinusBtn" data-bs-toggle="tooltip" data-bs title="์ค๊ฐ๊ฒฉ ์ข๊ฒ">Lhโ</button> <button class="btn tb-btn icon-only" id="lhPlusBtn" data-bs-toggle="tooltip" data-bs title="์ค๊ฐ๊ฒฉ ๋๊ฒ">Lh+</button> <button class="btn tb-btn icon-only" id="preQuickBtn" data-bs-toggle="tooltip" data-bs title="pre ๋ธ๋ก ์ฝ์ / Ctrl+Enter ํ์ฌ์ค์ pre๋ก ๋ณํ">pre+</button> </div> </div> <!-- โโ ฦ ํจ์๋ชฉ๋ก ๋ชจ๋ฌ โโ --> <div class="modal fade " id="funcModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-scrollable modal-lg yyDrag yyResize" data-yy-key="func_modal_dialog" data-yyDragHandle=".modal-header" data-yyMinW="520" data-yyMinH="260" > <div class="modal-content" style="background:var(--panel);color:var(--text);border:1px solid var(--border);"> <div class="modal-header" style="background:var(--panel2);border-bottom:1px solid var(--border);"> <h6 class="modal-title m-0">ฦ ํจ์ / ํด๋์ค ๋ชฉ๋ก</h6> <span id="funcSortBtn" class="pl-3 tb-btn icon-only yyNoDrag" role="button" tabindex="0" title="์ ๋ ฌ: ๋ผ์ธ์ / ์ด๋ฆ์ " aria-pressed="false" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์ ๋ ฌ" > <i class="bi bi-sort-numeric-down" id="funcSortBtnIcon"></i> </span> <span id="funcAddToSpRstBtn" class="pl-3 tb-btn icon-only yyNoDrag" role="button" tabindex="0" data-bs title="์ฐ์ธก์ฐฝ์ ์ถ๊ฐ" aria-pressed="false" data-bs-placement="bottom" data-bs-toggle="tooltip"> <i class="bi bi-box-arrow-in-right" id="funcAddToSpRstiCon"></i> </span> <span type="button" class="tb-btn icon-only btn-close" data-bs-dismiss="modal" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ซ๊ธฐ" aria-label="Close"></span> </div> <div class="modal-body"> <div class="d-flex gap-2 align-items-center mb-2"> <input type="text" id="funcSearch" class="form-control form-control-sm" placeholder="๊ฒ์ (ํจ์๋ช /ํด๋์ค๋ช ) โฆ" autocomplete="off"> <span id="funcMeta" class="small" style="opacity:.7;white-space:nowrap;"></span> </div> <div id="funcList"></div> </div> <div class="modal-footer" style="background:var(--panel2);border-top:1px solid var(--border);"> <span class="small" style="opacity:.7;">Ctrl+Shift+F</span> <span id="funcFooterMeta" class="small ms-2" style="opacity:.85;"></span> <!-- โ ์ถ๊ฐ --> <button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">๋ซ๊ธฐ</button> <span class="file-path" data-bs-toggle="tooltip" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="ํด๋ฆฝ๋ณด๋ ai_help๋ณต์ฌ <?=$web_url2?>" onclick="copyToClipboard('<?= $web_url2 ?>')">๐</span> </div> </div> </div> </div> <div id="search-panel"> <div id="sp-resize-handle"></div> <div id="sp-header"> <span id="sp-close" class="btn tb-btn icon-only " data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ซ๊ธฐ" >โ</span> <button class="btn tb-btn icon-only " id="saveBtn1" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ฌป์ง๋ง ์ ์ฅ">๐พ</button> <div class="tb-sep"></div> <button id="spWholeLineBtn" class="btn icon-only tb-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์: ์ ์ฒด๋ผ์ธ์ผ์น"> <i class="bi-hr"></i> </button> <button id="spTrimBtn" class="btn icon-only tb-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์: ๋ผ์ธ๋ณ ์๋ค๊ณต๋ฐฑ๋ฌด์"> <i class="bi-arrows-angle-contract"></i> </button> <button id="spCaseBtn" class="btn tb-btn icon-only" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์: ๋์๋ฌธ์ ๊ตฌ๋ถ">Aa</button> <button id="spWordBtn" class="btn tb-btn icon-only" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์: ๋จ์ด๋จ์">.*</button> <div class="tb-sep"></div> <button type="button" class="btn tb-btn icon-only sp-tool-btn" id="yyy-bf-toggle" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์: ๋ฐฑ์ ์์ ์ฐพ๊ธฐ">bF</button> <!-- ์ฐ์ธก ๊ฒ์๊ฒฐ๊ณผ Wrap ๋ฒํผ ์์ (ํจ๋ ํค๋ ์) --> <button class="btn tb-btn icon-only sp-tool-btn" id="spWrapBtn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๊ฒ์๊ฒฐ๊ณผ ์ค๋ฐ๊ฟ" aria-pressed="false"> <i class="bi bi-text-wrap ico-off"></i> <i class="bi bi-card-text ico-on"></i> </button> <div class="tb-sep"></div> </div EndOf="id= sp-header"> <div id="yyy-bak-find-wrap" data-file-path="<?=$filePath?>"></div> <script src="/y/yyy_bak_find.js?v=1.1"></script> <link rel="stylesheet" href="/y/yyy_bak_find.css"> <div id="sp-input-wrap"> <div class="sp-textarea-wrap mb-2"> <div id="sp-input-lines" class="sp-lines">1</div> <textarea id="sp-input" placeholder="๐๊ฒ์์ด.." autocomplete="off" title="์๋ฒ์์๊ฐ ์๋ ํ์ฌ ํธ์ง๊ธฐ์์ ๊ฒ์" rows="1"></textarea> </div> <div class="sp-meta-row"> <?php //์น์ผ๋ก์ด๊ธฐ $BASE = get_self_base_path(); $web_url = get_web_url($file_path); $web_icon = $web_url ? '<a href="'.$web_url.'" target="_blank" class="selct-none text-primary btn icon-only tb-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="์น์ผ๋ก ์ด๊ธฐ '.$file_path.'">๐</a>' : ''; echo $web_icon; //php๋ฌธ๋ฒ๊ฒ์ฌ. $web_url = $BASE . '/php_l.php?token='.YYY_TOKEN.'&path='.$filePath.'&fmt=html&noBot=1'; echo '<a href="'.$web_url.'" target="_blank" class="selct-none text-primary btn icon-only tb-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="php ๋ฌธ๋ฒ ๊ฒ์ฌ '.$web_url.'">๐</a>' ; ?> <button id="spReplaceBtn" class="btn tb-btn icon-only sp-tool-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs title="๋ฐ๊พธ๊ธฐ ์ฌ์ฉ" role="button" tabindex="0" aria-pressed="false"><i class="bi bi-arrow-left-right"></i></button> <div id="sp-meta"></div> <span id="search_bytes" class="yy-byte-badge"></span> <div id="sp-replace-meta" class="small">๊ฒ์์ด๋ฅผ ๋จผ์ ์ ๋ ฅํ์ธ์.</div> </div> <!-- โ Find / Replace ํ์ฅ ๋ฐ์ค --> <div id="sp-replace-box" style="" aria-hidden="false"> <div class="sp-replace-row"> <div class="sp-textarea-wrap"> <div id="sp-replace-lines" class="sp-lines">1</div> <textarea class="bt-tbn" id="sp-replace-input" placeholder="๋ฐ๊ฟ๋ง.." autocomplete="off" rows="1"></textarea> </div> <div class="sp-replace-actions"> <span type="button" id="sp-replace-auto-one" class="tb-btn sp-apply-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="์ฐพ์๋ง ๋ถ์ฌ๋ฃ๊ธฐ ๊ฒฐ๊ณผ๊ฐ 1๊ฑด์ผ ๋, ๋ฐ๊ฟ๋ง ๋ถ์ฌ๋ฃ๊ธฐ ํ 0.3์ด ๋ค 1๊ฐ์ ์ฉ ์๋ ์คํ">At</span> <span type="button" id="sp-replace-apply" class="tb-btn sp-apply-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="๊ฒ์์ด๋ฅผ ๋ฐ๊ฟ๋ง๋ก ์ ์ฒด ์ ์ฉ">์ ์ฒด์ ์ฉ</span> <span type="button" id="sp-replace-next" class="tb-btn sp-apply-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="ํ์ฌ ์์น๋ถํฐ ๋ค์ ๊ฒ์์ด๋ก ์ด๋">๋ค์์ฐพ๊ธฐ</span> <span type="button" id="sp-replace-one" class="tb-btn sp-apply-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="ํ์ฌ ์ ํ ๋๋ ํ์ฌ ์์น๋ถํฐ ์๋๋ก 1๊ฐ ์ฐพ์ ์ ์ฉ">1๊ฐ์ ์ฉ</span> <button id="sp-replace-double-ennter-line-to-one" class="btn icon-only tb-btn" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-title="์ฐ์ ๊ณต๋ฐฑ์ค์ 1๊ฐ ๊ณต๋ฐฑ์ค๋ก ์ค์ด๊ธฐ"> <i class="bi-arrows-collapse"></i></button> <span id="replace_bytes" class=""></span> </div> </div> </div> <!--๊ตฌsp-meta์๋ฆฌ --> <style> /*yyy_view.css๋ก์ด๋ํจ*/ #sp-input-wrap .sp-meta-row{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 4px; } .yy-byte-badge{ display:inline-flex; align-items:center; justify-content:center; height:22px; padding:0 8px; border-radius:999px; font-size:11px; line-height:22px; white-space:nowrap; border:1px solid var(--border); background:var(--panel2); color:var(--text); opacity:.92; } </style> <a id="sp-paste-jump" href="#sp-paste-jump" style="display:block;height:10px;overflow:hidden;">-----------</a> </div EndOf="id= sp-input-wrap"> <div id="sp-results"></div> </div EndOf="id=search-panel"> </div EndOf="94 id=yyy-view-shell"> <script src="yy__theme.js?v=1.3"></script> <script>window.YY_ZIP_DROP_TO_APPLY_CFG = Object.assign({}, window.YY_ZIP_DROP_TO_APPLY_CFG || {}, { viewDropUrl: "yyy_view.php" });</script> <script src="yy_zip_drop_to_apply.js?v=1.10"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <script src="<?php echo htmlspecialchars($YY_VIEW_JS, ENT_QUOTES, 'UTF-8'); ?>?v=<?php echo file_exists(__DIR__ . '/' . $YY_VIEW_JS) ? filemtime(__DIR__ . '/' . $YY_VIEW_JS) : '1234'; ?>"></script> <script src="yy_seg_toggle.js?v=1"></script> <div id="yy-alarm-timer-here"></div> </div> <div id="yy-toast-wrap"></div> </body> </html>
โจyyy_view.php
36,832 bytes
::
php
Y:0px 0%
X:0px 0%
Split:--
Line:1
A0
Aโ
A+
Lh0
Lhโ
Lh+
pre+
ฦ ํจ์ / ํด๋์ค ๋ชฉ๋ก
โ
๐พ
Aa
.*
bF
1
๐
๐
๊ฒ์์ด๋ฅผ ๋จผ์ ์ ๋ ฅํ์ธ์.
1
At
์ ์ฒด์ ์ฉ
๋ค์์ฐพ๊ธฐ
1๊ฐ์ ์ฉ
-----------