phnxhxr

phpfm

Dec 7th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 71.06 KB | None | 0 0
  1. <?php
  2. /**
  3. * PHP File Manager (2017-08-07)
  4. * https://github.com/alexantr/filemanager
  5. */
  6.  
  7. // Auth with login/password (set true/false to enable/disable it)
  8. $use_auth = true;
  9.  
  10. // Users: array('Username' => 'Password', 'Username2' => 'Password2', ...)
  11. $auth_users = array(
  12. 'nanang' => 'y',
  13. );
  14.  
  15. // Enable highlight.js (https://highlightjs.org/) on view's page
  16. $use_highlightjs = true;
  17.  
  18. // highlight.js style
  19. $highlightjs_style = 'vs';
  20.  
  21. // Default timezone for date() and time() - http://php.net/manual/en/timezones.php
  22. $default_timezone = 'Europe/Minsk'; // UTC+3
  23.  
  24. // Root path for file manager
  25. $root_path = $_SERVER['DOCUMENT_ROOT'];
  26.  
  27. // Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder'
  28. // Will not working if $root_path will be outside of server document root
  29. $root_url = '';
  30.  
  31. // Server hostname. Can set manually if wrong
  32. $http_host = $_SERVER['HTTP_HOST'];
  33.  
  34. // input encoding for iconv
  35. $iconv_input_encoding = 'CP1251';
  36.  
  37. // date() format for file modification date
  38. $datetime_format = 'd.m.y H:i';
  39.  
  40. //--- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL
  41.  
  42. // if fm included
  43. if (defined('FM_EMBED')) {
  44. $use_auth = false;
  45. } else {
  46. @set_time_limit(600);
  47.  
  48. date_default_timezone_set($default_timezone);
  49.  
  50. ini_set('default_charset', 'UTF-8');
  51. if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) {
  52. mb_internal_encoding('UTF-8');
  53. }
  54. if (function_exists('mb_regex_encoding')) {
  55. mb_regex_encoding('UTF-8');
  56. }
  57.  
  58. session_cache_limiter('');
  59. session_name('filemanager');
  60. session_start();
  61. }
  62.  
  63. if (empty($auth_users)) {
  64. $use_auth = false;
  65. }
  66.  
  67. $is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1)
  68. || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
  69.  
  70. // clean and check $root_path
  71. $root_path = rtrim($root_path, '\\/');
  72. $root_path = str_replace('\\', '/', $root_path);
  73. if (!@is_dir($root_path)) {
  74. echo sprintf('<h1>Root path "%s" not found!</h1>', fm_enc($root_path));
  75. exit;
  76. }
  77.  
  78. // clean $root_url
  79. $root_url = fm_clean_path($root_url);
  80.  
  81. // abs path for site
  82. defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path);
  83. defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : ''));
  84. defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']);
  85.  
  86. // logout
  87. if (isset($_GET['logout'])) {
  88. unset($_SESSION['logged']);
  89. fm_redirect(FM_SELF_URL);
  90. }
  91.  
  92. // Show image here
  93. if (isset($_GET['img'])) {
  94. fm_show_image($_GET['img']);
  95. }
  96.  
  97. // Auth
  98. if ($use_auth) {
  99. if (isset($_SESSION['logged'], $auth_users[$_SESSION['logged']])) {
  100. // Logged
  101. } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'])) {
  102. // Logging In
  103. sleep(1);
  104. if (isset($auth_users[$_POST['fm_usr']]) && $_POST['fm_pwd'] === $auth_users[$_POST['fm_usr']]) {
  105. $_SESSION['logged'] = $_POST['fm_usr'];
  106. fm_set_msg('You are logged in');
  107. fm_redirect(FM_SELF_URL . '?p=');
  108. } else {
  109. unset($_SESSION['logged']);
  110. fm_set_msg('Wrong password', 'error');
  111. fm_redirect(FM_SELF_URL);
  112. }
  113. } else {
  114. // Form
  115. unset($_SESSION['logged']);
  116. fm_show_header();
  117. fm_show_message();
  118. ?>
  119. <div class="path">
  120. <center><br><br><br><img src="https://4.bp.blogspot.com/-RXYYgWJbgQM/XYJX3Aght9I/AAAAAAAAEZU/XRvt_EHFw1QeIuuXoTg5ESyuF5hce63RgCLcBGAsYHQ/s640/yuru-yuri-mini-2.jpg" width="70%"/></center>
  121. <form action="" method="post" style="margin:10px;text-align:center">
  122. <input name="fm_usr" value="" placeholder="Username" required>
  123. <br><input type="password" name="fm_pwd" value="" placeholder="Password" required>
  124. <br><input type="submit" value="Login"><br><br>
  125. </form>
  126. </div>
  127. <?php
  128. fm_show_footer();
  129. exit;
  130. }
  131. }
  132.  
  133. define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\');
  134.  
  135. // always use ?p=
  136. if (!isset($_GET['p'])) {
  137. fm_redirect(FM_SELF_URL . '?p=');
  138. }
  139.  
  140. // get path
  141. $p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : '');
  142.  
  143. // clean path
  144. $p = fm_clean_path($p);
  145.  
  146. // instead globals vars
  147. define('FM_PATH', $p);
  148. define('FM_USE_AUTH', $use_auth);
  149.  
  150. defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding);
  151. defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs);
  152. defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style);
  153. defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format);
  154.  
  155. unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style);
  156.  
  157. /*************************** ACTIONS ***************************/
  158.  
  159. // Delete file / folder
  160. if (isset($_GET['del'])) {
  161. $del = $_GET['del'];
  162. $del = fm_clean_path($del);
  163. $del = str_replace('/', '', $del);
  164. if ($del != '' && $del != '..' && $del != '.') {
  165. $path = FM_ROOT_PATH;
  166. if (FM_PATH != '') {
  167. $path .= '/' . FM_PATH;
  168. }
  169. $is_dir = is_dir($path . '/' . $del);
  170. if (fm_rdelete($path . '/' . $del)) {
  171. $msg = $is_dir ? 'Folder <b>%s</b> deleted' : 'File <b>%s</b> deleted';
  172. fm_set_msg(sprintf($msg, fm_enc($del)));
  173. } else {
  174. $msg = $is_dir ? 'Folder <b>%s</b> not deleted' : 'File <b>%s</b> not deleted';
  175. fm_set_msg(sprintf($msg, fm_enc($del)), 'error');
  176. }
  177. } else {
  178. fm_set_msg('Wrong file or folder name', 'error');
  179. }
  180. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  181. }
  182.  
  183. // Create folder
  184. if (isset($_GET['new'])) {
  185. $new = strip_tags($_GET['new']); // remove unwanted characters from folder name
  186. $new = fm_clean_path($new);
  187. $new = str_replace('/', '', $new);
  188. if ($new != '' && $new != '..' && $new != '.') {
  189. $path = FM_ROOT_PATH;
  190. if (FM_PATH != '') {
  191. $path .= '/' . FM_PATH;
  192. }
  193. if (fm_mkdir($path . '/' . $new, false) === true) {
  194. fm_set_msg(sprintf('Folder <b>%s</b> created', fm_enc($new)));
  195. } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) {
  196. fm_set_msg(sprintf('Folder <b>%s</b> already exists', fm_enc($new)), 'alert');
  197. } else {
  198. fm_set_msg(sprintf('Folder <b>%s</b> not created', fm_enc($new)), 'error');
  199. }
  200. } else {
  201. fm_set_msg('Wrong folder name', 'error');
  202. }
  203. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  204. }
  205.  
  206. // Copy folder / file
  207. if (isset($_GET['copy'], $_GET['finish'])) {
  208. // from
  209. $copy = $_GET['copy'];
  210. $copy = fm_clean_path($copy);
  211. // empty path
  212. if ($copy == '') {
  213. fm_set_msg('Source path not defined', 'error');
  214. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  215. }
  216. // abs path from
  217. $from = FM_ROOT_PATH . '/' . $copy;
  218. // abs path to
  219. $dest = FM_ROOT_PATH;
  220. if (FM_PATH != '') {
  221. $dest .= '/' . FM_PATH;
  222. }
  223. $dest .= '/' . basename($from);
  224. // move?
  225. $move = isset($_GET['move']);
  226. // copy/move
  227. if ($from != $dest) {
  228. $msg_from = trim(FM_PATH . '/' . basename($from), '/');
  229. if ($move) {
  230. $rename = fm_rename($from, $dest);
  231. if ($rename) {
  232. fm_set_msg(sprintf('Moved from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
  233. } elseif ($rename === null) {
  234. fm_set_msg('File or folder with this path already exists', 'alert');
  235. } else {
  236. fm_set_msg(sprintf('Error while moving from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
  237. }
  238. } else {
  239. if (fm_rcopy($from, $dest)) {
  240. fm_set_msg(sprintf('Copyied from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
  241. } else {
  242. fm_set_msg(sprintf('Error while copying from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
  243. }
  244. }
  245. } else {
  246. fm_set_msg('Paths must be not equal', 'alert');
  247. }
  248. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  249. }
  250.  
  251. // Mass copy files/ folders
  252. if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish'])) {
  253. // from
  254. $path = FM_ROOT_PATH;
  255. if (FM_PATH != '') {
  256. $path .= '/' . FM_PATH;
  257. }
  258. // to
  259. $copy_to_path = FM_ROOT_PATH;
  260. $copy_to = fm_clean_path($_POST['copy_to']);
  261. if ($copy_to != '') {
  262. $copy_to_path .= '/' . $copy_to;
  263. }
  264. if ($path == $copy_to_path) {
  265. fm_set_msg('Paths must be not equal', 'alert');
  266. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  267. }
  268. if (!is_dir($copy_to_path)) {
  269. if (!fm_mkdir($copy_to_path, true)) {
  270. fm_set_msg('Unable to create destination folder', 'error');
  271. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  272. }
  273. }
  274. // move?
  275. $move = isset($_POST['move']);
  276. // copy/move
  277. $errors = 0;
  278. $files = $_POST['file'];
  279. if (is_array($files) && count($files)) {
  280. foreach ($files as $f) {
  281. if ($f != '') {
  282. // abs path from
  283. $from = $path . '/' . $f;
  284. // abs path to
  285. $dest = $copy_to_path . '/' . $f;
  286. // do
  287. if ($move) {
  288. $rename = fm_rename($from, $dest);
  289. if ($rename === false) {
  290. $errors++;
  291. }
  292. } else {
  293. if (!fm_rcopy($from, $dest)) {
  294. $errors++;
  295. }
  296. }
  297. }
  298. }
  299. if ($errors == 0) {
  300. $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied';
  301. fm_set_msg($msg);
  302. } else {
  303. $msg = $move ? 'Error while moving items' : 'Error while copying items';
  304. fm_set_msg($msg, 'error');
  305. }
  306. } else {
  307. fm_set_msg('Nothing selected', 'alert');
  308. }
  309. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  310. }
  311.  
  312. // Rename
  313. if (isset($_GET['ren'], $_GET['to'])) {
  314. // old name
  315. $old = $_GET['ren'];
  316. $old = fm_clean_path($old);
  317. $old = str_replace('/', '', $old);
  318. // new name
  319. $new = $_GET['to'];
  320. $new = fm_clean_path($new);
  321. $new = str_replace('/', '', $new);
  322. // path
  323. $path = FM_ROOT_PATH;
  324. if (FM_PATH != '') {
  325. $path .= '/' . FM_PATH;
  326. }
  327. // rename
  328. if ($old != '' && $new != '') {
  329. if (fm_rename($path . '/' . $old, $path . '/' . $new)) {
  330. fm_set_msg(sprintf('Renamed from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)));
  331. } else {
  332. fm_set_msg(sprintf('Error while renaming from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)), 'error');
  333. }
  334. } else {
  335. fm_set_msg('Names not set', 'error');
  336. }
  337. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  338. }
  339.  
  340. // Download
  341. if (isset($_GET['dl'])) {
  342. $dl = $_GET['dl'];
  343. $dl = fm_clean_path($dl);
  344. $dl = str_replace('/', '', $dl);
  345. $path = FM_ROOT_PATH;
  346. if (FM_PATH != '') {
  347. $path .= '/' . FM_PATH;
  348. }
  349. if ($dl != '' && is_file($path . '/' . $dl)) {
  350. header('Content-Description: File Transfer');
  351. header('Content-Type: application/octet-stream');
  352. header('Content-Disposition: attachment; filename="' . basename($path . '/' . $dl) . '"');
  353. header('Content-Transfer-Encoding: binary');
  354. header('Connection: Keep-Alive');
  355. header('Expires: 0');
  356. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  357. header('Pragma: public');
  358. header('Content-Length: ' . filesize($path . '/' . $dl));
  359. readfile($path . '/' . $dl);
  360. exit;
  361. } else {
  362. fm_set_msg('File not found', 'error');
  363. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  364. }
  365. }
  366.  
  367. // Upload
  368. if (isset($_POST['upl'])) {
  369. $path = FM_ROOT_PATH;
  370. if (FM_PATH != '') {
  371. $path .= '/' . FM_PATH;
  372. }
  373.  
  374. $errors = 0;
  375. $uploads = 0;
  376. $total = count($_FILES['upload']['name']);
  377.  
  378. for ($i = 0; $i < $total; $i++) {
  379. $tmp_name = $_FILES['upload']['tmp_name'][$i];
  380. if (empty($_FILES['upload']['error'][$i]) && !empty($tmp_name) && $tmp_name != 'none') {
  381. if (move_uploaded_file($tmp_name, $path . '/' . $_FILES['upload']['name'][$i])) {
  382. $uploads++;
  383. } else {
  384. $errors++;
  385. }
  386. }
  387. }
  388.  
  389. if ($errors == 0 && $uploads > 0) {
  390. fm_set_msg(sprintf('All files uploaded to <b>%s</b>', fm_enc($path)));
  391. } elseif ($errors == 0 && $uploads == 0) {
  392. fm_set_msg('Nothing uploaded', 'alert');
  393. } else {
  394. fm_set_msg(sprintf('Error while uploading files. Uploaded files: %s', $uploads), 'error');
  395. }
  396.  
  397. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  398. }
  399.  
  400. // Mass deleting
  401. if (isset($_POST['group'], $_POST['delete'])) {
  402. $path = FM_ROOT_PATH;
  403. if (FM_PATH != '') {
  404. $path .= '/' . FM_PATH;
  405. }
  406.  
  407. $errors = 0;
  408. $files = $_POST['file'];
  409. if (is_array($files) && count($files)) {
  410. foreach ($files as $f) {
  411. if ($f != '') {
  412. $new_path = $path . '/' . $f;
  413. if (!fm_rdelete($new_path)) {
  414. $errors++;
  415. }
  416. }
  417. }
  418. if ($errors == 0) {
  419. fm_set_msg('Selected files and folder deleted');
  420. } else {
  421. fm_set_msg('Error while deleting items', 'error');
  422. }
  423. } else {
  424. fm_set_msg('Nothing selected', 'alert');
  425. }
  426.  
  427. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  428. }
  429.  
  430. // Pack files
  431. if (isset($_POST['group'], $_POST['zip'])) {
  432. $path = FM_ROOT_PATH;
  433. if (FM_PATH != '') {
  434. $path .= '/' . FM_PATH;
  435. }
  436.  
  437. if (!class_exists('ZipArchive')) {
  438. fm_set_msg('Operations with archives are not available', 'error');
  439. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  440. }
  441.  
  442. $files = $_POST['file'];
  443. if (!empty($files)) {
  444. chdir($path);
  445.  
  446. if (count($files) == 1) {
  447. $one_file = reset($files);
  448. $one_file = basename($one_file);
  449. $zipname = $one_file . '_' . date('ymd_His') . '.zip';
  450. } else {
  451. $zipname = 'archive_' . date('ymd_His') . '.zip';
  452. }
  453.  
  454. $zipper = new FM_Zipper();
  455. $res = $zipper->create($zipname, $files);
  456.  
  457. if ($res) {
  458. fm_set_msg(sprintf('Archive <b>%s</b> created', fm_enc($zipname)));
  459. } else {
  460. fm_set_msg('Archive not created', 'error');
  461. }
  462. } else {
  463. fm_set_msg('Nothing selected', 'alert');
  464. }
  465.  
  466. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  467. }
  468.  
  469. // Unpack
  470. if (isset($_GET['unzip'])) {
  471. $unzip = $_GET['unzip'];
  472. $unzip = fm_clean_path($unzip);
  473. $unzip = str_replace('/', '', $unzip);
  474.  
  475. $path = FM_ROOT_PATH;
  476. if (FM_PATH != '') {
  477. $path .= '/' . FM_PATH;
  478. }
  479.  
  480. if (!class_exists('ZipArchive')) {
  481. fm_set_msg('Operations with archives are not available', 'error');
  482. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  483. }
  484.  
  485. if ($unzip != '' && is_file($path . '/' . $unzip)) {
  486. $zip_path = $path . '/' . $unzip;
  487.  
  488. //to folder
  489. $tofolder = '';
  490. if (isset($_GET['tofolder'])) {
  491. $tofolder = pathinfo($zip_path, PATHINFO_FILENAME);
  492. if (fm_mkdir($path . '/' . $tofolder, true)) {
  493. $path .= '/' . $tofolder;
  494. }
  495. }
  496.  
  497. $zipper = new FM_Zipper();
  498. $res = $zipper->unzip($zip_path, $path);
  499.  
  500. if ($res) {
  501. fm_set_msg('Archive unpacked');
  502. } else {
  503. fm_set_msg('Archive not unpacked', 'error');
  504. }
  505.  
  506. } else {
  507. fm_set_msg('File not found', 'error');
  508. }
  509. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  510. }
  511.  
  512. // Change Perms (not for Windows)
  513. if (isset($_POST['chmod']) && !FM_IS_WIN) {
  514. $path = FM_ROOT_PATH;
  515. if (FM_PATH != '') {
  516. $path .= '/' . FM_PATH;
  517. }
  518.  
  519. $file = $_POST['chmod'];
  520. $file = fm_clean_path($file);
  521. $file = str_replace('/', '', $file);
  522. if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
  523. fm_set_msg('File not found', 'error');
  524. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  525. }
  526.  
  527. $mode = 0;
  528. if (!empty($_POST['ur'])) {
  529. $mode |= 0400;
  530. }
  531. if (!empty($_POST['uw'])) {
  532. $mode |= 0200;
  533. }
  534. if (!empty($_POST['ux'])) {
  535. $mode |= 0100;
  536. }
  537. if (!empty($_POST['gr'])) {
  538. $mode |= 0040;
  539. }
  540. if (!empty($_POST['gw'])) {
  541. $mode |= 0020;
  542. }
  543. if (!empty($_POST['gx'])) {
  544. $mode |= 0010;
  545. }
  546. if (!empty($_POST['or'])) {
  547. $mode |= 0004;
  548. }
  549. if (!empty($_POST['ow'])) {
  550. $mode |= 0002;
  551. }
  552. if (!empty($_POST['ox'])) {
  553. $mode |= 0001;
  554. }
  555.  
  556. if (@chmod($path . '/' . $file, $mode)) {
  557. fm_set_msg('Permissions changed');
  558. } else {
  559. fm_set_msg('Permissions not changed', 'error');
  560. }
  561.  
  562. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  563. }
  564.  
  565. /*************************** /ACTIONS ***************************/
  566.  
  567. // get current path
  568. $path = FM_ROOT_PATH;
  569. if (FM_PATH != '') {
  570. $path .= '/' . FM_PATH;
  571. }
  572.  
  573. // check path
  574. if (!is_dir($path)) {
  575. fm_redirect(FM_SELF_URL . '?p=');
  576. }
  577.  
  578. // get parent folder
  579. $parent = fm_get_parent_path(FM_PATH);
  580.  
  581. $objects = is_readable($path) ? scandir($path) : array();
  582. $folders = array();
  583. $files = array();
  584. if (is_array($objects)) {
  585. foreach ($objects as $file) {
  586. if ($file == '.' || $file == '..') {
  587. continue;
  588. }
  589. $new_path = $path . '/' . $file;
  590. if (is_file($new_path)) {
  591. $files[] = $file;
  592. } elseif (is_dir($new_path) && $file != '.' && $file != '..') {
  593. $folders[] = $file;
  594. }
  595. }
  596. }
  597.  
  598. if (!empty($files)) {
  599. natcasesort($files);
  600. }
  601. if (!empty($folders)) {
  602. natcasesort($folders);
  603. }
  604.  
  605. // upload form
  606. if (isset($_GET['upload'])) {
  607. fm_show_header(); // HEADER
  608. fm_show_nav_path(FM_PATH); // current path
  609. ?>
  610. <div class="path">
  611. <p><b>Uploading files</b></p>
  612. <p class="break-word">Destination folder: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?></p>
  613. <form action="" method="post" enctype="multipart/form-data">
  614. <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
  615. <input type="hidden" name="upl" value="1">
  616. <input type="file" name="upload[]"><br>
  617. <input type="file" name="upload[]"><br>
  618. <input type="file" name="upload[]"><br>
  619. <input type="file" name="upload[]"><br>
  620. <input type="file" name="upload[]"><br>
  621. <br>
  622. <p>
  623. <button class="btn"><i class="icon-apply"></i> Upload</button> &nbsp;
  624. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="icon-cancel"></i> Cancel</a></b>
  625. </p>
  626. </form>
  627. </div>
  628. <?php
  629. fm_show_footer();
  630. exit;
  631. }
  632.  
  633. // copy form POST
  634. if (isset($_POST['copy'])) {
  635. $copy_files = $_POST['file'];
  636. if (!is_array($copy_files) || empty($copy_files)) {
  637. fm_set_msg('Nothing selected', 'alert');
  638. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  639. }
  640.  
  641. fm_show_header(); // HEADER
  642. fm_show_nav_path(FM_PATH); // current path
  643. ?>
  644. <div class="path">
  645. <p><b>Copying</b></p>
  646. <form action="" method="post">
  647. <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
  648. <input type="hidden" name="finish" value="1">
  649. <?php
  650. foreach ($copy_files as $cf) {
  651. echo '<input type="hidden" name="file[]" value="' . fm_enc($cf) . '">' . PHP_EOL;
  652. }
  653. $copy_files_enc = array_map('fm_enc', $copy_files);
  654. ?>
  655. <p class="break-word">Files: <b><?php echo implode('</b>, <b>', $copy_files_enc) ?></b></p>
  656. <p class="break-word">Source folder: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?><br>
  657. <label for="inp_copy_to">Destination folder:</label>
  658. <?php echo FM_ROOT_PATH ?>/<input name="copy_to" id="inp_copy_to" value="<?php echo fm_enc(FM_PATH) ?>">
  659. </p>
  660. <p><label><input type="checkbox" name="move" value="1"> Move</label></p>
  661. <p>
  662. <button class="btn"><i class="icon-apply"></i> Copy</button> &nbsp;
  663. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="icon-cancel"></i> Cancel</a></b>
  664. </p>
  665. </form>
  666. </div>
  667. <?php
  668. fm_show_footer();
  669. exit;
  670. }
  671.  
  672. // copy form
  673. if (isset($_GET['copy']) && !isset($_GET['finish'])) {
  674. $copy = $_GET['copy'];
  675. $copy = fm_clean_path($copy);
  676. if ($copy == '' || !file_exists(FM_ROOT_PATH . '/' . $copy)) {
  677. fm_set_msg('File not found', 'error');
  678. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  679. }
  680.  
  681. fm_show_header(); // HEADER
  682. fm_show_nav_path(FM_PATH); // current path
  683. ?>
  684. <div class="path">
  685. <p><b>Copying</b></p>
  686. <p class="break-word">
  687. Source path: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . $copy)) ?><br>
  688. Destination folder: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?>
  689. </p>
  690. <p>
  691. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&amp;copy=<?php echo urlencode($copy) ?>&amp;finish=1"><i class="icon-apply"></i> Copy</a></b> &nbsp;
  692. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&amp;copy=<?php echo urlencode($copy) ?>&amp;finish=1&amp;move=1"><i class="icon-apply"></i> Move</a></b> &nbsp;
  693. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="icon-cancel"></i> Cancel</a></b>
  694. </p>
  695. <p><i>Select folder:</i></p>
  696. <ul class="folders break-word">
  697. <?php
  698. if ($parent !== false) {
  699. ?>
  700. <li><a href="?p=<?php echo urlencode($parent) ?>&amp;copy=<?php echo urlencode($copy) ?>"><i class="icon-arrow_up"></i> ..</a></li>
  701. <?php
  702. }
  703. foreach ($folders as $f) {
  704. ?>
  705. <li><a href="?p=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>&amp;copy=<?php echo urlencode($copy) ?>"><i class="icon-folder"></i> <?php echo fm_enc(fm_convert_win($f)) ?></a></li>
  706. <?php
  707. }
  708. ?>
  709. </ul>
  710. </div>
  711. <?php
  712. fm_show_footer();
  713. exit;
  714. }
  715.  
  716. // file viewer
  717. if (isset($_GET['view'])) {
  718. $file = $_GET['view'];
  719. $file = fm_clean_path($file);
  720. $file = str_replace('/', '', $file);
  721. if ($file == '' || !is_file($path . '/' . $file)) {
  722. fm_set_msg('File not found', 'error');
  723. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  724. }
  725.  
  726. fm_show_header(); // HEADER
  727. fm_show_nav_path(FM_PATH); // current path
  728.  
  729. $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
  730. $file_path = $path . '/' . $file;
  731.  
  732. $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
  733. $mime_type = fm_get_mime_type($file_path);
  734. $filesize = filesize($file_path);
  735.  
  736. $is_zip = false;
  737. $is_image = false;
  738. $is_audio = false;
  739. $is_video = false;
  740. $is_text = false;
  741.  
  742. $view_title = 'File';
  743. $filenames = false; // for zip
  744. $content = ''; // for text
  745.  
  746. if ($ext == 'zip') {
  747. $is_zip = true;
  748. $view_title = 'Archive';
  749. $filenames = fm_get_zif_info($file_path);
  750. } elseif (in_array($ext, fm_get_image_exts())) {
  751. $is_image = true;
  752. $view_title = 'Image';
  753. } elseif (in_array($ext, fm_get_audio_exts())) {
  754. $is_audio = true;
  755. $view_title = 'Audio';
  756. } elseif (in_array($ext, fm_get_video_exts())) {
  757. $is_video = true;
  758. $view_title = 'Video';
  759. } elseif (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) {
  760. $is_text = true;
  761. $content = file_get_contents($file_path);
  762. }
  763.  
  764. ?>
  765. <div class="path">
  766. <p class="break-word"><b><?php echo $view_title ?> "<?php echo fm_enc(fm_convert_win($file)) ?>"</b></p>
  767. <p class="break-word">
  768. Full path: <?php echo fm_enc(fm_convert_win($file_path)) ?><br>
  769. File size: <?php echo fm_get_filesize($filesize) ?><?php if ($filesize >= 1000): ?> (<?php echo sprintf('%s bytes', $filesize) ?>)<?php endif; ?><br>
  770. MIME-type: <?php echo $mime_type ?><br>
  771. <?php
  772. // ZIP info
  773. if ($is_zip && $filenames !== false) {
  774. $total_files = 0;
  775. $total_comp = 0;
  776. $total_uncomp = 0;
  777. foreach ($filenames as $fn) {
  778. if (!$fn['folder']) {
  779. $total_files++;
  780. }
  781. $total_comp += $fn['compressed_size'];
  782. $total_uncomp += $fn['filesize'];
  783. }
  784. ?>
  785. Files in archive: <?php echo $total_files ?><br>
  786. Total size: <?php echo fm_get_filesize($total_uncomp) ?><br>
  787. Size in archive: <?php echo fm_get_filesize($total_comp) ?><br>
  788. Compression: <?php echo round(($total_comp / $total_uncomp) * 100) ?>%<br>
  789. <?php
  790. }
  791. // Image info
  792. if ($is_image) {
  793. $image_size = getimagesize($file_path);
  794. echo 'Image sizes: ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '<br>';
  795. }
  796. // Text info
  797. if ($is_text) {
  798. $is_utf8 = fm_is_utf8($content);
  799. if (function_exists('iconv')) {
  800. if (!$is_utf8) {
  801. $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content);
  802. }
  803. }
  804. echo 'Charset: ' . ($is_utf8 ? 'utf-8' : '8 bit') . '<br>';
  805. }
  806. ?>
  807. </p>
  808. <p>
  809. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&amp;dl=<?php echo urlencode($file) ?>"><i class="icon-download"></i> Download</a></b> &nbsp;
  810. <b><a href="<?php echo fm_enc($file_url) ?>" target="_blank"><i class="icon-chain"></i> Open</a></b> &nbsp;
  811. <?php
  812. // ZIP actions
  813. if ($is_zip && $filenames !== false) {
  814. $zip_name = pathinfo($file_path, PATHINFO_FILENAME);
  815. ?>
  816. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&amp;unzip=<?php echo urlencode($file) ?>"><i class="icon-apply"></i> Unpack</a></b> &nbsp;
  817. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&amp;unzip=<?php echo urlencode($file) ?>&amp;tofolder=1" title="Unpack to <?php echo fm_enc($zip_name) ?>"><i class="icon-apply"></i>
  818. Unpack to folder</a></b> &nbsp;
  819. <?php
  820. }
  821. ?>
  822. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="icon-goback"></i> Back</a></b>
  823. </p>
  824. <?php
  825. if ($is_zip) {
  826. // ZIP content
  827. if ($filenames !== false) {
  828. echo '<code class="maxheight">';
  829. foreach ($filenames as $fn) {
  830. if ($fn['folder']) {
  831. echo '<b>' . fm_enc($fn['name']) . '</b><br>';
  832. } else {
  833. echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')<br>';
  834. }
  835. }
  836. echo '</code>';
  837. } else {
  838. echo '<p>Error while fetching archive info</p>';
  839. }
  840. } elseif ($is_image) {
  841. // Image content
  842. if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico'))) {
  843. echo '<p><img src="' . fm_enc($file_url) . '" alt="" class="preview-img"></p>';
  844. }
  845. } elseif ($is_audio) {
  846. // Audio content
  847. echo '<p><audio src="' . fm_enc($file_url) . '" controls preload="metadata"></audio></p>';
  848. } elseif ($is_video) {
  849. // Video content
  850. echo '<div class="preview-video"><video src="' . fm_enc($file_url) . '" width="640" height="360" controls preload="metadata"></video></div>';
  851. } elseif ($is_text) {
  852. if (FM_USE_HIGHLIGHTJS) {
  853. // highlight
  854. $hljs_classes = array(
  855. 'shtml' => 'xml',
  856. 'htaccess' => 'apache',
  857. 'phtml' => 'php',
  858. 'lock' => 'json',
  859. 'svg' => 'xml',
  860. );
  861. $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext;
  862. if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) {
  863. $hljs_class = 'nohighlight';
  864. }
  865. $content = '<pre class="with-hljs"><code class="' . $hljs_class . '">' . fm_enc($content) . '</code></pre>';
  866. } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) {
  867. // php highlight
  868. $content = highlight_string($content, true);
  869. } else {
  870. $content = '<pre>' . fm_enc($content) . '</pre>';
  871. }
  872. echo $content;
  873. }
  874. ?>
  875. </div>
  876. <?php
  877. fm_show_footer();
  878. exit;
  879. }
  880.  
  881. // chmod (not for Windows)
  882. if (isset($_GET['chmod']) && !FM_IS_WIN) {
  883. $file = $_GET['chmod'];
  884. $file = fm_clean_path($file);
  885. $file = str_replace('/', '', $file);
  886. if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
  887. fm_set_msg('File not found', 'error');
  888. fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
  889. }
  890.  
  891. fm_show_header(); // HEADER
  892. fm_show_nav_path(FM_PATH); // current path
  893.  
  894. $file_url = FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file;
  895. $file_path = $path . '/' . $file;
  896.  
  897. $mode = fileperms($path . '/' . $file);
  898.  
  899. ?>
  900. <div class="path">
  901. <p><b>Change Permissions</b></p>
  902. <p>
  903. Full path: <?php echo fm_enc($file_path) ?><br>
  904. </p>
  905. <form action="" method="post">
  906. <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
  907. <input type="hidden" name="chmod" value="<?php echo fm_enc($file) ?>">
  908.  
  909. <table class="compact-table">
  910. <tr>
  911. <td></td>
  912. <td><b>Owner</b></td>
  913. <td><b>Group</b></td>
  914. <td><b>Other</b></td>
  915. </tr>
  916. <tr>
  917. <td style="text-align: right"><b>Read</b></td>
  918. <td><label><input type="checkbox" name="ur" value="1"<?php echo ($mode & 00400) ? ' checked' : '' ?>></label></td>
  919. <td><label><input type="checkbox" name="gr" value="1"<?php echo ($mode & 00040) ? ' checked' : '' ?>></label></td>
  920. <td><label><input type="checkbox" name="or" value="1"<?php echo ($mode & 00004) ? ' checked' : '' ?>></label></td>
  921. </tr>
  922. <tr>
  923. <td style="text-align: right"><b>Write</b></td>
  924. <td><label><input type="checkbox" name="uw" value="1"<?php echo ($mode & 00200) ? ' checked' : '' ?>></label></td>
  925. <td><label><input type="checkbox" name="gw" value="1"<?php echo ($mode & 00020) ? ' checked' : '' ?>></label></td>
  926. <td><label><input type="checkbox" name="ow" value="1"<?php echo ($mode & 00002) ? ' checked' : '' ?>></label></td>
  927. </tr>
  928. <tr>
  929. <td style="text-align: right"><b>Execute</b></td>
  930. <td><label><input type="checkbox" name="ux" value="1"<?php echo ($mode & 00100) ? ' checked' : '' ?>></label></td>
  931. <td><label><input type="checkbox" name="gx" value="1"<?php echo ($mode & 00010) ? ' checked' : '' ?>></label></td>
  932. <td><label><input type="checkbox" name="ox" value="1"<?php echo ($mode & 00001) ? ' checked' : '' ?>></label></td>
  933. </tr>
  934. </table>
  935.  
  936. <p>
  937. <button class="btn"><i class="icon-apply"></i> Change</button> &nbsp;
  938. <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="icon-cancel"></i> Cancel</a></b>
  939. </p>
  940.  
  941. </form>
  942.  
  943. </div>
  944. <?php
  945. fm_show_footer();
  946. exit;
  947. }
  948.  
  949. //--- FILEMANAGER MAIN
  950. fm_show_header(); // HEADER
  951. fm_show_nav_path(FM_PATH); // current path
  952.  
  953. // messages
  954. fm_show_message();
  955.  
  956. $num_files = count($files);
  957. $num_folders = count($folders);
  958. $all_files_size = 0;
  959. ?>
  960. <form action="" method="post">
  961. <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
  962. <input type="hidden" name="group" value="1">
  963. <table><tr>
  964. <th style="width:3%"><label><input type="checkbox" title="Invert selection" onclick="checkbox_toggle()"></label></th>
  965. <th>Name</th><th style="width:10%">Size</th>
  966. <th style="width:12%">Modified</th>
  967. <?php if (!FM_IS_WIN): ?><th style="width:6%">Perms</th><th style="width:10%">Owner</th><?php endif; ?>
  968. <th style="width:13%"></th></tr>
  969. <?php
  970. // link to parent folder
  971. if ($parent !== false) {
  972. ?>
  973. <tr><td></td><td colspan="<?php echo !FM_IS_WIN ? '6' : '4' ?>"><a href="?p=<?php echo urlencode($parent) ?>"><i class="icon-arrow_up"></i> ..</a></td></tr>
  974. <?php
  975. }
  976. foreach ($folders as $f) {
  977. $is_link = is_link($path . '/' . $f);
  978. $img = $is_link ? 'icon-link_folder' : 'icon-folder';
  979. $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
  980. $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
  981. if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
  982. $owner = posix_getpwuid(fileowner($path . '/' . $f));
  983. $group = posix_getgrgid(filegroup($path . '/' . $f));
  984. } else {
  985. $owner = array('name' => '?');
  986. $group = array('name' => '?');
  987. }
  988. ?>
  989. <tr>
  990. <td><label><input type="checkbox" name="file[]" value="<?php echo fm_enc($f) ?>"></label></td>
  991. <td><div class="filename"><a href="?p=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="<?php echo $img ?>"></i> <?php echo fm_enc(fm_convert_win($f)) ?></a><?php echo ($is_link ? ' &rarr; <i>' . fm_enc(readlink($path . '/' . $f)) . '</i>' : '') ?></div></td>
  992. <td>Folder</td><td><?php echo $modif ?></td>
  993. <?php if (!FM_IS_WIN): ?>
  994. <td><a title="Change Permissions" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;chmod=<?php echo urlencode($f) ?>"><?php echo $perms ?></a></td>
  995. <td><?php echo fm_enc($owner['name'] . ':' . $group['name']) ?></td>
  996. <?php endif; ?>
  997. <td>
  998. <a title="Delete" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;del=<?php echo urlencode($f) ?>" onclick="return confirm('Delete folder?');"><i class="icon-cross"></i></a>
  999. <a title="Rename" href="#" onclick="rename('<?php echo fm_enc(FM_PATH) ?>', '<?php echo fm_enc($f) ?>');return false;"><i class="icon-rename"></i></a>
  1000. <a title="Copy to..." href="?p=&amp;copy=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="icon-copy"></i></a>
  1001. <a title="Direct link" href="<?php echo fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $f . '/') ?>" target="_blank"><i class="icon-chain"></i></a>
  1002. </td></tr>
  1003. <?php
  1004. flush();
  1005. }
  1006.  
  1007. foreach ($files as $f) {
  1008. $is_link = is_link($path . '/' . $f);
  1009. $img = $is_link ? 'icon-link_file' : fm_get_file_icon_class($path . '/' . $f);
  1010. $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
  1011. $filesize_raw = filesize($path . '/' . $f);
  1012. $filesize = fm_get_filesize($filesize_raw);
  1013. $filelink = '?p=' . urlencode(FM_PATH) . '&view=' . urlencode($f);
  1014. $all_files_size += $filesize_raw;
  1015. $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
  1016. if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
  1017. $owner = posix_getpwuid(fileowner($path . '/' . $f));
  1018. $group = posix_getgrgid(filegroup($path . '/' . $f));
  1019. } else {
  1020. $owner = array('name' => '?');
  1021. $group = array('name' => '?');
  1022. }
  1023. ?>
  1024. <tr>
  1025. <td><label><input type="checkbox" name="file[]" value="<?php echo fm_enc($f) ?>"></label></td>
  1026. <td><div class="filename"><a href="<?php echo fm_enc($filelink) ?>" title="File info"><i class="<?php echo $img ?>"></i> <?php echo fm_enc(fm_convert_win($f)) ?></a><?php echo ($is_link ? ' &rarr; <i>' . fm_enc(readlink($path . '/' . $f)) . '</i>' : '') ?></div></td>
  1027. <td><span class="gray" title="<?php printf('%s bytes', $filesize_raw) ?>"><?php echo $filesize ?></span></td>
  1028. <td><?php echo $modif ?></td>
  1029. <?php if (!FM_IS_WIN): ?>
  1030. <td><a title="Change Permissions" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;chmod=<?php echo urlencode($f) ?>"><?php echo $perms ?></a></td>
  1031. <td><?php echo fm_enc($owner['name'] . ':' . $group['name']) ?></td>
  1032. <?php endif; ?>
  1033. <td>
  1034. <a title="Delete" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;del=<?php echo urlencode($f) ?>" onclick="return confirm('Delete file?');"><i class="icon-cross"></i></a>
  1035. <a title="Rename" href="#" onclick="rename('<?php echo fm_enc(FM_PATH) ?>', '<?php echo fm_enc($f) ?>');return false;"><i class="icon-rename"></i></a>
  1036. <a title="Copy to..." href="?p=<?php echo urlencode(FM_PATH) ?>&amp;copy=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="icon-copy"></i></a>
  1037. <a title="Direct link" href="<?php echo fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $f) ?>" target="_blank"><i class="icon-chain"></i></a>
  1038. <a title="Download" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;dl=<?php echo urlencode($f) ?>"><i class="icon-download"></i></a>
  1039. </td></tr>
  1040. <?php
  1041. flush();
  1042. }
  1043.  
  1044. if (empty($folders) && empty($files)) {
  1045. ?>
  1046. <tr><td></td><td colspan="<?php echo !FM_IS_WIN ? '6' : '4' ?>"><em>Folder is empty</em></td></tr>
  1047. <?php
  1048. } else {
  1049. ?>
  1050. <tr><td class="gray"></td><td class="gray" colspan="<?php echo !FM_IS_WIN ? '6' : '4' ?>">
  1051. Full size: <span title="<?php printf('%s bytes', $all_files_size) ?>"><?php echo fm_get_filesize($all_files_size) ?></span>,
  1052. files: <?php echo $num_files ?>,
  1053. folders: <?php echo $num_folders ?>
  1054. </td></tr>
  1055. <?php
  1056. }
  1057. ?>
  1058. </table>
  1059. <p class="path"><a href="#" onclick="select_all();return false;"><i class="icon-checkbox"></i> Select all</a> &nbsp;
  1060. <a href="#" onclick="unselect_all();return false;"><i class="icon-checkbox_uncheck"></i> Unselect all</a> &nbsp;
  1061. <a href="#" onclick="invert_all();return false;"><i class="icon-checkbox_invert"></i> Invert selection</a></p>
  1062. <p><input type="submit" name="delete" value="Delete" onclick="return confirm('Delete selected files and folders?')">
  1063. <input type="submit" name="zip" value="Pack" onclick="return confirm('Create archive?')">
  1064. <input type="submit" name="copy" value="Copy"></p>
  1065. </form>
  1066.  
  1067. <?php
  1068. fm_show_footer();
  1069.  
  1070. //--- END
  1071.  
  1072. // Functions
  1073.  
  1074. /**
  1075. * Delete file or folder (recursively)
  1076. * @param string $path
  1077. * @return bool
  1078. */
  1079. function fm_rdelete($path)
  1080. {
  1081. if (is_link($path)) {
  1082. return unlink($path);
  1083. } elseif (is_dir($path)) {
  1084. $objects = scandir($path);
  1085. $ok = true;
  1086. if (is_array($objects)) {
  1087. foreach ($objects as $file) {
  1088. if ($file != '.' && $file != '..') {
  1089. if (!fm_rdelete($path . '/' . $file)) {
  1090. $ok = false;
  1091. }
  1092. }
  1093. }
  1094. }
  1095. return ($ok) ? rmdir($path) : false;
  1096. } elseif (is_file($path)) {
  1097. return unlink($path);
  1098. }
  1099. return false;
  1100. }
  1101.  
  1102. /**
  1103. * Recursive chmod
  1104. * @param string $path
  1105. * @param int $filemode
  1106. * @param int $dirmode
  1107. * @return bool
  1108. * @todo Will use in mass chmod
  1109. */
  1110. function fm_rchmod($path, $filemode, $dirmode)
  1111. {
  1112. if (is_dir($path)) {
  1113. if (!chmod($path, $dirmode)) {
  1114. return false;
  1115. }
  1116. $objects = scandir($path);
  1117. if (is_array($objects)) {
  1118. foreach ($objects as $file) {
  1119. if ($file != '.' && $file != '..') {
  1120. if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) {
  1121. return false;
  1122. }
  1123. }
  1124. }
  1125. }
  1126. return true;
  1127. } elseif (is_link($path)) {
  1128. return true;
  1129. } elseif (is_file($path)) {
  1130. return chmod($path, $filemode);
  1131. }
  1132. return false;
  1133. }
  1134.  
  1135. /**
  1136. * Safely rename
  1137. * @param string $old
  1138. * @param string $new
  1139. * @return bool|null
  1140. */
  1141. function fm_rename($old, $new)
  1142. {
  1143. return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null;
  1144. }
  1145.  
  1146. /**
  1147. * Copy file or folder (recursively).
  1148. * @param string $path
  1149. * @param string $dest
  1150. * @param bool $upd Update files
  1151. * @param bool $force Create folder with same names instead file
  1152. * @return bool
  1153. */
  1154. function fm_rcopy($path, $dest, $upd = true, $force = true)
  1155. {
  1156. if (is_dir($path)) {
  1157. if (!fm_mkdir($dest, $force)) {
  1158. return false;
  1159. }
  1160. $objects = scandir($path);
  1161. $ok = true;
  1162. if (is_array($objects)) {
  1163. foreach ($objects as $file) {
  1164. if ($file != '.' && $file != '..') {
  1165. if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) {
  1166. $ok = false;
  1167. }
  1168. }
  1169. }
  1170. }
  1171. return $ok;
  1172. } elseif (is_file($path)) {
  1173. return fm_copy($path, $dest, $upd);
  1174. }
  1175. return false;
  1176. }
  1177.  
  1178. /**
  1179. * Safely create folder
  1180. * @param string $dir
  1181. * @param bool $force
  1182. * @return bool
  1183. */
  1184. function fm_mkdir($dir, $force)
  1185. {
  1186. if (file_exists($dir)) {
  1187. if (is_dir($dir)) {
  1188. return $dir;
  1189. } elseif (!$force) {
  1190. return false;
  1191. }
  1192. unlink($dir);
  1193. }
  1194. return mkdir($dir, 0777, true);
  1195. }
  1196.  
  1197. /**
  1198. * Safely copy file
  1199. * @param string $f1
  1200. * @param string $f2
  1201. * @param bool $upd
  1202. * @return bool
  1203. */
  1204. function fm_copy($f1, $f2, $upd)
  1205. {
  1206. $time1 = filemtime($f1);
  1207. if (file_exists($f2)) {
  1208. $time2 = filemtime($f2);
  1209. if ($time2 >= $time1 && $upd) {
  1210. return false;
  1211. }
  1212. }
  1213. $ok = copy($f1, $f2);
  1214. if ($ok) {
  1215. touch($f2, $time1);
  1216. }
  1217. return $ok;
  1218. }
  1219.  
  1220. /**
  1221. * Get mime type
  1222. * @param string $file_path
  1223. * @return mixed|string
  1224. */
  1225. function fm_get_mime_type($file_path)
  1226. {
  1227. if (function_exists('finfo_open')) {
  1228. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  1229. $mime = finfo_file($finfo, $file_path);
  1230. finfo_close($finfo);
  1231. return $mime;
  1232. } elseif (function_exists('mime_content_type')) {
  1233. return mime_content_type($file_path);
  1234. } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) {
  1235. $file = escapeshellarg($file_path);
  1236. $mime = shell_exec('file -bi ' . $file);
  1237. return $mime;
  1238. } else {
  1239. return '--';
  1240. }
  1241. }
  1242.  
  1243. /**
  1244. * HTTP Redirect
  1245. * @param string $url
  1246. * @param int $code
  1247. */
  1248. function fm_redirect($url, $code = 302)
  1249. {
  1250. header('Location: ' . $url, true, $code);
  1251. exit;
  1252. }
  1253.  
  1254. /**
  1255. * Clean path
  1256. * @param string $path
  1257. * @return string
  1258. */
  1259. function fm_clean_path($path)
  1260. {
  1261. $path = trim($path);
  1262. $path = trim($path, '\\/');
  1263. $path = str_replace(array('../', '..\\'), '', $path);
  1264. if ($path == '..') {
  1265. $path = '';
  1266. }
  1267. return str_replace('\\', '/', $path);
  1268. }
  1269.  
  1270. /**
  1271. * Get parent path
  1272. * @param string $path
  1273. * @return bool|string
  1274. */
  1275. function fm_get_parent_path($path)
  1276. {
  1277. $path = fm_clean_path($path);
  1278. if ($path != '') {
  1279. $array = explode('/', $path);
  1280. if (count($array) > 1) {
  1281. $array = array_slice($array, 0, -1);
  1282. return implode('/', $array);
  1283. }
  1284. return '';
  1285. }
  1286. return false;
  1287. }
  1288.  
  1289. /**
  1290. * Get nice filesize
  1291. * @param int $size
  1292. * @return string
  1293. */
  1294. function fm_get_filesize($size)
  1295. {
  1296. if ($size < 1000) {
  1297. return sprintf('%s B', $size);
  1298. } elseif (($size / 1024) < 1000) {
  1299. return sprintf('%s KiB', round(($size / 1024), 2));
  1300. } elseif (($size / 1024 / 1024) < 1000) {
  1301. return sprintf('%s MiB', round(($size / 1024 / 1024), 2));
  1302. } elseif (($size / 1024 / 1024 / 1024) < 1000) {
  1303. return sprintf('%s GiB', round(($size / 1024 / 1024 / 1024), 2));
  1304. } else {
  1305. return sprintf('%s TiB', round(($size / 1024 / 1024 / 1024 / 1024), 2));
  1306. }
  1307. }
  1308.  
  1309. /**
  1310. * Get info about zip archive
  1311. * @param string $path
  1312. * @return array|bool
  1313. */
  1314. function fm_get_zif_info($path)
  1315. {
  1316. if (function_exists('zip_open')) {
  1317. $arch = zip_open($path);
  1318. if ($arch) {
  1319. $filenames = array();
  1320. while ($zip_entry = zip_read($arch)) {
  1321. $zip_name = zip_entry_name($zip_entry);
  1322. $zip_folder = substr($zip_name, -1) == '/';
  1323. $filenames[] = array(
  1324. 'name' => $zip_name,
  1325. 'filesize' => zip_entry_filesize($zip_entry),
  1326. 'compressed_size' => zip_entry_compressedsize($zip_entry),
  1327. 'folder' => $zip_folder
  1328. //'compression_method' => zip_entry_compressionmethod($zip_entry),
  1329. );
  1330. }
  1331. zip_close($arch);
  1332. return $filenames;
  1333. }
  1334. }
  1335. return false;
  1336. }
  1337.  
  1338. /**
  1339. * Encode html entities
  1340. * @param string $text
  1341. * @return string
  1342. */
  1343. function fm_enc($text)
  1344. {
  1345. return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
  1346. }
  1347.  
  1348. /**
  1349. * Save message in session
  1350. * @param string $msg
  1351. * @param string $status
  1352. */
  1353. function fm_set_msg($msg, $status = 'ok')
  1354. {
  1355. $_SESSION['message'] = $msg;
  1356. $_SESSION['status'] = $status;
  1357. }
  1358.  
  1359. /**
  1360. * Check if string is in UTF-8
  1361. * @param string $string
  1362. * @return int
  1363. */
  1364. function fm_is_utf8($string)
  1365. {
  1366. return preg_match('//u', $string);
  1367. }
  1368.  
  1369. /**
  1370. * Convert file name to UTF-8 in Windows
  1371. * @param string $filename
  1372. * @return string
  1373. */
  1374. function fm_convert_win($filename)
  1375. {
  1376. if (FM_IS_WIN && function_exists('iconv')) {
  1377. $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename);
  1378. }
  1379. return $filename;
  1380. }
  1381.  
  1382. /**
  1383. * Get CSS classname for file
  1384. * @param string $path
  1385. * @return string
  1386. */
  1387. function fm_get_file_icon_class($path)
  1388. {
  1389. // get extension
  1390. $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
  1391.  
  1392. switch ($ext) {
  1393. case 'ico': case 'gif': case 'jpg': case 'jpeg': case 'jpc': case 'jp2':
  1394. case 'jpx': case 'xbm': case 'wbmp': case 'png': case 'bmp': case 'tif':
  1395. case 'tiff':
  1396. $img = 'icon-file_image';
  1397. break;
  1398. case 'txt': case 'css': case 'ini': case 'conf': case 'log': case 'htaccess':
  1399. case 'passwd': case 'ftpquota': case 'sql': case 'js': case 'json': case 'sh':
  1400. case 'config': case 'twig': case 'tpl': case 'md': case 'gitignore':
  1401. case 'less': case 'sass': case 'scss': case 'c': case 'cpp': case 'cs': case 'py':
  1402. case 'map': case 'lock': case 'dtd':
  1403. $img = 'icon-file_text';
  1404. break;
  1405. case 'zip': case 'rar': case 'gz': case 'tar': case '7z':
  1406. $img = 'icon-file_zip';
  1407. break;
  1408. case 'php': case 'php4': case 'php5': case 'phps': case 'phtml':
  1409. $img = 'icon-file_php';
  1410. break;
  1411. case 'htm': case 'html': case 'shtml': case 'xhtml':
  1412. $img = 'icon-file_html';
  1413. break;
  1414. case 'xml': case 'xsl': case 'svg':
  1415. $img = 'icon-file_code';
  1416. break;
  1417. case 'wav': case 'mp3': case 'mp2': case 'm4a': case 'aac': case 'ogg':
  1418. case 'oga': case 'wma': case 'mka': case 'flac': case 'ac3': case 'tds':
  1419. $img = 'icon-file_music';
  1420. break;
  1421. case 'm3u': case 'm3u8': case 'pls': case 'cue':
  1422. $img = 'icon-file_playlist';
  1423. break;
  1424. case 'avi': case 'mpg': case 'mpeg': case 'mp4': case 'm4v': case 'flv':
  1425. case 'f4v': case 'ogm': case 'ogv': case 'mov': case 'mkv': case '3gp':
  1426. case 'asf': case 'wmv':
  1427. $img = 'icon-file_film';
  1428. break;
  1429. case 'eml': case 'msg':
  1430. $img = 'icon-file_outlook';
  1431. break;
  1432. case 'xls': case 'xlsx':
  1433. $img = 'icon-file_excel';
  1434. break;
  1435. case 'csv':
  1436. $img = 'icon-file_csv';
  1437. break;
  1438. case 'doc': case 'docx':
  1439. $img = 'icon-file_word';
  1440. break;
  1441. case 'ppt': case 'pptx':
  1442. $img = 'icon-file_powerpoint';
  1443. break;
  1444. case 'ttf': case 'ttc': case 'otf': case 'woff':case 'woff2': case 'eot': case 'fon':
  1445. $img = 'icon-file_font';
  1446. break;
  1447. case 'pdf':
  1448. $img = 'icon-file_pdf';
  1449. break;
  1450. case 'psd':
  1451. $img = 'icon-file_photoshop';
  1452. break;
  1453. case 'ai': case 'eps':
  1454. $img = 'icon-file_illustrator';
  1455. break;
  1456. case 'fla':
  1457. $img = 'icon-file_flash';
  1458. break;
  1459. case 'swf':
  1460. $img = 'icon-file_swf';
  1461. break;
  1462. case 'exe': case 'msi':
  1463. $img = 'icon-file_application';
  1464. break;
  1465. case 'bat':
  1466. $img = 'icon-file_terminal';
  1467. break;
  1468. default:
  1469. $img = 'icon-document';
  1470. }
  1471.  
  1472. return $img;
  1473. }
  1474.  
  1475. /**
  1476. * Get image files extensions
  1477. * @return array
  1478. */
  1479. function fm_get_image_exts()
  1480. {
  1481. return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd');
  1482. }
  1483.  
  1484. /**
  1485. * Get video files extensions
  1486. * @return array
  1487. */
  1488. function fm_get_video_exts()
  1489. {
  1490. return array('webm', 'mp4', 'm4v', 'ogm', 'ogv', 'mov');
  1491. }
  1492.  
  1493. /**
  1494. * Get audio files extensions
  1495. * @return array
  1496. */
  1497. function fm_get_audio_exts()
  1498. {
  1499. return array('wav', 'mp3', 'ogg', 'm4a');
  1500. }
  1501.  
  1502. /**
  1503. * Get text file extensions
  1504. * @return array
  1505. */
  1506. function fm_get_text_exts()
  1507. {
  1508. return array(
  1509. 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'json', 'sh', 'config',
  1510. 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue',
  1511. 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py',
  1512. 'map', 'lock', 'dtd', 'svg',
  1513. );
  1514. }
  1515.  
  1516. /**
  1517. * Get mime types of text files
  1518. * @return array
  1519. */
  1520. function fm_get_text_mimes()
  1521. {
  1522. return array(
  1523. 'application/xml',
  1524. 'application/javascript',
  1525. 'application/x-javascript',
  1526. 'image/svg+xml',
  1527. 'message/rfc822',
  1528. );
  1529. }
  1530.  
  1531. /**
  1532. * Get file names of text files w/o extensions
  1533. * @return array
  1534. */
  1535. function fm_get_text_names()
  1536. {
  1537. return array(
  1538. 'license',
  1539. 'readme',
  1540. 'authors',
  1541. 'contributors',
  1542. 'changelog',
  1543. );
  1544. }
  1545.  
  1546. /**
  1547. * Class to work with zip files (using ZipArchive)
  1548. */
  1549. class FM_Zipper
  1550. {
  1551. private $zip;
  1552.  
  1553. public function __construct()
  1554. {
  1555. $this->zip = new ZipArchive();
  1556. }
  1557.  
  1558. /**
  1559. * Create archive with name $filename and files $files (RELATIVE PATHS!)
  1560. * @param string $filename
  1561. * @param array|string $files
  1562. * @return bool
  1563. */
  1564. public function create($filename, $files)
  1565. {
  1566. $res = $this->zip->open($filename, ZipArchive::CREATE);
  1567. if ($res !== true) {
  1568. return false;
  1569. }
  1570. if (is_array($files)) {
  1571. foreach ($files as $f) {
  1572. if (!$this->addFileOrDir($f)) {
  1573. $this->zip->close();
  1574. return false;
  1575. }
  1576. }
  1577. $this->zip->close();
  1578. return true;
  1579. } else {
  1580. if ($this->addFileOrDir($files)) {
  1581. $this->zip->close();
  1582. return true;
  1583. }
  1584. return false;
  1585. }
  1586. }
  1587.  
  1588. /**
  1589. * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS)
  1590. * @param string $filename
  1591. * @param string $path
  1592. * @return bool
  1593. */
  1594. public function unzip($filename, $path)
  1595. {
  1596. $res = $this->zip->open($filename);
  1597. if ($res !== true) {
  1598. return false;
  1599. }
  1600. if ($this->zip->extractTo($path)) {
  1601. $this->zip->close();
  1602. return true;
  1603. }
  1604. return false;
  1605. }
  1606.  
  1607. /**
  1608. * Add file/folder to archive
  1609. * @param string $filename
  1610. * @return bool
  1611. */
  1612. private function addFileOrDir($filename)
  1613. {
  1614. if (is_file($filename)) {
  1615. return $this->zip->addFile($filename);
  1616. } elseif (is_dir($filename)) {
  1617. return $this->addDir($filename);
  1618. }
  1619. return false;
  1620. }
  1621.  
  1622. /**
  1623. * Add folder recursively
  1624. * @param string $path
  1625. * @return bool
  1626. */
  1627. private function addDir($path)
  1628. {
  1629. if (!$this->zip->addEmptyDir($path)) {
  1630. return false;
  1631. }
  1632. $objects = scandir($path);
  1633. if (is_array($objects)) {
  1634. foreach ($objects as $file) {
  1635. if ($file != '.' && $file != '..') {
  1636. if (is_dir($path . '/' . $file)) {
  1637. if (!$this->addDir($path . '/' . $file)) {
  1638. return false;
  1639. }
  1640. } elseif (is_file($path . '/' . $file)) {
  1641. if (!$this->zip->addFile($path . '/' . $file)) {
  1642. return false;
  1643. }
  1644. }
  1645. }
  1646. }
  1647. return true;
  1648. }
  1649. return false;
  1650. }
  1651. }
  1652.  
  1653. //--- templates functions
  1654.  
  1655. /**
  1656. * Show nav block
  1657. * @param string $path
  1658. */
  1659. function fm_show_nav_path($path)
  1660. {
  1661. ?>
  1662. <div class="path">
  1663. <div class="float-right">
  1664. <a title="Upload files" href="?p=<?php echo urlencode(FM_PATH) ?>&amp;upload"><i class="icon-upload"></i></a>
  1665. <a title="New folder" href="#" onclick="newfolder('<?php echo fm_enc(FM_PATH) ?>');return false;"><i class="icon-folder_add"></i></a>
  1666. <?php if (FM_USE_AUTH): ?><a title="Logout" href="?logout=1"><i class="icon-logout"></i></a><?php endif; ?>
  1667. </div>
  1668. <?php
  1669. $path = fm_clean_path($path);
  1670. $root_url = "<a href='?p='><i class='icon-home' title='" . FM_ROOT_PATH . "'></i></a>";
  1671. $sep = '<i class="icon-separator"></i>';
  1672. if ($path != '') {
  1673. $exploded = explode('/', $path);
  1674. $count = count($exploded);
  1675. $array = array();
  1676. $parent = '';
  1677. for ($i = 0; $i < $count; $i++) {
  1678. $parent = trim($parent . '/' . $exploded[$i], '/');
  1679. $parent_enc = urlencode($parent);
  1680. $array[] = "<a href='?p={$parent_enc}'>" . fm_enc(fm_convert_win($exploded[$i])) . "</a>";
  1681. }
  1682. $root_url .= $sep . implode($sep, $array);
  1683. }
  1684. echo '<div class="break-word">' . $root_url . '</div>';
  1685. ?>
  1686. </div>
  1687. <?php
  1688. }
  1689.  
  1690. /**
  1691. * Show message from session
  1692. */
  1693. function fm_show_message()
  1694. {
  1695. if (isset($_SESSION['message'])) {
  1696. $class = isset($_SESSION['status']) ? $_SESSION['status'] : 'ok';
  1697. echo '<p class="message ' . $class . '">' . $_SESSION['message'] . '</p>';
  1698. unset($_SESSION['message']);
  1699. unset($_SESSION['status']);
  1700. }
  1701. }
  1702.  
  1703. /**
  1704. * Show page header
  1705. */
  1706. function fm_show_header()
  1707. {
  1708. $sprites_ver = '20160315';
  1709. header("Content-Type: text/html; charset=utf-8");
  1710. header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
  1711. header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
  1712. header("Pragma: no-cache");
  1713. ?>
  1714. <!DOCTYPE html>
  1715. <html>
  1716. <head>
  1717. <meta charset="utf-8">
  1718. <title>Nothing...</title>
  1719. <style>
  1720. html,body,div,span,p,pre,a,code,em,img,small,strong,ol,ul,li,form,label,table,tr,th,td{margin:0;padding:0;vertical-align:baseline;outline:none;font-size:100%;background:transparent;border:none;text-decoration:none}
  1721. html{overflow-y:scroll}body{padding:0;font:13px/16px Tahoma,Arial,sans-serif;color:#222;background:#efefef}
  1722. input,select,textarea,button{font-size:inherit;font-family:inherit}
  1723. a{color:#296ea3;text-decoration:none}a:hover{color:#b00}img{vertical-align:middle;border:none}
  1724. a img{border:none}span.gray{color:#777}small{font-size:11px;color:#999}p{margin-bottom:10px}
  1725. ul{margin-left:2em;margin-bottom:10px}ul{list-style-type:none;margin-left:0}ul li{padding:3px 0}
  1726. table{border-collapse:collapse;border-spacing:0;margin-bottom:10px;width:100%}
  1727. th,td{padding:4px 7px;text-align:left;vertical-align:top;border:1px solid #ddd;background:#fff;white-space:nowrap}
  1728. th,td.gray{background-color:#eee}td.gray span{color:#222}
  1729. tr:hover td{background-color:#f5f5f5}tr:hover td.gray{background-color:#eee}
  1730. code,pre{display:block;margin-bottom:10px;font:13px/16px Consolas,'Courier New',Courier,monospace;border:1px dashed #ccc;padding:5px;overflow:auto}
  1731. pre.with-hljs{padding:0}
  1732. pre.with-hljs code{margin:0;border:0;overflow:visible}
  1733. code.maxheight,pre.maxheight{max-height:512px}input[type="checkbox"]{margin:0;padding:0}
  1734. #wrapper{max-width:1000px;min-width:400px;margin:10px auto}
  1735. .path{padding:4px 7px;border:1px solid #ddd;background-color:#fff;margin-bottom:10px}
  1736. .right{text-align:right}.center{text-align:center}.float-right{float:right}
  1737. .message{padding:4px 7px;border:1px solid #ddd;background-color:#fff}
  1738. .message.ok{border-color:green;color:green}
  1739. .message.error{border-color:red;color:red}
  1740. .message.alert{border-color:orange;color:orange}
  1741. .btn{border:0;background:none;padding:0;margin:0;font-weight:bold;color:#296ea3;cursor:pointer}.btn:hover{color:#b00}
  1742. .preview-img{max-width:100%;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKklEQVR42mL5//8/Azbw+PFjrOJMDCSCUQ3EABZc4S0rKzsaSvTTABBgAMyfCMsY4B9iAAAAAElFTkSuQmCC") repeat 0 0}
  1743. .preview-video{position:relative;max-width:100%;height:0;padding-bottom:62.5%;margin-bottom:10px}.preview-video video{position:absolute;width:100%;height:100%;left:0;top:0;background:#000}
  1744. [class*="icon-"]{display:inline-block;width:16px;height:16px;background:url("<?php echo FM_SELF_URL ?>?img=sprites&amp;t=<?php echo $sprites_ver ?>") no-repeat 0 0;vertical-align:bottom}
  1745. .icon-document{background-position:-16px 0}.icon-folder{background-position:-32px 0}
  1746. .icon-folder_add{background-position:-48px 0}.icon-upload{background-position:-64px 0}
  1747. .icon-arrow_up{background-position:-80px 0}.icon-home{background-position:-96px 0}
  1748. .icon-separator{background-position:-112px 0}.icon-cross{background-position:-128px 0}
  1749. .icon-copy{background-position:-144px 0}.icon-apply{background-position:-160px 0}
  1750. .icon-cancel{background-position:-176px 0}.icon-rename{background-position:-192px 0}
  1751. .icon-checkbox{background-position:-208px 0}.icon-checkbox_invert{background-position:-224px 0}
  1752. .icon-checkbox_uncheck{background-position:-240px 0}.icon-download{background-position:-256px 0}
  1753. .icon-goback{background-position:-272px 0}.icon-folder_open{background-position:-288px 0}
  1754. .icon-file_application{background-position:0 -16px}.icon-file_code{background-position:-16px -16px}
  1755. .icon-file_csv{background-position:-32px -16px}.icon-file_excel{background-position:-48px -16px}
  1756. .icon-file_film{background-position:-64px -16px}.icon-file_flash{background-position:-80px -16px}
  1757. .icon-file_font{background-position:-96px -16px}.icon-file_html{background-position:-112px -16px}
  1758. .icon-file_illustrator{background-position:-128px -16px}.icon-file_image{background-position:-144px -16px}
  1759. .icon-file_music{background-position:-160px -16px}.icon-file_outlook{background-position:-176px -16px}
  1760. .icon-file_pdf{background-position:-192px -16px}.icon-file_photoshop{background-position:-208px -16px}
  1761. .icon-file_php{background-position:-224px -16px}.icon-file_playlist{background-position:-240px -16px}
  1762. .icon-file_powerpoint{background-position:-256px -16px}.icon-file_swf{background-position:-272px -16px}
  1763. .icon-file_terminal{background-position:-288px -16px}.icon-file_text{background-position:-304px -16px}
  1764. .icon-file_word{background-position:-320px -16px}.icon-file_zip{background-position:-336px -16px}
  1765. .icon-logout{background-position:-304px 0}.icon-chain{background-position:-320px 0}
  1766. .icon-link_folder{background-position:-352px -16px}.icon-link_file{background-position:-368px -16px}
  1767. .compact-table{border:0;width:auto}.compact-table td,.compact-table th{width:100px;border:0;text-align:center}.compact-table tr:hover td{background-color:#fff}
  1768. .filename{max-width:420px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  1769. .break-word{word-wrap:break-word}
  1770. </style>
  1771. <link rel="icon" href="<?php echo FM_SELF_URL ?>?img=favicon" type="image/png">
  1772. <link rel="shortcut icon" href="<?php echo FM_SELF_URL ?>?img=favicon" type="image/png">
  1773. <?php if (isset($_GET['view']) && FM_USE_HIGHLIGHTJS): ?>
  1774. <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/styles/<?php echo FM_HIGHLIGHTJS_STYLE ?>.min.css">
  1775. <?php endif; ?>
  1776. </head>
  1777. <body>
  1778. <div id="wrapper">
  1779. <?php
  1780. }
  1781.  
  1782. /**
  1783. * Show page footer
  1784. */
  1785. function fm_show_footer()
  1786. {
  1787. ?>
  1788.  
  1789. </div>
  1790. <script>
  1791. function newfolder(p){var n=prompt('New folder name','folder');if(n!==null&&n!==''){window.location.search='p='+encodeURIComponent(p)+'&new='+encodeURIComponent(n);}}
  1792. function rename(p,f){var n=prompt('New name',f);if(n!==null&&n!==''&&n!=f){window.location.search='p='+encodeURIComponent(p)+'&ren='+encodeURIComponent(f)+'&to='+encodeURIComponent(n);}}
  1793. function change_checkboxes(l,v){for(var i=l.length-1;i>=0;i--){l[i].checked=(typeof v==='boolean')?v:!l[i].checked;}}
  1794. function get_checkboxes(){var i=document.getElementsByName('file[]'),a=[];for(var j=i.length-1;j>=0;j--){if(i[j].type='checkbox'){a.push(i[j]);}}return a;}
  1795. function select_all(){var l=get_checkboxes();change_checkboxes(l,true);}
  1796. function unselect_all(){var l=get_checkboxes();change_checkboxes(l,false);}
  1797. function invert_all(){var l=get_checkboxes();change_checkboxes(l);}
  1798. function checkbox_toggle(){var l=get_checkboxes();l.push(this);change_checkboxes(l);}
  1799. </script>
  1800. <?php if (isset($_GET['view']) && FM_USE_HIGHLIGHTJS): ?>
  1801. <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/highlight.min.js"></script>
  1802. <script>hljs.initHighlightingOnLoad();</script>
  1803. <?php endif; ?>
  1804. </body>
  1805. </html>
  1806. <?php
  1807. }
  1808.  
  1809. /**
  1810. * Show image
  1811. * @param string $img
  1812. */
  1813. function fm_show_image($img)
  1814. {
  1815. $modified_time = gmdate('D, d M Y 00:00:00') . ' GMT';
  1816. $expires_time = gmdate('D, d M Y 00:00:00', strtotime('+1 day')) . ' GMT';
  1817.  
  1818. $img = trim($img);
  1819. $images = fm_get_images();
  1820. $image = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==';
  1821. if (isset($images[$img])) {
  1822. $image = $images[$img];
  1823. }
  1824. $image = base64_decode($image);
  1825. if (function_exists('mb_strlen')) {
  1826. $size = mb_strlen($image, '8bit');
  1827. } else {
  1828. $size = strlen($image);
  1829. }
  1830.  
  1831. if (function_exists('header_remove')) {
  1832. header_remove('Cache-Control');
  1833. header_remove('Pragma');
  1834. } else {
  1835. header('Cache-Control:');
  1836. header('Pragma:');
  1837. }
  1838.  
  1839. header('Last-Modified: ' . $modified_time, true, 200);
  1840. header('Expires: ' . $expires_time);
  1841. header('Content-Length: ' . $size);
  1842. header('Content-Type: image/png');
  1843. echo $image;
  1844.  
  1845. exit;
  1846. }
  1847.  
  1848. /**
  1849. * Get base64-encoded images
  1850. * @return array
  1851. */
  1852. function fm_get_images()
  1853. {
  1854. return array(
  1855. 'favicon' => 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
  1856. bWFnZVJlYWR5ccllPAAAAZVJREFUeNqkk79Lw0AUx1+uidTQim4Waxfpnl1BcHMR6uLkIF0cpYOI
  1857. f4KbOFcRwbGTc0HQSVQQXCqlFIXgFkhIyvWS870LaaPYH9CDy8vdfb+fey930aSUMEvT6VHVzw8x
  1858. rKUX3N3Hj/8M+cZ6GcOtBPl6KY5iAA7KJzfVWrfbhUKhALZtQ6myDf1+X5nsuzjLUmUOnpa+v5r1
  1859. Z4ZDDfsLiwER45xDEATgOI6KntfDd091GidzC8vZ4vH1QQ09+4MSMAMWRREKPMhmsyr6voYmrnb2
  1860. PKEizdEabUaeFCDKCCHAdV0wTVNFznMgpVqGlZ2cipzHGtKSZwCIZJgJwxB38KHT6Sjx21V75Jcn
  1861. LXmGAKTRpGVZUx2dAqQzSEqw9kqwuGqONTufPrw37D8lQFxCvjgPXIixANLEGfwuQacMOC4kZz+q
  1862. GdhJS550BjpRCdCbAJCMJRkMASEIg+4Bxz4JwAwDSEueAYDLIM+QrOk6GHiRxjXSkJY8KUCvdXZ6
  1863. kbuvNx+mOcbN9taGBlpLAWf9nX8EGADoCfqkKWV/cgAAAABJRU5ErkJggg==',
  1864. 'sprites' => 'iVBORw0KGgoAAAANSUhEUgAAAYAAAAAgCAMAAAAscl/XAAAC/VBMVEUAAABUfn4KKipIcXFSeXsx
  1865. VlZSUlNAZ2c4Xl4lSUkRDg7w8O/d3d3LhwAWFhYXODgMLCx8fHw9PT2TtdOOAACMXgE8lt+dmpq+
  1866. fgABS3RUpN+VUycuh9IgeMJUe4C5dUI6meKkAQEKCgoMWp5qtusJmxSUPgKudAAXCghQMieMAgIU
  1867. abNSUlJLe70VAQEsh85oaGjBEhIBOGxfAoyUbUQAkw8gui4LBgbOiFPHx8cZX6PMS1OqFha/MjIK
  1868. VKFGBABSAXovGAkrg86xAgIoS5Y7c6Nf7W1Hz1NmAQB3Hgx8fHyiTAAwp+eTz/JdDAJ0JwAAlxCQ
  1869. UAAvmeRiYp6ysrmIAABJr/ErmiKmcsATpRyfEBAOdQgOXahyAAAecr1JCwHMiABgfK92doQGBgZG
  1870. AGkqKiw0ldYuTHCYsF86gB05UlJmQSlra2tVWED////8/f3t9fX5/Pzi8/Px9vb2+/v0+fnn8vLf
  1871. 7OzZ6enV5+eTpKTo6Oj6/v765Z/U5eX4+Pjx+Pjv0ojWBASxw8O8vL52dnfR19CvAADR3PHr6+vi
  1872. 4uPDx8v/866nZDO7iNT335jtzIL+7aj86aTIztXDw8X13JOlpKJoaHDJAACltratrq3lAgKfAADb
  1873. 4vb76N2au9by2I9gYGVIRkhNTE90wfXq2sh8gL8QMZ3pyn27AADr+uu1traNiIh2olTTshifodQ4
  1874. ZM663PH97+YeRq2GqmRjmkGjnEDnfjLVVg6W4f7s6/p/0fr98+5UVF6wz+SjxNsmVb5RUVWMrc7d
  1875. zrrIpWI8PD3pkwhCltZFYbNZja82wPv05NPRdXzhvna4uFdIiibPegGQXankxyxe0P7PnOhTkDGA
  1876. gBrbhgR9fX9bW1u8nRFamcgvVrACJIvlXV06nvtdgON4mdn3og7AagBTufkucO7snJz4b28XEhIT
  1877. sflynsLEvIk55kr866aewo2YuYDrnFffOTk6Li6hgAn3y8XkusCHZQbt0NP571lqRDZyMw96lZXE
  1878. s6qcrMmJaTmVdRW2AAAAbnRSTlMAZodsJHZocHN7hP77gnaCZWdx/ki+RfqOd/7+zc9N/szMZlf8
  1879. z8yeQybOzlv+tP5q/qKRbk78i/vZmf798s3MojiYjTj+/vqKbFc2/vvMzJiPXPzbs4z9++bj1XbN
  1880. uJxhyMBWwJbp28C9tJ6L1xTnMfMAAA79SURBVGje7Jn5b8thHMcfzLDWULXq2upqHT2kbrVSrJYx
  1881. NzHmviWOrCudqxhbNdZqHauKJTZHm0j0ByYkVBCTiC1+EH6YRBY/EJnjD3D84PMc3++39Z1rjp+8
  1882. Kn189rT5Pt/363k+3YHEDOrCSKP16t48q8U1IysLAUKZk1obLBYDKjAUoB8ziLv4vyQLQD+Lcf4Q
  1883. jvno90kfDaQTRhcioIv7QPk2oJqF0PsIT29RzQdOEhfKG6QW8lcoLIYxjWPQD2GXr/63BhYsWrQA
  1884. fYc0JSaNxa8dH4zUEYag32f009DTkNTnC4WkpcRAl4ryHTt37d5/ugxCIIEfZ0Dg4poFThIXygSp
  1885. hfybmhSWLS0dCpDrdFMRZubUkmJ2+d344qIU8sayN8iFQaBgMDy+FWA/wjelOmbrHUKVtQgxFqFc
  1886. JeE2RpmLEIlfFazzer3hcOAPCQiFasNheAo9HQ1f6FZRTgzs2bOnFwn8+AnG8d6impClTkSjCXWW
  1887. kH80GmUGWP6A4kKkQwG616/tOhin6kii3dzl5YHqT58+bf5KQdq8IjCAg3+tk3NDCoPZC2fQuGcI
  1888. 7+8nKQMk/b41r048UKOk48zln4MgesydOw0NDbeVCA2B+FVaEIDz/0MCSkOlAa+3tDRQSgW4t1MD
  1889. +7d1Q8DA9/sY7weKapZ/Qp+tzwYDtLyRiOrBANQ0/3hTMBIJNsXPb0GM5ANfrLO3telmTrWXGBG7
  1890. fHVHbWjetKKiPCJsAkQv17VNaANv6zJTWAcvmCEtI0hnII4RLsIIBIjmHStXaqKzNCtXOvj+STxl
  1891. OXKwgDuEBuAOEQDxgwDIv85bCwKMw6B5DzOyoVMCHpc+Dnu9gUD4MSeAGWACTnCBnxgorgGHRqPR
  1892. Z8OTg5ZqtRoEwLODy79JdfiwqgkMGBAlJ4caYK3HNGGCHedPBLgqtld30IbmLZk2jTsB9jadboJ9
  1893. Aj4BMqlAXCqV4e3udGH8zn6CgMrtQCUIoPMEbj5Xk3jS3N78UpPL7R81kJOTHdU7QACff/9kAbD/
  1894. IxHvEGTcmi/1+/NlMjJsNXZKAAcIoAkwA0zAvqOMfQNFNcOsf2BGAppotl6D+P0fi6nOnFHFYk1x
  1895. CzOgvqEGA4ICk91uQpQee90V1W58fdYDx0Ls+JnmTwy02e32iRNJB5L5X7y4/Pzq1buXX/lb/X4Z
  1896. SRtTo4C8uf6/Nez11dRI0pkNCswzA+Yn7e3NZi5/aKcYaKPqLBDw5iHPKGUutCAQoKqri0QizsgW
  1897. lJ6/1mqNK4C41bo2P72TnwEMEEASYAa29SCBHz1J2fdo4ExRTbHl5NiSBWQ/yGYCLBnFLbFY8PPn
  1898. YCzWUpxhYS9IJDSIx1iydKJpKTPQ0+lyV9MuCEcQJw+tH57Hjcubhyhy00TAJEdAuocX4Gn1eNJJ
  1899. wHG/xB+PQ8BC/6/0ejw1nAAJAeZ5A83tNH+kuaHHZD8A1MsRUvZ/c0WgPwhQBbGAiAQz2CjzZSJr
  1900. GOxKw1aU6ZOhX2ZK6GYZ42ZoChbgdDED5UzAWcLRR4+cA0U1ZfmiRcuRgJkIYIwBARThuyDzE7hf
  1901. nulLR5qKS5aWMAFOV7WrghjAAvKKpoEByH8J5C8WMELCC5AckkhGYCeS1lZfa6uf2/AuoM51yePB
  1902. DYrM18AD/sE8Z2DSJLaeLHNCr385C9iowbekfHOvQWBN4dzxXhUIuIRPgD+yCskWrs3MOETIyFy7
  1903. sFMC9roYe0EA2YLMwIGeCBh68iDh5P2TFUOhzhs3LammFC5YUIgEVmY/mKVJ4wTUx2JvP358G4vV
  1904. 8wLo/TKKl45cWgwaTNNx1b3M6TwNh5DuANJ7xk37Kv+RBDCAtzMvoPJUZSUVID116pTUw3ecyPZI
  1905. vHIzfEQXMAEeAszzpKUhoR81m4GVNnJHyocN/Xnu2NLmaj/CEVBdqvX5FArvXGTYoAhIaxUb2GDo
  1906. jAD3doabCeAMVFABZ6mAs/fP7sCBLykal1KjYemMYYhh2zgrWUBLi2r8eFVLiyDAlpS/ccXIkSXk
  1907. IJTIiYAy52l8COkOoAZE+ZtMzEA/p8ApJ/lcldX4fc98fn8Nt+Fhd/Lbnc4DdF68fjgNzZMQhQkQ
  1908. UKK52mAQC/D5fHVe6VyEDBlWqzXDwAbUGQEHdjAOgACcAGegojsRcPAY4eD9g7uGonl5S4oWL77G
  1909. 17D+fF/AewmzkDNQaG5v1+SmCtASAWKgAVWtKKD/w0egD/TC005igO2AsctAQB6/RU1VVVUmuZwM
  1910. CM3oJ2CB7+1xwPkeQj4TUOM5x/o/IJoXrR8MJAkY9ab/PZ41uZwAr88nBUDA7wICyncyypkAzoCb
  1911. CbhIgMCbh6K8d5jFfA3346qUePywmtrDfAdcrmmfZeMENNbXq7Taj/X1Hf8qYk7VxOlcMwIRfbt2
  1912. 7bq5jBqAHUANLFlmRBzyFVUr5NyQgoUdqcGZhMFGmrfUA5D+L57vcP25thQBArZCIkCl/eCF/IE5
  1913. 6PdZHzqwjXEgtB6+0KuMM+DuRQQcowKO3T/WjE/A4ndwAmhNBXjq4q1wyluLamWIN2Aebl4uCAhq
  1914. x2u/JUA+Z46Ri4aeBLYHYAEggBooSHmDXBgE1lnggcQU0LgLUMekrl+EclQSSgQCVFrVnFWTKav+
  1915. xAlY35Vn/RTSA4gB517X3j4IGMC1oOsHB8yEetm7xSl15kL4TVIAfjDxKjIRT6Ft0iQb3da3GhuD
  1916. QGPjrWL0E7AlsAX8ZUTr/xFzIP7pRvQ36SsI6Yvr+QN45uN607JlKbUhg8eAOgB2S4bFarVk/PyG
  1917. 6Sss4O/y4/WL7+avxS/+e8D/+ku31tKbRBSFXSg+6iOpMRiiLrQ7JUQ3vhIXKks36h/QhY+FIFJ8
  1918. pEkx7QwdxYUJjRC1mAEF0aK2WEActVVpUbE2mBYp1VofaGyibW19LDSeOxdm7jCDNI0rv0lIvp7v
  1919. nnPnHKaQ+zHV/sxcPlPZT5Hrp69SEVg1vdgP+C/58cOT00+5P2pKreynyPWr1s+Ff4EOOzpctTt2
  1920. rir2A/bdxPhSghfrt9TxcCVlcWU+r5NH+ukk9fu6MYZL1NtwA9De3n6/dD4GA/N1EYwRxXzl+7NL
  1921. i/FJUo9y0Mp+inw/Kgp9BwZz5wxArV5e7AfcNGDcLMGL9XXnEOpcAVlcmXe+QYAJTFLfbcDoLlGv
  1922. /QaeQKiwfusuH8BB5EMnfYcKPGLAiCjmK98frQFDK9kvNZdW9lPk96cySKAq9gOCxmBw7hd4LcGl
  1923. enQDBsOoAW5AFlfkMICnhqdvDJ3pSerDRje8/93GMM9xwwznhHowAINhCA0gz5f5MOxiviYG8K4F
  1924. XoBHjO6RkdNuY4TI9wFuoZBPFfd6vR6EOAIaQHV9vaO+sJ8Ek7gAF5OQ7JeqoJX9FPn9qYwSqIr9
  1925. gGB10BYMfqkOluBIr6Y7AHQz4q4667k6q8sVIOI4n5zjARjfGDtH0j1E/FoepP4dg+Nha/fwk+Fu
  1926. axj0uN650e+vxHqhG6YbptcmbSjPd13H8In5TRaU7+Ix4GgAI5Fx7qkxIuY7N54T86m89mba6WTZ
  1927. Do/H2+HhB3Cstra2sP9EdSIGV3VCcn+Umlb2U+T9UJmsBEyqYj+gzWJrg8vSVoIjPW3vWLjQY6fx
  1928. DXDcKOcKNBBxyFdTQ3KmSqOpauF5upPjuE4u3UPEhQGI66FhR4/iAYQfwGUNgx7Xq3v1anxUqBdq
  1929. j8WG7mlD/jzfcf0jf+0Q8s9saoJnYFBzkWHgrC9qjUS58RFrVMw3ynE5IZ/Km2lsZtmMF9p/544X
  1930. DcAEDwDAXo/iA5bEXd9dn2VAcr/qWlrZT5H7LSqrmYBVxfsBc5trTjbbeD+g7crNNuj4lTZYocSR
  1931. nqa99+97aBrxgKvV5WoNNDTgeMFfSCYJzmi2ATQtiKfTrZ2t6daeHiLeD81PpVLXiPVmaBgfD1eE
  1932. hy8Nwyvocb1X7tx4a7JQz98eg/8/sYQ/z3cXngDJfizm94feHzqMBsBFotFohIsK+Vw5t0vcv8pD
  1933. 0SzVjPvPdixH648eO1YLmIviUMp33Xc9FpLkp2i1sp8i91sqzRUEzJUgMNbQdrPZTtceBEHvlc+f
  1934. P/f2XumFFUoc6Z2Nnvu/4o1OxBsC7kAgl2s4T8RN1RPJ5ITIP22rulXVsi2LeE/aja6et4T+Zxja
  1935. /yOVEtfzDePjfRW2cF/YVtGH9LhebuPqBqGeP9QUCjVd97/M82U7fAg77EL+WU0Igy2DDDMLDeBS
  1936. JBq5xEWFfDl3MiDmq/R0wNvfy7efdd5BAzDWow8Bh6OerxdLDDgGHDE/eb9oAsp+itxvqaw4QaCi
  1937. Eh1HXz2DFGfOHp+FGo7RCyuUONI7nZ7MWNzpRLwhj/NE3GRKfp9Iilyv0XVpuqr0iPfk8ZbQj/2E
  1938. /v/4kQIu+BODhwYhjgaAN9oHeqV6L/0YLwv5tu7dAXCYJfthtg22tPA8yrUicFHlfDCATKYD+o/a
  1939. 74QBoPVHjuJnAOIwAAy/JD9Fk37K/auif0L6LRc38IfjNQRO8AOoYRthhuxJCyTY/wwjaKZpCS/4
  1940. BaBnG+NDQ/FGFvEt5zGSRNz4fSPgu8D1XTqdblCnR3zxW4yHhP7j2M/fT09dTgnr8w1DfFEfRhj0
  1941. SvXWvMTwYa7gb8yA97/unQ59F5oBJnsUI6KcDz0B0H/+7S8MwG6DR8Bhd6D4Jj9GQlqPogk/JZs9
  1942. K/gn5H40e7aL7oToUYAfYMvUnMw40Gkw4Q80O6XcLMRZFgYwxrKl4saJjabqjRMCf6QDdOkeldJ/
  1943. BfSnrvWLcWgYxGX6KfPswEKLZVL6yrgXvv6g9uMBoDic3B/9e36KLvDNS7TZ7K3sGdE/wfoqDQD9
  1944. NGG+9AmYL/MDRM5iLo9nqDEYAJWRx5U5o+3SaHRaplS8H+Faf78Yh4bJ8k2Vz24qgJldXj8/DkCf
  1945. wDy8fH/sdpujTD2KxhxM/ueA249E/wTru/Dfl05bPkeC5TI/QOAvbJjL47TnI8BDy+KlOJPV6bJM
  1946. yfg3wNf+r99KxafOibNu5IQvKKsv2x9lTtEFvmGlXq9/rFeL/gnWD2kB6KcwcpB+wP/IyeP2svqp
  1947. 9oeiCT9Fr1cL/gmp125aUc4P+B85iX+qJ/la0k/Ze0D0T0j93jXTpv0BYUGhQhdSooYAAAAASUVO
  1948. RK5CYII=',
  1949. );
  1950. }
Add Comment
Please, Sign In to add comment