Browse Source

Updating elfinder 2.1 see #6833

Julio Montoya 11 years ago
parent
commit
b375b93a5c
50 changed files with 20978 additions and 587 deletions
  1. 0 12
      main/inc/lib/elfinder/.gitignore
  2. 4 6
      main/inc/lib/elfinder/README.md
  3. 1622 0
      main/inc/lib/elfinder/css/elfinder.full.css
  4. 2 2
      main/inc/lib/elfinder/css/elfinder.min.css
  5. 1 0
      main/inc/lib/elfinder/css/theme.css
  6. 15 13
      main/inc/lib/elfinder/elfinder.html
  7. BIN
      main/inc/lib/elfinder/img/dialogs.png
  8. 11519 0
      main/inc/lib/elfinder/js/elfinder.full.js
  9. 2 2
      main/inc/lib/elfinder/js/elfinder.min.js
  10. 15 8
      main/inc/lib/elfinder/js/i18n/elfinder.LANG.js
  11. 1 1
      main/inc/lib/elfinder/js/i18n/elfinder.ar.js
  12. 1 1
      main/inc/lib/elfinder/js/i18n/elfinder.bg.js
  13. 1 1
      main/inc/lib/elfinder/js/i18n/elfinder.ca.js
  14. 77 22
      main/inc/lib/elfinder/js/i18n/elfinder.cs.js
  15. 85 30
      main/inc/lib/elfinder/js/i18n/elfinder.de.js
  16. 355 0
      main/inc/lib/elfinder/js/i18n/elfinder.el.js
  17. 33 17
      main/inc/lib/elfinder/js/i18n/elfinder.es.js
  18. 339 0
      main/inc/lib/elfinder/js/i18n/elfinder.fa.js
  19. 70 30
      main/inc/lib/elfinder/js/i18n/elfinder.fr.js
  20. 1 1
      main/inc/lib/elfinder/js/i18n/elfinder.hu.js
  21. 340 0
      main/inc/lib/elfinder/js/i18n/elfinder.it.js
  22. 58 32
      main/inc/lib/elfinder/js/i18n/elfinder.jp.js
  23. 340 0
      main/inc/lib/elfinder/js/i18n/elfinder.ko.js
  24. 33 14
      main/inc/lib/elfinder/js/i18n/elfinder.nl.js
  25. 1 1
      main/inc/lib/elfinder/js/i18n/elfinder.no.js
  26. 37 3
      main/inc/lib/elfinder/js/i18n/elfinder.pl.js
  27. 58 7
      main/inc/lib/elfinder/js/i18n/elfinder.pt_BR.js
  28. 30 12
      main/inc/lib/elfinder/js/i18n/elfinder.ru.js
  29. 348 0
      main/inc/lib/elfinder/js/i18n/elfinder.sk.js
  30. 340 0
      main/inc/lib/elfinder/js/i18n/elfinder.sl.js
  31. 353 0
      main/inc/lib/elfinder/js/i18n/elfinder.sv.js
  32. 340 0
      main/inc/lib/elfinder/js/i18n/elfinder.tr.js
  33. 340 0
      main/inc/lib/elfinder/js/i18n/elfinder.vi.js
  34. 86 12
      main/inc/lib/elfinder/js/i18n/elfinder.zh_CN.js
  35. 353 0
      main/inc/lib/elfinder/js/i18n/elfinder.zh_TW.js
  36. 1 1
      main/inc/lib/elfinder/js/proxy/elFinderSupportVer1.js
  37. 47 0
      main/inc/lib/elfinder/php/connector.minimal.php
  38. 47 0
      main/inc/lib/elfinder/php/connector.php
  39. 504 39
      main/inc/lib/elfinder/php/elFinder.class.php
  40. 201 139
      main/inc/lib/elfinder/php/elFinderVolumeDriver.class.php
  41. 1418 0
      main/inc/lib/elfinder/php/elFinderVolumeFTP.class.php
  42. 134 0
      main/inc/lib/elfinder/php/elFinderVolumeFTPIIS.class.php
  43. 106 176
      main/inc/lib/elfinder/php/elFinderVolumeLocalFileSystem.class.php
  44. 69 5
      main/inc/lib/elfinder/php/elFinderVolumeMySQL.class.php
  45. 732 0
      main/inc/lib/elfinder/php/elFinderVolumeS3.class.php
  46. 157 0
      main/inc/lib/elfinder/php/plugins/AutoResize/plugin.php
  47. 119 0
      main/inc/lib/elfinder/php/plugins/Normalizer/plugin.php
  48. BIN
      main/inc/lib/elfinder/php/plugins/Watermark/logo.png
  49. 243 0
      main/inc/lib/elfinder/php/plugins/Watermark/plugin.php
  50. BIN
      main/inc/lib/elfinder/rm.wav

+ 0 - 12
main/inc/lib/elfinder/.gitignore

@@ -1,12 +0,0 @@
-*~
-._*
-_*
-.DS_Store
-php-old
-extensions
-build
-files2
-elFinderVolumeSVN.class.php
-connector-svn.php
-node_modules
-connector.php

+ 4 - 6
main/inc/lib/elfinder/README.md

@@ -25,8 +25,8 @@ Features
  * Local file system, MySQL, FTP volume storage drivers
  * Background file upload with Drag & Drop HTML5 support
  * List and Icons view
- * Kayboard shortcuts
- * Standart methods of file/group selection using mouse or keyboard
+ * Keyboard shortcuts
+ * Standard methods of file/group selection using mouse or keyboard
  * Move/Copy files with Drag & Drop
  * Archives create/extract (zip, rar, 7z, tar, gzip, bzip2)
  * Rich context menu and toolbar
@@ -46,8 +46,8 @@ Requirements
 ------------
 
 ### Client
- * Modern browser. elFinder was tested in Firefox 10, Internet Explorer 8+,
-   Safari 5, Opera 11 and Chrome 15+
+ * Modern browser. elFinder was tested in Firefox 12, Internet Explorer 8+,
+   Safari 6, Opera 12 and Chrome 19
 
 ### Server
  * Any web server
@@ -60,8 +60,6 @@ Requirements
  * [Django](https://github.com/mikery/django-elfinder)
  * [Ruby/Rails](https://github.com/phallstrom/el_finder)
  * [Java Servlet](https://github.com/Studio-42/elfinder-servlet)
- * [ASP.NET Integration](http://code.google.com/p/elfinderintegration/)
- * [elFinder .Net connector](http://elfinderconnectornet.codeplex.com/)
 
 
 Support

+ 1622 - 0
main/inc/lib/elfinder/css/elfinder.full.css

@@ -0,0 +1,1622 @@
+/*!
+ * elFinder - file manager for web
+ * Version 2.1 (Nightly: 093d077) (2013-12-05)
+ * http://elfinder.org
+ * 
+ * Copyright 2009-2013, Studio 42
+ * Licensed under a 3 clauses BSD license
+ */
+
+/* File: /home/osc/elFinder-build/elFinder/css/commands.css */
+/******************************************************************/
+/*                          COMMANDS STYLES                       */
+/******************************************************************/
+
+/********************** COMMAND "RESIZE" ****************************/
+.elfinder-dialog-resize  { margin-top:.3em; }
+.elfinder-resize-type    { float:left; margin-bottom: .4em; }
+.elfinder-resize-control { padding-top:3em; }
+.elfinder-resize-control input[type=text] { border:1px solid #aaa; text-align: right; }
+.elfinder-resize-preview {
+	width:400px;
+	height:400px;
+	padding:10px;
+	background:#fff;
+	border:1px solid #aaa;
+	float:right;
+	position:relative;
+	overflow:auto;
+/*	z-index:100;*/
+}
+
+.elfinder-resize-handle { position:relative;}
+
+.elfinder-resize-handle-hline,
+.elfinder-resize-handle-vline {
+	position:absolute;
+	background-image:url("../img/crop.gif");
+}
+
+.elfinder-resize-handle-hline {
+	width:100%;
+	height:1px !important;
+	background-repeat:repeat-x;
+}
+.elfinder-resize-handle-vline {
+	width:1px !important;
+	height:100%;
+	background-repeat:repeat-y;
+}
+
+.elfinder-resize-handle-hline-top    { top:0; left:0; }
+.elfinder-resize-handle-hline-bottom { bottom:0; left:0; }
+.elfinder-resize-handle-vline-left   { top:0; left:0; }
+.elfinder-resize-handle-vline-right  { top:0; right:0; }
+
+.elfinder-resize-handle-point {
+	position:absolute;
+	width:8px;
+	height:8px;
+	border:1px solid #777;
+	background:transparent;
+}
+
+.elfinder-resize-handle-point-n  {
+	top:0;
+	left:50%;
+	margin-top:-5px;
+	margin-left:-5px;
+}
+.elfinder-resize-handle-point-ne {
+	top:0;
+	right:0;
+	margin-top:-5px;
+	margin-right:-5px;
+}
+.elfinder-resize-handle-point-e  {
+	top:50%;
+	right:0;
+	margin-top:-5px;
+	margin-right:-5px;
+}
+.elfinder-resize-handle-point-se  {
+	bottom:0;
+	right:0;
+	margin-bottom:-5px;
+	margin-right:-5px;
+}
+.elfinder-resize-handle-point-s  {
+	bottom:0;
+	left:50%;
+	margin-bottom:-5px;
+	margin-left:-5px;
+}
+.elfinder-resize-handle-point-sw {
+	bottom:0;
+	left:0;
+	margin-bottom:-5px;
+	margin-left:-5px;
+}
+.elfinder-resize-handle-point-w  {
+	top:50%;
+	left:0;
+	margin-top:-5px;
+	margin-left:-5px;
+}
+.elfinder-resize-handle-point-nw {
+	top:0;
+	left:0;
+	margin-top:-5px;
+	margin-left:-5px;
+}
+
+.elfinder-resize-spinner {
+	position:absolute;
+	width:200px;
+	height:30px;
+	top:50%;
+	margin-top:-25px;
+	left:50%;
+	margin-left:-100px;
+	text-align:center;
+	background:url(../img/progress.gif) center bottom repeat-x;
+}
+
+.elfinder-resize-row { margin-bottom:7px; position:relative;}
+
+.elfinder-resize-label { float:left; width:80px; padding-top: 3px; }
+
+.elfinder-resize-reset {
+	width:16px;
+	height:16px;
+/*	border:1px solid #111;*/
+	position:absolute;
+	margin-top:-8px;
+}
+
+.elfinder-dialog .elfinder-dialog-resize .ui-resizable-e { height:100%; width:10px; }
+.elfinder-dialog .elfinder-dialog-resize .ui-resizable-s { width:100%; height:10px; }
+.elfinder-dialog .elfinder-dialog-resize .ui-resizable-se { 
+	background:transparent; 
+	bottom:0; 
+	right:0; 
+	margin-right:-7px;
+	margin-bottom:-7px;
+}
+
+.elfinder-dialog-resize  .ui-icon-grip-solid-vertical {
+	position:absolute;
+	top:50%;
+	right:0;
+	margin-top:-8px;
+	margin-right:-11px;
+}
+.elfinder-dialog-resize .ui-icon-grip-solid-horizontal {
+	position:absolute;
+	left:50%;
+	bottom:0;
+	margin-left:-8px;
+	margin-bottom:-11px;;
+}
+
+.elfinder-resize-row .elfinder-buttonset { float:right; }
+
+.elfinder-resize-rotate-slider {
+	float: left;
+	width: 195px;
+	margin: 7px 7px 0;
+}
+
+/********************** COMMAND "EDIT" ****************************/
+/* edit text file textarea */
+.elfinder-file-edit {
+	width:99%;
+	height:99%;
+	margin:0;
+	padding:2px;
+	border:1px solid #ccc;
+}
+
+
+/********************** COMMAND "HELP" ****************************/
+/* help dialog */
+.elfinder-help { margin-bottom:.5em; }
+
+/* fix tabs */
+.elfinder-help .ui-tabs-panel { padding:.5em; }
+.elfinder-dialog .ui-tabs .ui-tabs-nav li a { padding:.2em 1em;}
+
+.elfinder-help-shortcuts {
+	height:300px;
+	padding:1em;
+	margin:.5em 0;
+	overflow:auto;
+}
+.elfinder-help-shortcut { white-space:nowrap; clear:both;}
+
+.elfinder-help-shortcut-pattern { float:left; width:160px;}
+
+.elfinder-help-logo {
+	width:100px;
+	height:96px;
+	float:left;
+	margin-right:1em;
+	background:url('../img/logo.png') center center no-repeat;
+}
+
+.elfinder-help h3 { font-size:1.5em; margin:.2em 0 .3em 0; }
+
+.elfinder-help-separator { clear:both; padding:.5em;  }
+
+.elfinder-help-link { padding:2px; }
+
+.elfinder-help .ui-priority-secondary { font-size:.9em;}
+
+.elfinder-help .ui-priority-primary { margin-bottom:7px;}
+
+.elfinder-help-team { 
+	clear: both; 
+	text-align:right; 
+	border-bottom:1px solid #ccc;
+	margin:.5em 0;
+	font-size:.9em;
+}
+
+.elfinder-help-team div { float:left; }
+.elfinder-help-license { font-size:.9em;}
+
+.elfinder-help-disabled {
+	font-weight:bold;
+	text-align:center;
+	margin:90px 0;
+}
+
+.elfinder-help .elfinder-dont-panic {
+	display:block;
+	border:1px solid transparent;
+	width:200px;
+	height:200px;
+	margin:30px auto;
+	text-decoration:none;
+	text-align:center;
+	position:relative;
+	background:#d90004;
+	-moz-box-shadow: 5px 5px 9px #111;
+	-webkit-box-shadow:  5px 5px 9px #111;
+	box-shadow:  5px 5px 9px #111;
+	background: -moz-radial-gradient(80px 80px, circle farthest-corner,  #d90004 35%, #960004 100%);
+	background: -webkit-gradient(radial, 80 80, 60, 80 80, 120, from(#d90004), to(#960004));
+	-moz-border-radius: 100px;
+	-webkit-border-radius: 100px;
+	border-radius: 100px;
+	outline:none;
+}
+
+.elfinder-help .elfinder-dont-panic span {
+	font-size:3em;
+	font-weight:bold;
+	text-align:center;
+	color:#fff;
+	position:absolute;
+	left:0;
+	top:45px;
+}
+
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/common.css */
+/*********************************************/
+/*            COMMON ELFINDER STUFFS         */
+/*********************************************/
+
+/* common container */
+.elfinder { padding:0; position:relative; display:block; }
+
+/* right to left enviroment */
+.elfinder-rtl { text-align:right; direction:rtl; }
+
+/* nav and cwd container */
+.elfinder-workzone {
+	padding: 0;
+	position:relative;
+	overflow:hidden;
+}
+
+/* dir/file permissions and symlink markers */
+.elfinder-perms,
+.elfinder-symlink {
+	position:absolute;
+	width:16px;
+	height:16px;
+	background-image:url(../img/toolbar.png);
+	background-repeat:no-repeat;
+	background-position:0 -528px;
+}
+
+.elfinder-symlink { }
+
+/* noaccess */
+.elfinder-na .elfinder-perms { background-position:0 -96px; }
+
+/* read only */
+.elfinder-ro .elfinder-perms { background-position:0 -64px;}
+
+/* write only */
+.elfinder-wo .elfinder-perms { background-position:0 -80px;}
+
+/* drag helper */
+.elfinder-drag-helper {
+	width:60px;
+	height:50px;
+	padding:0 0 0 25px;
+	z-index:100000;
+}
+
+/* drag helper "plus" icon */
+.elfinder-drag-helper-icon-plus {
+	position:absolute;
+	width:16px;
+	height:16px;
+	left:43px;
+	top:55px;
+	background:url('../img/toolbar.png') 0 -544px no-repeat;
+	display:none;
+}
+
+/* show "plus" icon when ctrl/shift pressed */
+.elfinder-drag-helper-plus .elfinder-drag-helper-icon-plus { display:block; }
+
+/* files num in drag helper */
+.elfinder-drag-num {
+	position:absolute;
+	top:0;
+	left:0;
+	width:16px;
+	height:14px;
+	text-align:center;
+	padding-top:2px;
+	
+	font-weight:bold;
+	color:#fff;
+	background-color:red;
+	-moz-border-radius: 8px; 
+	-webkit-border-radius: 8px; 
+	border-radius: 8px;
+}
+
+/* icon in drag helper */
+.elfinder-drag-helper .elfinder-cwd-icon { margin:0 0 0 -24px; float:left; }
+
+/* transparent overlay >_< */
+.elfinder-overlay { opacity: 0; filter:Alpha(Opacity=0); }
+
+/* panels under/below cwd (for search field etc) */
+.elfinder .elfinder-panel {
+	position:relative;
+	background-image:none;
+	padding:7px 12px;
+}
+
+
+
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/contextmenu.css */
+/* menu and submenu */
+.elfinder-contextmenu,
+.elfinder-contextmenu-sub {
+	display:none;
+	position:absolute;
+	border:1px solid #aaa;
+	background:#fff;
+	color:#555;
+	padding:4px 0;
+}
+
+/* submenu */
+.elfinder-contextmenu-sub { top:5px; }
+/* submenu in rtl/ltr enviroment */
+.elfinder-contextmenu-ltr .elfinder-contextmenu-sub { margin-left:-5px; }
+.elfinder-contextmenu-rtl .elfinder-contextmenu-sub { margin-right:-5px; }
+
+/* menu item */
+.elfinder-contextmenu-item {
+	position:relative;
+	display:block;
+	padding:4px 30px;
+	text-decoration:none;
+	white-space:nowrap;
+	cursor:default;
+}
+/* text in item */
+.elfinder-contextmenu .elfinder-contextmenu-item span { display:block; }
+
+
+
+/* submenu item in rtl/ltr enviroment */
+.elfinder-contextmenu-ltr .elfinder-contextmenu-item { text-align:left; }
+.elfinder-contextmenu-rtl .elfinder-contextmenu-item { text-align:right; }
+.elfinder-contextmenu-ltr .elfinder-contextmenu-sub .elfinder-contextmenu-item { padding-left:12px;  }
+.elfinder-contextmenu-rtl .elfinder-contextmenu-sub .elfinder-contextmenu-item { padding-right:12px; }
+
+/* command/submenu icon */
+.elfinder-contextmenu-arrow,
+.elfinder-contextmenu-icon {
+	position:absolute;
+	top:50%;
+	margin-top:-8px;
+}
+
+/* command icon in rtl/ltr enviroment */
+.elfinder-contextmenu-ltr .elfinder-contextmenu-icon { left:8px; }
+.elfinder-contextmenu-rtl .elfinder-contextmenu-icon { right:8px; }
+
+/* arrow icon */
+.elfinder-contextmenu-arrow {
+	width:16px;
+	height:16px;
+	background:url('../img/arrows-normal.png') 5px 4px no-repeat;
+}
+
+/* arrow icon in rtl/ltr enviroment */
+.elfinder-contextmenu-ltr .elfinder-contextmenu-arrow { right:5px; }
+.elfinder-contextmenu-rtl .elfinder-contextmenu-arrow { left:5px; background-position: 0 -10px; }
+
+/* disable ui border/bg image on hover */
+.elfinder-contextmenu .ui-state-hover { border:0 solid; background-image:none;}
+
+/* separator */
+.elfinder-contextmenu-separator {
+	height:0px;
+	border-top:1px solid #ccc;
+	margin:0 1px;
+}
+
+/* File: /home/osc/elFinder-build/elFinder/css/cwd.css */
+/******************************************************************/
+/*                     CURRENT DIRECTORY STYLES                   */
+/******************************************************************/
+/* cwd container to avoid selectable on scrollbar */
+.elfinder-cwd-wrapper {
+	overflow: auto;
+	position:relative;
+	padding:2px;
+	margin:0;
+}
+
+.elfinder-cwd-wrapper-list { padding:0; }
+
+/* container */
+.elfinder-cwd { 
+	position:relative;
+	cursor:default;
+	padding:0;
+	margin:0;
+	-moz-user-select: -moz-none;
+	-khtml-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+/* container active on dropenter */
+.elfinder .elfinder-cwd-wrapper.elfinder-droppable-active {
+	padding:0;
+	border:2px solid #8cafed;
+}
+
+
+/************************** ICONS VIEW ********************************/
+
+/* file container */
+.elfinder-cwd-view-icons .elfinder-cwd-file {
+	width:120px;
+	height:80px;
+	padding-bottom:2px;
+	cursor:default;
+/*	overflow:hidden;*/
+/*	position:relative;*/
+}
+
+/* ltr/rtl enviroment */
+.elfinder-ltr .elfinder-cwd-view-icons .elfinder-cwd-file { float:left;  margin:0 3px 12px 0; }
+.elfinder-rtl .elfinder-cwd-view-icons .elfinder-cwd-file { float:right; margin:0 0 5px 3px; }
+
+/* remove ui hover class border */
+.elfinder-cwd-view-icons .elfinder-cwd-file .ui-state-hover { border:0 solid; }
+
+/* icon wrapper to create selected highlight around icon */
+.elfinder-cwd-view-icons .elfinder-cwd-file-wrapper {
+	width:52px;
+	height:52px;
+	margin:1px auto 1px auto;
+	padding:2px;
+	position:relative;
+}
+
+/* file name place */
+.elfinder-cwd-view-icons .elfinder-cwd-filename {
+	text-align:center;
+	white-space:pre;
+	overflow:hidden;
+	text-overflow:ellipsis;
+    -o-text-overflow:ellipsis;
+	margin:3px 1px 0 1px;
+	padding:1px;
+	-moz-border-radius: 8px; 
+	-webkit-border-radius: 8px; 
+	border-radius: 8px;
+}
+
+/* permissions/symlink markers */
+.elfinder-cwd-view-icons .elfinder-perms { bottom:4px; right:2px; }
+.elfinder-cwd-view-icons .elfinder-symlink { bottom:6px; left:0px; }
+
+/* icon/thumbnail */
+.elfinder-cwd-icon {
+	display:block;
+	width:48px;
+	height:48px;
+	margin:0 auto;
+	background: url('../img/icons-big.png') 0 0 no-repeat;
+	-moz-background-clip: padding; 
+	-webkit-background-clip: padding-box; 
+	background-clip: padding-box;
+}
+
+/* "opened folder" icon on dragover */
+.elfinder-cwd .elfinder-droppable-active .elfinder-cwd-icon { background-position: 0 -100px; }
+
+/* mimetypes icons */
+.elfinder-cwd-icon-directory         { background-position:0 -50px; }
+.elfinder-cwd-icon-application       { background-position:0 -150px; }
+.elfinder-cwd-icon-x-empty, 
+.elfinder-cwd-icon-text              { background-position:0  -200px; }
+.elfinder-cwd-icon-image, 
+.elfinder-cwd-icon-vnd-adobe-photoshop, 
+.elfinder-cwd-icon-postscript        { background-position:0 -250px;  }
+.elfinder-cwd-icon-audio             { background-position:0 -300px; }
+.elfinder-cwd-icon-video,
+.elfinder-cwd-icon-flash-video       { background-position:0 -350px; }
+.elfinder-cwd-icon-rtf, 
+.elfinder-cwd-icon-rtfd              { background-position: 0 -401px; }
+.elfinder-cwd-icon-pdf               { background-position: 0 -450px; }
+.elfinder-cwd-icon-ms-excel,
+.elfinder-cwd-icon-msword,
+.elfinder-cwd-icon-vnd-ms-excel,
+.elfinder-cwd-icon-vnd-ms-excel-addin-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-excel-sheet-binary-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-excel-sheet-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-excel-template-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-office,
+.elfinder-cwd-icon-vnd-ms-powerpoint,
+.elfinder-cwd-icon-vnd-ms-powerpoint-addin-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-powerpoint-presentation-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-powerpoint-slide-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-powerpoint-slideshow-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-powerpoint-template-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-word,
+.elfinder-cwd-icon-vnd-ms-word-document-macroEnabled-12,
+.elfinder-cwd-icon-vnd-ms-word-template-macroEnabled-12,
+.elfinder-cwd-icon-vnd-oasis-opendocument-chart,
+.elfinder-cwd-icon-vnd-oasis-opendocument-database,
+.elfinder-cwd-icon-vnd-oasis-opendocument-formula,
+.elfinder-cwd-icon-vnd-oasis-opendocument-graphics,
+.elfinder-cwd-icon-vnd-oasis-opendocument-graphics-template,
+.elfinder-cwd-icon-vnd-oasis-opendocument-image,
+.elfinder-cwd-icon-vnd-oasis-opendocument-presentation,
+.elfinder-cwd-icon-vnd-oasis-opendocument-presentation-template,
+.elfinder-cwd-icon-vnd-oasis-opendocument-spreadsheet,
+.elfinder-cwd-icon-vnd-oasis-opendocument-spreadsheet-template,
+.elfinder-cwd-icon-vnd-oasis-opendocument-text,
+.elfinder-cwd-icon-vnd-oasis-opendocument-text-master,
+.elfinder-cwd-icon-vnd-oasis-opendocument-text-template,
+.elfinder-cwd-icon-vnd-oasis-opendocument-text-web,
+.elfinder-cwd-icon-vnd-openofficeorg-extension,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-presentationml-presentation,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-presentationml-slide,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-presentationml-slideshow,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-presentationml-template,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-spreadsheetml-sheet,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-spreadsheetml-template,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-wordprocessingml-document,
+.elfinder-cwd-icon-vnd-openxmlformats-officedocument-wordprocessingml-template { background-position: 0 -500px; }
+.elfinder-cwd-icon-html              { background-position: 0 -550px; }
+.elfinder-cwd-icon-css               { background-position: 0 -600px; }
+.elfinder-cwd-icon-javascript, 
+.elfinder-cwd-icon-x-javascript      { background-position: 0 -650px; }
+.elfinder-cwd-icon-x-perl            { background-position: 0 -700px; }
+.elfinder-cwd-icon-x-python          { background-position: 0 -750px; }
+.elfinder-cwd-icon-x-ruby            { background-position: 0 -800px; }
+.elfinder-cwd-icon-x-sh, 
+.elfinder-cwd-icon-x-shellscript     { background-position: 0 -850px; }
+.elfinder-cwd-icon-x-c,
+.elfinder-cwd-icon-x-csrc,
+.elfinder-cwd-icon-x-chdr,
+.elfinder-cwd-icon-x-c--, 
+.elfinder-cwd-icon-x-c--src,
+.elfinder-cwd-icon-x-c--hdr, 
+.elfinder-cwd-icon-x-java, 
+.elfinder-cwd-icon-x-java-source     { background-position: 0 -900px; }
+.elfinder-cwd-icon-x-php             { background-position: 0 -950px; }
+.elfinder-cwd-icon-xml               { background-position: 0 -1000px; }
+.elfinder-cwd-icon-zip, 
+.elfinder-cwd-icon-x-zip, 
+.elfinder-cwd-icon-x-7z-compressed   { background-position: 0 -1050px; }
+.elfinder-cwd-icon-x-gzip,  
+.elfinder-cwd-icon-x-tar             { background-position: 0 -1100px; }
+.elfinder-cwd-icon-x-bzip, 
+.elfinder-cwd-icon-x-bzip2           { background-position: 0 -1150px; }
+.elfinder-cwd-icon-x-rar, 
+.elfinder-cwd-icon-x-rar-compressed  { background-position: 0 -1200px; }
+.elfinder-cwd-icon-x-shockwave-flash { background-position: 0 -1250px; }
+.elfinder-cwd-icon-group             { background-position:0 -1300px;}
+
+/* textfield inside icon */
+.elfinder-cwd input { width:100%; border:0px solid; margin:0; padding:0; }
+.elfinder-cwd-view-icons input {text-align:center; }
+
+.elfinder-cwd-view-icons { text-align:center; }
+
+
+/************************************  LIST VIEW ************************************/
+
+/*.elfinder-cwd-view-list { padding:0 0 4px 0; }*/
+
+.elfinder-cwd table { width:100%; border-collapse:collapse; border:0 solid; margin:0 0 10px 0; }
+.elfinder .elfinder-cwd table thead tr { border-left:0 solid; border-top:0 solid; border-right:0 solid; }
+
+.elfinder .elfinder-cwd table td { 
+	padding:3px 12px;
+	white-space:pre;
+	overflow:hidden;
+	text-align:right;
+	cursor:default;
+	border:0 solid;
+	
+}
+
+.elfinder-ltr .elfinder-cwd table td { text-align:right; }
+.elfinder-ltr .elfinder-cwd table td:first-child { text-align:left; }
+.elfinder-rtl .elfinder-cwd table td { text-align:left; }
+.elfinder-rtl .elfinder-cwd table td:first-child { text-align:right; }
+
+.elfinder-odd-row { background:#eee; }
+
+/* filename container */
+.elfinder-cwd-view-list .elfinder-cwd-file-wrapper { width:97%; position:relative; }
+/* filename container in ltr/rtl enviroment */
+.elfinder-ltr .elfinder-cwd-view-list .elfinder-cwd-file-wrapper { padding-left:23px;  }
+.elfinder-rtl .elfinder-cwd-view-list .elfinder-cwd-file-wrapper { padding-right:23px; }
+
+/* premissions/symlink marker */
+.elfinder-cwd-view-list .elfinder-perms, 
+.elfinder-cwd-view-list .elfinder-symlink { top:50%; margin-top:-6px; }
+/* markers in ltr/rtl enviroment */
+.elfinder-ltr .elfinder-cwd-view-list .elfinder-perms   { left:7px;  }
+.elfinder-ltr .elfinder-cwd-view-list .elfinder-symlink { left:-7px; }
+
+/* file icon */
+.elfinder-cwd-view-list td .elfinder-cwd-icon {
+	width:16px;
+	height:16px;
+	position:absolute;
+	top:50%;
+	margin-top:-8px;
+	background-image:url(../img/icons-small.png);
+}
+/* icon in ltr/rtl enviroment */
+.elfinder-ltr .elfinder-cwd-view-list .elfinder-cwd-icon { left:0;  }
+.elfinder-rtl .elfinder-cwd-view-list .elfinder-cwd-icon { right:0; }
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/dialog.css */
+/*********************************************/
+/*                DIALOGS STYLES             */
+/*********************************************/
+
+/* common dialogs class */
+.std42-dialog {
+	padding:0;
+	position:absolute;
+	left:auto;
+	right:auto;
+}
+
+/* titlebar */
+.std42-dialog .ui-dialog-titlebar {
+	border-left:0 solid transparent;
+	border-top:0 solid transparent;
+	border-right:0 solid transparent;
+	-moz-border-radius-bottomleft: 0; 
+	-webkit-border-bottom-left-radius: 0; 
+	border-bottom-left-radius: 0; 
+	-moz-border-radius-bottomright: 0; 
+	-webkit-border-bottom-right-radius: 0; 
+	border-bottom-right-radius: 0;
+	font-weight:normal;
+	padding:.2em 1em;
+}
+
+.std42-dialog .ui-dialog-titlebar-close,
+.std42-dialog .ui-dialog-titlebar-close:hover { padding:1px; }
+
+.elfinder-rtl .elfinder-dialog .ui-dialog-titlebar { text-align:right; }
+.elfinder-rtl .elfinder-dialog .ui-dialog-titlebar .ui-dialog-titlebar-close { right:auto; left:.3em; }
+
+/* content */
+.std42-dialog .ui-dialog-content {
+	padding:.3em .5em;
+}
+
+/* buttons */
+.std42-dialog .ui-dialog-buttonpane {
+	border:0 solid;
+	margin:0;
+	padding:.5em .7em;
+}
+
+.std42-dialog .ui-dialog-buttonpane button { margin:0 0 0 .4em;	padding:0; outline:0px solid; }
+.std42-dialog .ui-dialog-buttonpane button span { padding:2px 9px; }
+
+.elfinder-dialog .ui-resizable-e, 
+.elfinder-dialog .ui-resizable-s { width:0; height:0;}
+
+.std42-dialog .ui-button input { cursor: pointer;}
+
+/* error/notify/confirm dialogs icon */
+.elfinder-dialog-icon {
+	position:absolute;
+	width:32px;
+	height:32px;
+	left:12px;
+	top:50%;
+	margin-top:-15px;
+	background:url("../img/dialogs.png") 0 0 no-repeat;
+}
+
+.elfinder-rtl .elfinder-dialog-icon { left:auto; right:12px;}
+
+
+
+/*********************** ERROR DIALOG **************************/
+
+.elfinder-dialog-error .ui-dialog-content,
+.elfinder-dialog-confirm .ui-dialog-content { padding-left: 56px; min-height:35px; }
+
+.elfinder-rtl .elfinder-dialog-error .ui-dialog-content,
+.elfinder-rtl .elfinder-dialog-confirm .ui-dialog-content { padding-left:0; padding-right: 56px; }
+
+/*********************** NOTIFY DIALOG **************************/
+
+.elfinder-dialog-notify .ui-dialog-titlebar-close { display:none; }
+.elfinder-dialog-notify .ui-dialog-content { padding:0; }
+
+/* one notification container */
+.elfinder-notify {
+	border-bottom:1px solid #ccc;
+	position:relative;
+	padding:.5em;
+	
+	text-align:center;
+	overflow:hidden;
+}
+
+.elfinder-ltr .elfinder-notify { padding-left:30px; }
+.elfinder-rtl .elfinder-notify { padding-right:30px; }
+
+.elfinder-notify:last-child { border:0 solid; }
+
+/* progressbar */
+.elfinder-notify-progressbar {
+	width:180px;
+	height:8px;
+	border:1px solid #aaa;
+	background:#f5f5f5;
+	margin:5px auto;
+	overflow:hidden;
+}
+
+.elfinder-notify-progress {
+	width:100%;
+	height:8px;
+	background:url(../img/progress.gif) center center repeat-x;
+}
+
+.elfinder-notify-progressbar, .elfinder-notify-progress {
+	-moz-border-radius: 2px; 
+	-webkit-border-radius: 2px; 
+	border-radius: 2px;
+}
+
+/* icons */
+.elfinder-dialog-icon-open, 
+.elfinder-dialog-icon-file        { background-position: 0 -225px; }
+.elfinder-dialog-icon-reload      { background-position: 0 -225px; }
+.elfinder-dialog-icon-mkdir       { background-position: 0 -64px; }
+.elfinder-dialog-icon-mkfile      { background-position: 0 -96px; }
+.elfinder-dialog-icon-copy,
+.elfinder-dialog-icon-prepare,
+.elfinder-dialog-icon-move        { background-position: 0 -128px;}
+.elfinder-dialog-icon-upload      { background-position: 0 -160px; }
+.elfinder-dialog-icon-rm          { background-position: 0 -192px; }
+.elfinder-dialog-icon-download    { background-position: 0 -260px; }
+.elfinder-dialog-icon-save        { background-position: 0 -295px; }
+.elfinder-dialog-icon-rename      { background-position: 0 -330px; }
+.elfinder-dialog-icon-archive,
+.elfinder-dialog-icon-extract     { background-position: 0 -365px; }
+.elfinder-dialog-icon-search      { background-position: 0 -402px; }
+.elfinder-dialog-icon-resize,
+.elfinder-dialog-icon-loadimg,
+.elfinder-dialog-icon-netmount,
+.elfinder-dialog-icon-netunmount,
+.elfinder-dialog-icon-dim         { background-position: 0 -434px; }
+
+/*********************** CONFIRM DIALOG **************************/
+
+.elfinder-dialog-confirm-applyall {	padding-top:3px; }
+
+.elfinder-dialog-confirm .elfinder-dialog-icon { background-position:0 -32px; }
+
+
+
+/*********************** FILE INFO DIALOG **************************/
+
+
+.elfinder-info-title .elfinder-cwd-icon {
+	float:left;
+	width:48px;
+	height:48px;
+	margin-right:1em;
+}
+
+.elfinder-info-title strong { display:block; padding:.3em 0 .5em 0; }
+
+.elfinder-info-tb {
+	min-width:200px;
+	border:0 solid;
+	margin:1em .2em 1em .2em;
+}
+
+.elfinder-info-tb td { white-space:nowrap; padding:2px; }
+
+.elfinder-info-tb tr td:first-child { text-align:right;  }
+
+.elfinder-info-tb span { float:left;}
+.elfinder-info-tb a { outline: none; text-decoration:underline; }
+.elfinder-info-tb a:hover { text-decoration:none; }
+.elfinder-info-spinner { 
+	width:14px;
+	height:14px;
+	float:left;
+	background: url("../img/spinner-mini.gif") center center no-repeat;
+	margin:0 5px; 
+}
+
+.elfinder-netmount-tb { margin:0 auto; }
+.elfinder-netmount-tb input { border:1px solid #ccc; }
+/*********************** UPLOAD DIALOG **************************/
+
+.elfinder-upload-dropbox {
+	text-align:center;
+	padding:2em 0;
+	border:3px dashed #aaa;
+}
+
+.elfinder-upload-dropbox.ui-state-hover {
+	background:#dfdfdf;
+	border:3px dashed #555;
+}
+
+.elfinder-upload-dialog-or {
+	margin:.3em 0;
+	text-align:center;
+}
+
+.elfinder-upload-dialog-wrapper { text-align:center; }
+
+.elfinder-upload-dialog-wrapper .ui-button { position:relative;	overflow:hidden; }
+
+.elfinder-upload-dialog-wrapper .ui-button form {
+	position:absolute;
+	right:0;
+	top:0;
+	opacity: 0; filter:Alpha(Opacity=0);
+}
+
+.elfinder-upload-dialog-wrapper .ui-button form input {
+	padding:0 20px;
+	font-size:3em;
+
+}
+
+
+/* dialog for elFinder itself */
+.dialogelfinder .dialogelfinder-drag {
+	border-left:0 solid;
+	border-top:0 solid;
+	border-right:0 solid;
+	font-weight:normal;
+	padding:2px 12px;
+	cursor:move;
+	position:relative;
+	text-align:left;
+}
+
+.elfinder-rtl .dialogelfinder-drag { text-align:right;}
+
+.dialogelfinder-drag-close {
+	position: absolute;
+	top:50%;
+	margin-top:-8px;
+}
+
+.elfinder-ltr .dialogelfinder-drag-close { right:12px; }
+.elfinder-rtl .dialogelfinder-drag-close { left:12px; }
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/fonts.css */
+.elfinder-contextmenu .elfinder-contextmenu-item span { font-size:.76em; }
+
+.elfinder-cwd-view-icons .elfinder-cwd-filename { font-size:.7em; }
+.elfinder-cwd-view-list td { font-size:.7em; }
+
+.std42-dialog .ui-dialog-titlebar { font-size:.82em; }
+.std42-dialog .ui-dialog-content { font-size:.72em; }
+.std42-dialog .ui-dialog-buttonpane { font-size:.76em; }
+.elfinder-info-tb { font-size:.9em; }
+.elfinder-upload-dropbox { font-size:1.2em; }
+.elfinder-upload-dialog-or { font-size:1.2em; }
+.dialogelfinder .dialogelfinder-drag { font-size:.9em; }
+.elfinder .elfinder-navbar { font-size:.72em; }
+.elfinder-place-drag .elfinder-navbar-dir { font-size:.9em;}
+.elfinder-quicklook-title { font-size:.7em; }
+.elfinder-quicklook-info-data { font-size:.72em; }
+.elfinder-quicklook-preview-text-wrapper { font-size:.9em; }
+.elfinder-button-menu-item { font-size:.72em; }
+.elfinder-button-search input { font-size:.8em; }
+.elfinder-statusbar div { font-size:.7em; }
+.elfinder-drag-num { font-size:12px; }
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/navbar.css */
+/*********************************************/
+/*              NAVIGATION PANEL             */
+/*********************************************/
+
+/* container */
+.elfinder .elfinder-navbar {
+	width:230px;
+	padding:3px 5px;
+	background-image:none;
+	border-top:0 solid;
+	border-bottom:0 solid;
+	overflow:auto;
+	display:none;
+	position:relative;
+	-moz-user-select: none;
+	-khtml-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+/*	border:1px solid #111;*/
+}
+
+
+/* ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar { float:left;  border-left:0 solid; }
+.elfinder-rtl .elfinder-navbar { float:right; border-right:0 solid; }
+.elfinder-ltr .ui-resizable-e { margin-left:10px; }
+
+/* folders tree container */
+.elfinder-tree { display:table; width:100%; margin: 0 0 .5em 0; }
+
+/* one folder wrapper */
+.elfinder-navbar-wrapper, .elfinder-place-wrapper { }
+
+/* folder */
+.elfinder-navbar-dir { 
+	position:relative; 
+	display:block; 
+	white-space:nowrap;
+	padding:3px 12px;
+	margin: 0;
+	outline:0px solid;
+	border:1px solid transparent;
+	cursor:default;
+	
+}
+
+/* ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar-dir { padding-left:35px; }
+.elfinder-rtl .elfinder-navbar-dir { padding-right:35px; }
+
+/* arrow before icon */
+.elfinder-navbar-arrow {
+	width:12px;
+	height:14px;
+	position:absolute;
+	display:none;
+	top:50%;
+	margin-top:-8px;
+	background-image:url("../img/arrows-normal.png");
+	background-repeat:no-repeat;
+/*	border:1px solid #111;*/
+}
+
+.ui-state-active .elfinder-navbar-arrow { background-image:url("../img/arrows-active.png"); }
+
+/* collapsed/expanded arrow view */
+.elfinder-navbar-collapsed .elfinder-navbar-arrow { display:block; }
+
+/* arrow ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar-collapsed .elfinder-navbar-arrow { background-position: 0 4px; left:0; }
+.elfinder-rtl .elfinder-navbar-collapsed .elfinder-navbar-arrow { background-position: 0 -10px; right:0;  }
+.elfinder-ltr .elfinder-navbar-expanded  .elfinder-navbar-arrow,
+.elfinder-rtl .elfinder-navbar-expanded  .elfinder-navbar-arrow { background-position:0 -21px; }
+
+
+/* folder icon */
+.elfinder-navbar-icon {
+	width:16px;
+	height:16px;
+	position:absolute;
+	top:50%;
+	margin-top:-8px;
+	background-image:url("../img/toolbar.png");
+	background-repeat:no-repeat;
+	background-position:0 -16px;
+}
+
+/* ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar-icon { left:14px; }
+.elfinder-rtl .elfinder-navbar-icon { right:14px; }
+
+/* root folder */
+.elfinder-tree   .elfinder-navbar-root .elfinder-navbar-icon { background-position:0 0; }
+.elfinder-places .elfinder-navbar-root .elfinder-navbar-icon { background-position:0 -48px; }
+
+/* icon in active/hove/dropactive state */
+.ui-state-active           .elfinder-navbar-icon, 
+.elfinder-droppable-active .elfinder-navbar-icon, 
+.ui-state-hover            .elfinder-navbar-icon { background-position:0 -32px; }
+
+/* subdirs tree */
+.elfinder-navbar-subtree { display:none; }
+
+/* ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar-subtree { margin-left:12px; }
+.elfinder-rtl .elfinder-navbar-subtree { margin-right:12px; }
+
+
+/* spinner */
+.elfinder-navbar-spinner { 
+	width:14px;
+	height:14px;
+	position:absolute;
+	display:block;
+	top:50%;
+	margin-top:-7px;
+	background: url("../img/spinner-mini.gif") center center no-repeat;
+}
+/* spinner ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar-spinner { left:0;  margin-left:-2px; }
+.elfinder-rtl .elfinder-navbar-spinner { right:0; margin-right:-2px; }
+
+/* permissions marker */
+.elfinder-navbar .elfinder-perms { top:50%; margin-top:-8px; }
+
+/* permissions/symlink markers ltr/rtl enviroment */
+.elfinder-ltr .elfinder-navbar .elfinder-perms   { left:  18px; }
+.elfinder-rtl .elfinder-navbar .elfinder-perms   { right: 18px; }
+.elfinder-ltr .elfinder-navbar .elfinder-symlink { left:  8px; }
+.elfinder-rtl .elfinder-navbar .elfinder-symlink { right: 8px; }
+
+/* resizable */
+.elfinder-navbar .ui-resizable-handle { width:12px; background:transparent url('../img/resize.png') center center no-repeat; left:0; }
+.elfinder-nav-handle-icon {
+	position:absolute;
+	top:50%;
+	margin:-8px 2px 0 2px;
+	opacity: .5; filter:Alpha(Opacity=50);
+}
+
+.elfinder-places { border:1px solid transparent;}
+.elfinder-places.elfinder-droppable-active {
+	border:1px solid #8cafed;
+}
+
+
+
+
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/places.css */
+
+/* File: /home/osc/elFinder-build/elFinder/css/quicklook.css */
+/* quicklook window */
+.elfinder-quicklook {
+	position:absolute;
+	background:url("../img/quicklook-bg.png");
+	display:none;
+	overflow:hidden;
+	border-radius:7px;
+	-moz-border-radius:7px;
+	-webkit-border-radius:7px;
+	padding:20px 0 40px 0;
+}
+
+.elfinder-quicklook .ui-resizable-se { 
+	width:14px;
+	height:14px;
+	right:5px;
+	bottom:3px;
+	background:url("../img/toolbar.png") 0 -496px no-repeat;}
+
+/* quicklook fullscreen window */
+.elfinder-quicklook-fullscreen {
+	border-radius:0;
+	-moz-border-radius:0;
+	-webkit-border-radius:0;
+	-webkit-background-clip: padding-box;
+/*	background-clip:padding-box;*/
+	padding:0;
+	background:#000;
+	z-index:90000;
+	display:block;
+}
+/* hide titlebar in fullscreen mode */
+.elfinder-quicklook-fullscreen .elfinder-quicklook-titlebar { display:none; }
+
+/* hide preview border in fullscreen mode */
+.elfinder-quicklook-fullscreen .elfinder-quicklook-preview { border:0 solid ;}
+
+/* quicklook titlebar */
+.elfinder-quicklook-titlebar {
+	text-align:center;
+	background:#777;
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:20px;
+	-moz-border-radius-topleft: 7px; 
+	-webkit-border-top-left-radius: 7px; 
+	border-top-left-radius: 7px;
+	-moz-border-radius-topright: 7px; 
+	-webkit-border-top-right-radius: 7px; 
+	border-top-right-radius: 7px;
+	cursor:move;
+}
+
+/* window title */
+.elfinder-quicklook-title { 
+	color:#fff; 
+	white-space:nowrap; 
+	overflow:hidden;
+	padding:2px 0;
+}
+
+/* icon "close" in titlebar */
+.elfinder-quicklook-titlebar .ui-icon { 
+	position:absolute;
+	left : 4px;
+	top:50%;
+	margin-top:-8px;
+	width:16px;
+	height:16px;
+	cursor:default;
+}
+
+/* main part of quicklook window */
+.elfinder-quicklook-preview {
+	overflow:hidden;
+	position:relative;
+	border:0 solid;
+	border-left:1px solid transparent;
+	border-right:1px solid transparent;
+	height:100%;
+}
+
+/* wrapper for file info/icon */
+.elfinder-quicklook-info-wrapper {
+	position:absolute;
+	width:100%;
+	left:0;
+	top:50%;
+	margin-top:-50px;
+}
+
+/* file info */
+.elfinder-quicklook-info {
+	padding: 0 12px 0 112px;
+}
+
+/* file name in info */
+.elfinder-quicklook-info .elfinder-quicklook-info-data:first-child { 
+	color:#fff; 
+	font-weight:bold; 
+	padding-bottom:.5em; 
+}
+
+/* other data in info */
+.elfinder-quicklook-info-data {
+	padding-bottom:.2em;
+	color:#fff;
+}
+
+
+/* file icon */
+.elfinder-quicklook .elfinder-cwd-icon {
+	position:absolute;
+	left:32px;
+	top:50%;
+	margin-top:-20px;
+}
+
+/* image in preview */
+.elfinder-quicklook-preview img {
+	display:block;
+	margin:0 auto;
+}
+
+/* navigation bar on quicklook window bottom */
+.elfinder-quicklook-navbar {
+	position:absolute;
+	left:50%;
+	bottom:4px;
+	width:140px;
+	height:32px;
+	padding:0px;
+	margin-left:-70px;
+	border:1px solid transparent;
+	border-radius:19px;
+	-moz-border-radius:19px;
+	-webkit-border-radius:19px;
+}
+
+/* navigation bar in fullscreen mode */
+.elfinder-quicklook-fullscreen .elfinder-quicklook-navbar {
+	width:188px;
+	margin-left:-94px;
+	padding:5px;
+	border:1px solid #eee;
+	background:#000;
+}
+
+/* show close icon in fullscreen mode */
+.elfinder-quicklook-fullscreen .elfinder-quicklook-navbar-icon-close,
+.elfinder-quicklook-fullscreen .elfinder-quicklook-navbar-separator {
+	display:inline;
+}
+
+/* icons in navbar */
+.elfinder-quicklook-navbar-icon {
+	width:32px;
+	height:32px;
+	margin:0 7px;
+	float:left;
+	background:url("../img/quicklook-icons.png") 0 0 no-repeat;
+	
+}
+
+/* fullscreen icon */
+.elfinder-quicklook-navbar-icon-fullscreen {
+	background-position:0 -64px;
+}
+
+/* exit fullscreen icon */
+.elfinder-quicklook-navbar-icon-fullscreen-off {
+	background-position:0 -96px;
+}
+
+/* prev file icon */
+.elfinder-quicklook-navbar-icon-prev {
+	background-position:0 0;
+}
+
+/* next file icon */
+.elfinder-quicklook-navbar-icon-next {
+	background-position:0 -32px;
+}
+
+/* close icon */
+.elfinder-quicklook-navbar-icon-close {
+	background-position:0 -128px;
+	display:none;
+}
+
+/* icons separator */
+.elfinder-quicklook-navbar-separator {
+	width:1px;
+	height:32px;
+	float:left;
+	border-left:1px solid #fff;
+	display:none;
+}
+
+/* text files preview wrapper */
+.elfinder-quicklook-preview-text-wrapper {
+	width: 100%;
+	height:100%;
+	background:#fff;
+	color:#222;
+	overflow:auto;
+}
+
+/* text preview */
+pre.elfinder-quicklook-preview-text {
+	margin:0;
+	padding:3px 9px;
+}
+
+/* html/pdf preview */
+.elfinder-quicklook-preview-html,
+.elfinder-quicklook-preview-pdf {
+	width:100%;
+	height:100%;
+	background:#fff;
+	border:0 solid;
+	margin:0;
+}
+
+/* swf preview container */
+.elfinder-quicklook-preview-flash {
+	width:100%;
+	height:100%;
+}
+
+/* audio preview container */
+.elfinder-quicklook-preview-audio {
+	width:100%;
+	position:absolute;
+	bottom:0;
+	left:0;
+}
+
+/* audio preview using embed */
+embed.elfinder-quicklook-preview-audio {
+	height:30px;
+	background:transparent;
+}
+
+/* video preview container */
+.elfinder-quicklook-preview-video {
+	width:100%;
+	height:100%;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* File: /home/osc/elFinder-build/elFinder/css/statusbar.css */
+/******************************************************************/
+/*                           STATUSBAR STYLES                     */
+/******************************************************************/
+
+
+/* statusbar container */
+.elfinder-statusbar { 
+	text-align:center; 
+	font-weight:normal;
+	padding:.2em .5em;
+	
+	border-right:0 solid transparent;
+	border-bottom:0 solid transparent;
+	border-left:0 solid transparent;
+}
+
+.elfinder-statusbar a { text-decoration:none; }
+
+
+
+/* path in statusbar */
+.elfinder-path {
+	max-width:30%;
+	white-space:nowrap;
+	overflow:hidden;
+	text-overflow:ellipsis;
+    -o-text-overflow:ellipsis;
+}
+.elfinder-ltr .elfinder-path { float:left;  }
+.elfinder-rtl .elfinder-path { float:right; }
+
+/* total/selected size in statusbar */
+.elfinder-stat-size { white-space:nowrap; }
+.elfinder-ltr .elfinder-stat-size { float:right; }
+.elfinder-rtl .elfinder-stat-size { float:left; }
+
+.elfinder-stat-selected { white-space:nowrap; overflow:hidden; }
+
+/* File: /home/osc/elFinder-build/elFinder/css/toolbar.css */
+/*********************************************/
+/*               TOOLBAR STYLES              */
+/*********************************************/
+/* toolbar container */
+.elfinder-toolbar { 
+	padding:4px 0 3px 0; 
+	border-left:0 solid transparent;
+	border-top:0 solid transparent;
+	border-right:0 solid transparent;
+}
+
+/* container for button's group */
+.elfinder-buttonset {
+	margin: 1px 4px;
+	float:left;
+	background:transparent;
+	padding:0;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+	border-radius: 4px;
+}
+
+/*.elfinder-buttonset:first-child { margin:0; }*/
+
+/* button */
+.elfinder .elfinder-button {
+	width:16px;
+	height:16px;
+	margin:0;
+	padding:4px;
+	float:left;
+	overflow:hidden;
+	position:relative;
+	border:0 solid;
+}
+
+.elfinder .ui-icon-search { cursor:pointer;}
+
+.elfinder-button:first-child {
+	-moz-border-radius-topleft: 4px; 
+	-webkit-border-top-left-radius: 4px; 
+	border-top-left-radius: 4px;
+	-moz-border-radius-bottomleft: 4px; 
+	-webkit-border-bottom-left-radius: 4px; 
+	border-bottom-left-radius: 4px;
+}
+
+.elfinder-button:last-child {
+	-moz-border-radius-topright: 4px; 
+	-webkit-border-top-right-radius: 4px; 
+	border-top-right-radius: 4px;
+	-moz-border-radius-bottomright: 4px; 
+	-webkit-border-bottom-right-radius: 4px; 
+	border-bottom-right-radius: 4px;
+}
+
+/* separator between buttons, required for berder between button with ui color */
+.elfinder-toolbar-button-separator {
+	float:left;
+	padding:0;
+	height:24px;
+	border-top:0 solid;
+	border-right:0 solid;
+	border-bottom:0 solid;
+	width:0;
+}
+
+/* change icon opacity^ not button */
+.elfinder .elfinder-button.ui-state-disabled { opacity:1; filter:Alpha(Opacity=100);}
+.elfinder .elfinder-button.ui-state-disabled .elfinder-button-icon { opacity:.4; filter:Alpha(Opacity=40);}
+
+/* rtl enviroment */
+.elfinder-rtl .elfinder-buttonset { float:right; }
+
+/* icon inside button */
+.elfinder-button-icon {
+	width:16px;
+	height:16px;
+	display:block;
+	background:url('../img/toolbar.png')  no-repeat;
+}
+
+/* buttons icons */
+.elfinder-button-icon-home      { background-position: 0 0;  }
+.elfinder-button-icon-back      { background-position: 0 -112px; }
+.elfinder-button-icon-forward   { background-position: 0 -128px; }
+.elfinder-button-icon-up        { background-position: 0 -144px; }
+.elfinder-button-icon-reload    { background-position: 0 -160px; }
+.elfinder-button-icon-open      { background-position: 0 -176px; } 
+.elfinder-button-icon-mkdir     { background-position: 0 -192px; }
+.elfinder-button-icon-mkfile    { background-position: 0 -208px; }
+.elfinder-button-icon-rm        { background-position: 0 -224px; }
+.elfinder-button-icon-copy      { background-position: 0 -240px; }
+.elfinder-button-icon-cut       { background-position: 0 -256px; }
+.elfinder-button-icon-paste     { background-position: 0 -272px; }
+.elfinder-button-icon-getfile   { background-position: 0 -288px; }
+.elfinder-button-icon-duplicate { background-position: 0 -304px; }
+.elfinder-button-icon-rename    { background-position: 0 -320px; }
+.elfinder-button-icon-edit      { background-position: 0 -336px; }
+.elfinder-button-icon-quicklook { background-position: 0 -352px; }
+.elfinder-button-icon-upload    { background-position: 0 -368px; }
+.elfinder-button-icon-download  { background-position: 0 -384px; }
+.elfinder-button-icon-info      { background-position: 0 -400px; }
+.elfinder-button-icon-extract   { background-position: 0 -416px; }
+.elfinder-button-icon-archive   { background-position: 0 -432px; }
+.elfinder-button-icon-view      { background-position: 0 -448px; }
+.elfinder-button-icon-view-list { background-position: 0 -464px; }
+.elfinder-button-icon-help      { background-position: 0 -480px; }
+.elfinder-button-icon-resize    { background-position: 0 -512px; }
+.elfinder-button-icon-search    { background-position: 0 -561px; }
+.elfinder-button-icon-sort      { background-position: 0 -577px; }
+.elfinder-button-icon-rotate-r  { background-position: 0 -625px; }
+.elfinder-button-icon-rotate-l  { background-position: 0 -641px; }
+
+/* button with dropdown menu*/
+.elfinder .elfinder-menubutton { overflow:visible; }
+
+
+
+/* menu */
+.elfinder-button-menu {
+	position:absolute;
+	left:0;
+	top:25px;
+	padding:3px 0;
+}
+
+/* menu item */
+.elfinder-button-menu-item {
+	white-space:nowrap;
+	cursor:default;
+	padding:5px 19px;
+	position:relative;
+}
+
+/* fix hover ui class */
+.elfinder-button-menu .ui-state-hover { border:0 solid; }
+
+.elfinder-button-menu-item-separated { border-top:1px solid #ccc; }
+
+.elfinder-button-menu-item .ui-icon {
+	width:16px;
+	height:16px;
+	position:absolute;
+	left:2px;
+	top:50%;
+	margin-top:-8px;
+	display:none;
+}
+
+.elfinder-button-menu-item-selected .ui-icon { display:block; }
+.elfinder-button-menu-item-selected-asc .ui-icon-arrowthick-1-n { display:none; }
+.elfinder-button-menu-item-selected-desc .ui-icon-arrowthick-1-s { display:none; }
+
+/* hack for upload button */
+.elfinder-button form {
+	position:absolute;
+	top:0;
+	right:0;
+	opacity: 0; filter:Alpha(Opacity=0);
+	cursor: pointer;
+}
+
+.elfinder .elfinder-button form input { background:transparent; cursor: default;}
+
+/* search "button" */
+.elfinder .elfinder-button-search {
+	border:0 solid;
+	background:transparent;
+	padding:0;
+	margin: 1px 4px;
+	height: auto;
+	min-height: 26px;
+	float:right;
+	width:202px;
+}
+
+/* ltr/rte enviroment */
+.elfinder-ltr .elfinder-button-search { float:right; margin-right:10px; }
+.elfinder-rtl .elfinder-button-search { float:left; margin-left:10px; }
+
+/* search text field */
+.elfinder-button-search input {
+	width:160px;
+	height:22px;
+	padding:0 20px;
+	line-height: 22px;
+	border:0 solid;
+	border:1px solid #aaa;
+	-moz-border-radius: 12px;
+	-webkit-border-radius: 12px;
+	border-radius: 12px;
+	outline:0px solid;
+}
+
+.elfinder-rtl .elfinder-button-search input { direction:rtl; }
+
+/* icons */
+.elfinder-button-search .ui-icon {
+	position:absolute;
+	height:18px;
+	top: 50%;
+	margin:-9px 4px 0 4px;
+	opacity: .6; 
+	filter:Alpha(Opacity=60);
+}
+
+/* search/close icons */
+.elfinder-ltr .elfinder-button-search .ui-icon-search { left:0;}
+.elfinder-rtl .elfinder-button-search .ui-icon-search { right:0;}
+.elfinder-ltr .elfinder-button-search .ui-icon-close { right:0;}
+.elfinder-rtl .elfinder-button-search .ui-icon-close { left:0;}
+
+
+
+
+
+

File diff suppressed because it is too large
+ 2 - 2
main/inc/lib/elfinder/css/elfinder.min.css


+ 1 - 0
main/inc/lib/elfinder/css/theme.css

@@ -12,6 +12,7 @@
 .elfinder .elfinder-navbar { background:#dde4eb; }
 .elfinder-navbar .ui-state-hover  { background:transparent; border-color:transparent; }
 .elfinder-navbar .ui-state-active { background: #3875d7;    border-color:#3875d7; color:#fff; }
+.elfinder-navbar .elfinder-droppable-active {background:#A7C6E5 !important;}
 /* disabled elfinder */
 .elfinder-disabled .elfinder-navbar .ui-state-active { background: #dadada; border-color:#aaa; color:#fff; }
 

+ 15 - 13
main/inc/lib/elfinder/elfinder.html

@@ -1,31 +1,33 @@
 <!DOCTYPE html>
 <html>
 	<head>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta charset="utf-8">
 		<title>elFinder 2.0</title>
 
 		<!-- jQuery and jQuery UI (REQUIRED) -->
-		<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/smoothness/jquery-ui.css">
-		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
-		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
+		<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/smoothness/jquery-ui.css">
+		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
+		<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
 
 		<!-- elFinder CSS (REQUIRED) -->
-		<link rel="stylesheet" type="text/css" media="screen" href="css/elfinder.min.css">
-		<link rel="stylesheet" type="text/css" media="screen" href="css/theme.css">
+		<link rel="stylesheet" type="text/css" href="css/elfinder.min.css">
+		<link rel="stylesheet" type="text/css" href="css/theme.css">
 
 		<!-- elFinder JS (REQUIRED) -->
-		<script type="text/javascript" src="js/elfinder.min.js"></script>
+		<script src="js/elfinder.min.js"></script>
 
 		<!-- elFinder translation (OPTIONAL) -->
-		<script type="text/javascript" src="js/i18n/elfinder.ru.js"></script>
+		<script src="js/i18n/elfinder.ru.js"></script>
 
 		<!-- elFinder initialization (REQUIRED) -->
 		<script type="text/javascript" charset="utf-8">
-			$().ready(function() {
-				var elf = $('#elfinder').elfinder({
-					url : 'php/connector.php'  // connector URL (REQUIRED)
-					// lang: 'ru',             // language (OPTIONAL)
-				}).elfinder('instance');
+			// Documentation for client options:
+			// https://github.com/Studio-42/elFinder/wiki/Client-configuration-options
+			$(document).ready(function() {
+				$('#elfinder').elfinder({
+					url : 'php/connector.minimal.php'  // connector URL (REQUIRED)
+					// , lang: 'ru'                    // language (OPTIONAL)
+				});
 			});
 		</script>
 	</head>

BIN
main/inc/lib/elfinder/img/dialogs.png


+ 11519 - 0
main/inc/lib/elfinder/js/elfinder.full.js

@@ -0,0 +1,11519 @@
+/*!
+ * elFinder - file manager for web
+ * Version 2.1 (Nightly: 093d077) (2013-12-05)
+ * http://elfinder.org
+ * 
+ * Copyright 2009-2013, Studio 42
+ * Licensed under a 3 clauses BSD license
+ */
+(function($) {
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.js
+ */
+
+/**
+ * @class elFinder - file manager for web
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+window.elFinder = function(node, opts) {
+	this.time('load');
+	
+	var self = this,
+		
+		/**
+		 * Node on which elfinder creating
+		 *
+		 * @type jQuery
+		 **/
+		node = $(node),
+		
+		/**
+		 * Store node contents.
+		 *
+		 * @see this.destroy
+		 * @type jQuery
+		 **/
+		prevContent = $('<div/>').append(node.contents()),
+		
+		/**
+		 * Store node inline styles
+		 *
+		 * @see this.destroy
+		 * @type String
+		 **/
+		prevStyle = node.attr('style'),
+		
+		/**
+		 * Instance ID. Required to get/set cookie
+		 *
+		 * @type String
+		 **/
+		id = node.attr('id') || '',
+		
+		/**
+		 * Events namespace
+		 *
+		 * @type String
+		 **/
+		namespace = 'elfinder-'+(id || Math.random().toString().substr(2, 7)),
+		
+		/**
+		 * Mousedown event
+		 *
+		 * @type String
+		 **/
+		mousedown = 'mousedown.'+namespace,
+		
+		/**
+		 * Keydown event
+		 *
+		 * @type String
+		 **/
+		keydown = 'keydown.'+namespace,
+		
+		/**
+		 * Keypress event
+		 *
+		 * @type String
+		 **/
+		keypress = 'keypress.'+namespace,
+		
+		/**
+		 * Is shortcuts/commands enabled
+		 *
+		 * @type Boolean
+		 **/
+		enabled = true,
+		
+		/**
+		 * Store enabled value before ajax requiest
+		 *
+		 * @type Boolean
+		 **/
+		prevEnabled = true,
+		
+		/**
+		 * List of build-in events which mapped into methods with same names
+		 *
+		 * @type Array
+		 **/
+		events = ['enable', 'disable', 'load', 'open', 'reload', 'select',  'add', 'remove', 'change', 'dblclick', 'getfile', 'lockfiles', 'unlockfiles', 'dragstart', 'dragstop'],
+		
+		/**
+		 * Rules to validate data from backend
+		 *
+		 * @type Object
+		 **/
+		rules = {},
+		
+		/**
+		 * Current working directory hash
+		 *
+		 * @type String
+		 **/
+		cwd = '',
+		
+		/**
+		 * Current working directory options
+		 *
+		 * @type Object
+		 **/
+		cwdOptions = {
+			path          : '',
+			url           : '',
+			tmbUrl        : '',
+			disabled      : [],
+			separator     : '/',
+			archives      : [],
+			extract       : [],
+			copyOverwrite : true,
+			uploadMaxSize : 0,
+			tmb           : false // old API
+		},
+		
+		/**
+		 * Files/dirs cache
+		 *
+		 * @type Object
+		 **/
+		files = {},
+		
+		/**
+		 * Selected files hashes
+		 *
+		 * @type Array
+		 **/
+		selected = [],
+		
+		/**
+		 * Events listeners
+		 *
+		 * @type Object
+		 **/
+		listeners = {},
+		
+		/**
+		 * Shortcuts
+		 *
+		 * @type Object
+		 **/
+		shortcuts = {},
+		
+		/**
+		 * Buffer for copied files
+		 *
+		 * @type Array
+		 **/
+		clipboard = [],
+		
+		/**
+		 * Copied/cuted files hashes
+		 * Prevent from remove its from cache.
+		 * Required for dispaly correct files names in error messages
+		 *
+		 * @type Array
+		 **/
+		remember = [],
+		
+		/**
+		 * Queue for 'open' requests
+		 *
+		 * @type Array
+		 **/
+		queue = [],
+		
+		/**
+		 * Commands prototype
+		 *
+		 * @type Object
+		 **/
+		base = new self.command(self),
+		
+		/**
+		 * elFinder node width
+		 *
+		 * @type String
+		 * @default "auto"
+		 **/
+		width  = 'auto',
+		
+		/**
+		 * elFinder node height
+		 *
+		 * @type Number
+		 * @default 400
+		 **/
+		height = 400,
+				
+		beeper = $(document.createElement('audio')).hide().appendTo('body')[0],
+			
+		syncInterval,
+		
+		open = function(data) {
+			if (data.init) {
+				// init - reset cache
+				files = {};
+			} else {
+				// remove only files from prev cwd
+				for (var i in files) {
+					if (files.hasOwnProperty(i) 
+					&& files[i].mime != 'directory' 
+					&& files[i].phash == cwd
+					&& $.inArray(i, remember) === -1) {
+						delete files[i];
+					}
+				}
+			}
+
+			cwd = data.cwd.hash;
+			cache(data.files);
+			if (!files[cwd]) {
+				cache([data.cwd]);
+			}
+			self.lastDir(cwd);
+		},
+		
+		/**
+		 * Store info about files/dirs in "files" object.
+		 *
+		 * @param  Array  files
+		 * @return void
+		 **/
+		cache = function(data) {
+			var l = data.length, f;
+
+			while (l--) {
+				f = data[l];
+				if (f.name && f.hash && f.mime) {
+					if (!f.phash) {
+						var name = 'volume_'+f.name,
+							i18 = self.i18n(name);
+
+						if (name != i18) {
+							f.i18 = i18;
+						}
+					}
+					files[f.hash] = f;
+				} 
+			}
+		},
+		
+		/**
+		 * Exec shortcut
+		 *
+		 * @param  jQuery.Event  keydown/keypress event
+		 * @return void
+		 */
+		execShortcut = function(e) {
+			var code    = e.keyCode,
+				ctrlKey = !!(e.ctrlKey || e.metaKey);
+
+			if (enabled) {
+
+				$.each(shortcuts, function(i, shortcut) {
+					if (shortcut.type    == e.type 
+					&& shortcut.keyCode  == code 
+					&& shortcut.shiftKey == e.shiftKey 
+					&& shortcut.ctrlKey  == ctrlKey 
+					&& shortcut.altKey   == e.altKey) {
+						e.preventDefault()
+						e.stopPropagation();
+						shortcut.callback(e, self);
+						self.debug('shortcut-exec', i+' : '+shortcut.description);
+					}
+				});
+				
+				// prevent tab out of elfinder
+				if (code == 9 && !$(e.target).is(':input')) {
+					e.preventDefault();
+				}
+
+			}
+		},
+		date = new Date(),
+		utc,
+		i18n
+		;
+
+
+	/**
+	 * Protocol version
+	 *
+	 * @type String
+	 **/
+	this.api = null;
+	
+	/**
+	 * elFinder use new api
+	 *
+	 * @type Boolean
+	 **/
+	this.newAPI = false;
+	
+	/**
+	 * elFinder use old api
+	 *
+	 * @type Boolean
+	 **/
+	this.oldAPI = false;
+	
+	/**
+	 * User os. Required to bind native shortcuts for open/rename
+	 *
+	 * @type String
+	 **/
+	this.OS = navigator.userAgent.indexOf('Mac') !== -1 ? 'mac' : navigator.userAgent.indexOf('Win') !== -1  ? 'win' : 'other';
+	
+	/**
+	 * User browser UA.
+	 * jQuery.browser: version deprecated: 1.3, removed: 1.9
+	 *
+	 * @type Object
+	 **/
+	this.UA = (function(){
+		var webkit = !document.uniqueID && !window.opera && !window.sidebar && window.localStorage && typeof window.orientation == "undefined";
+		return {
+			// Browser IE <= IE 6
+			ltIE6:typeof window.addEventListener == "undefined" && typeof document.documentElement.style.maxHeight == "undefined",
+			// Browser IE <= IE 7
+			ltIE7:typeof window.addEventListener == "undefined" && typeof document.querySelectorAll == "undefined",
+			// Browser IE <= IE 8
+			ltIE8:typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined",
+			IE:document.uniqueID,
+			Firefox:window.sidebar,
+			Opera:window.opera,
+			Webkit:webkit,
+			Chrome:webkit && window.chrome,
+			Safari:webkit && !window.chrome,
+			Mobile:typeof window.orientation != "undefined"
+		}
+	})();
+	
+	/**
+	 * Configuration options
+	 *
+	 * @type Object
+	 **/
+	this.options = $.extend(true, {}, this._options, opts||{});
+	
+	if (opts.ui) {
+		this.options.ui = opts.ui;
+	}
+	
+	if (opts.commands) {
+		this.options.commands = opts.commands;
+	}
+	
+	if (opts.uiOptions && opts.uiOptions.toolbar) {
+		this.options.uiOptions.toolbar = opts.uiOptions.toolbar;
+	}
+
+	$.extend(this.options.contextmenu, opts.contextmenu);
+
+	
+	/**
+	 * Ajax request type
+	 *
+	 * @type String
+	 * @default "get"
+	 **/
+	this.requestType = /^(get|post)$/i.test(this.options.requestType) ? this.options.requestType.toLowerCase() : 'get',
+	
+	/**
+	 * Any data to send across every ajax request
+	 *
+	 * @type Object
+	 * @default {}
+	 **/
+	this.customData = $.isPlainObject(this.options.customData) ? this.options.customData : {};
+	
+	/**
+	 * ID. Required to create unique cookie name
+	 *
+	 * @type String
+	 **/
+	this.id = id;
+	
+	/**
+	 * URL to upload files
+	 *
+	 * @type String
+	 **/
+	this.uploadURL = opts.urlUpload || opts.url;
+	
+	/**
+	 * Events namespace
+	 *
+	 * @type String
+	 **/
+	this.namespace = namespace;
+
+	/**
+	 * Interface language
+	 *
+	 * @type String
+	 * @default "en"
+	 **/
+	this.lang = this.i18[this.options.lang] && this.i18[this.options.lang].messages ? this.options.lang : 'en';
+	
+	i18n = this.lang == 'en' 
+		? this.i18['en'] 
+		: $.extend(true, {}, this.i18['en'], this.i18[this.lang]);
+	
+	/**
+	 * Interface direction
+	 *
+	 * @type String
+	 * @default "ltr"
+	 **/
+	this.direction = i18n.direction;
+	
+	/**
+	 * i18 messages
+	 *
+	 * @type Object
+	 **/
+	this.messages = i18n.messages;
+	
+	/**
+	 * Date/time format
+	 *
+	 * @type String
+	 * @default "m.d.Y"
+	 **/
+	this.dateFormat = this.options.dateFormat || i18n.dateFormat;
+	
+	/**
+	 * Date format like "Yesterday 10:20:12"
+	 *
+	 * @type String
+	 * @default "{day} {time}"
+	 **/
+	this.fancyFormat = this.options.fancyDateFormat || i18n.fancyDateFormat;
+
+	/**
+	 * Today timestamp
+	 *
+	 * @type Number
+	 **/
+	this.today = (new Date(date.getFullYear(), date.getMonth(), date.getDate())).getTime()/1000;
+	
+	/**
+	 * Yesterday timestamp
+	 *
+	 * @type Number
+	 **/
+	this.yesterday = this.today - 86400;
+	
+	utc = this.options.UTCDate ? 'UTC' : '';
+	
+	this.getHours    = 'get'+utc+'Hours';
+	this.getMinutes  = 'get'+utc+'Minutes';
+	this.getSeconds  = 'get'+utc+'Seconds';
+	this.getDate     = 'get'+utc+'Date';
+	this.getDay      = 'get'+utc+'Day';
+	this.getMonth    = 'get'+utc+'Month';
+	this.getFullYear = 'get'+utc+'FullYear';
+	
+	/**
+	 * Css classes 
+	 *
+	 * @type String
+	 **/
+	this.cssClass = 'ui-helper-reset ui-helper-clearfix ui-widget ui-widget-content ui-corner-all elfinder elfinder-'+(this.direction == 'rtl' ? 'rtl' : 'ltr')+' '+this.options.cssClass;
+
+	/**
+	 * Method to store/fetch data
+	 *
+	 * @type Function
+	 **/
+	this.storage = (function() {
+		try {
+			return 'localStorage' in window && window['localStorage'] !== null ? self.localStorage : self.cookie;
+		} catch (e) {
+			return self.cookie;
+		}
+	})();
+
+	this.viewType = this.storage('view') || this.options.defaultView || 'icons';
+
+	this.sortType = this.storage('sortType') || this.options.sortType || 'name';
+	
+	this.sortOrder = this.storage('sortOrder') || this.options.sortOrder || 'asc';
+
+	this.sortStickFolders = this.storage('sortStickFolders');
+
+	if (this.sortStickFolders === null) {
+		this.sortStickFolders = !!this.options.sortStickFolders;
+	} else {
+		this.sortStickFolders = !!this.sortStickFolders
+	}
+
+	this.sortRules = $.extend(true, {}, this._sortRules, this.options.sortsRules);
+	
+	$.each(this.sortRules, function(name, method) {
+		if (typeof method != 'function') {
+			delete self.sortRules[name];
+		} 
+	});
+	
+	this.compare = $.proxy(this.compare, this);
+	
+	/**
+	 * Delay in ms before open notification dialog
+	 *
+	 * @type Number
+	 * @default 500
+	 **/
+	this.notifyDelay = this.options.notifyDelay > 0 ? parseInt(this.options.notifyDelay) : 500;
+	
+	/**
+	 * Base draggable options
+	 *
+	 * @type Object
+	 **/
+	this.draggable = {
+		appendTo   : 'body',
+		addClasses : true,
+		delay      : 30,
+		revert     : true,
+		refreshPositions : true,
+		cursor     : 'move',
+		cursorAt   : {left : 50, top : 47},
+		drag       : function(e, ui) {
+			if (! ui.helper.data('locked')) {
+				ui.helper.toggleClass('elfinder-drag-helper-plus', e.shiftKey||e.ctrlKey||e.metaKey);
+			}
+		},
+		start      : function(e, ui) {
+			var targets = $.map(ui.helper.data('files')||[], function(h) { return h || null ;}),
+			cnt, h;
+			cnt = targets.length;
+			while (cnt--) {
+				h = targets[cnt];
+				if (files[h].locked) {
+					ui.helper.addClass('elfinder-drag-helper-plus').data('locked', true);
+					break;
+				}
+			}
+		},
+		stop       : function() { self.trigger('focus').trigger('dragstop'); },
+		helper     : function(e, ui) {
+			var element = this.id ? $(this) : $(this).parents('[id]:first'),
+				helper  = $('<div class="elfinder-drag-helper"><span class="elfinder-drag-helper-icon-plus"/></div>'),
+				icon    = function(mime) { return '<div class="elfinder-cwd-icon '+self.mime2class(mime)+' ui-corner-all"/>'; },
+				hashes, l;
+			
+			self.trigger('dragstart', {target : element[0], originalEvent : e});
+			
+			hashes = element.is('.'+self.res('class', 'cwdfile')) 
+				? self.selected() 
+				: [self.navId2Hash(element.attr('id'))];
+			
+			helper.append(icon(files[hashes[0]].mime)).data('files', hashes).data('locked', false);
+
+			if ((l = hashes.length) > 1) {
+				helper.append(icon(files[hashes[l-1]].mime) + '<span class="elfinder-drag-num">'+l+'</span>');
+			}
+			
+			return helper;
+		}
+	};
+	
+	/**
+	 * Base droppable options
+	 *
+	 * @type Object
+	 **/
+	this.droppable = {
+			// greedy     : true,
+			tolerance  : 'pointer',
+			accept     : '.elfinder-cwd-file-wrapper,.elfinder-navbar-dir,.elfinder-cwd-file',
+			hoverClass : this.res('class', 'adroppable'),
+			drop : function(e, ui) {
+				var dst     = $(this),
+					targets = $.map(ui.helper.data('files')||[], function(h) { return h || null }),
+					result  = [],
+					c       = 'class',
+					cnt, hash, i, h;
+				
+				if (dst.is('.'+self.res(c, 'cwd'))) {
+					hash = cwd;
+				} else if (dst.is('.'+self.res(c, 'cwdfile'))) {
+					hash = dst.attr('id');
+				} else if (dst.is('.'+self.res(c, 'navdir'))) {
+					hash = self.navId2Hash(dst.attr('id'));
+				}
+
+				cnt = targets.length;
+				
+				while (cnt--) {
+					h = targets[cnt];
+					// ignore drop into itself or in own location
+					h != hash && files[h].phash != hash && result.push(h);
+				}
+				
+				if (result.length) {
+					ui.helper.hide();
+					self.clipboard(result, !(e.ctrlKey||e.shiftKey||e.metaKey||ui.helper.data('locked')));
+					self.exec('paste', hash);
+					self.trigger('drop', {files : targets});
+
+				}
+			}
+		};
+	
+	/**
+	 * Return true if filemanager is active
+	 *
+	 * @return Boolean
+	 **/
+	this.enabled = function() {
+		return node.is(':visible') && enabled;
+	}
+	
+	/**
+	 * Return true if filemanager is visible
+	 *
+	 * @return Boolean
+	 **/
+	this.visible = function() {
+		return node.is(':visible');
+	}
+	
+	/**
+	 * Return root dir hash for current working directory
+	 * 
+	 * @return String
+	 */
+	this.root = function(hash) {
+		var dir = files[hash || cwd], i;
+		
+		while (dir && dir.phash) {
+			dir = files[dir.phash]
+		}
+		if (dir) {
+			return dir.hash;
+		}
+		
+		while (i in files && files.hasOwnProperty(i)) {
+			dir = files[i]
+			if (!dir.phash && !dir.mime == 'directory' && dir.read) {
+				return dir.hash
+			}
+		}
+		
+		return '';
+	}
+	
+	/**
+	 * Return current working directory info
+	 * 
+	 * @return Object
+	 */
+	this.cwd = function() {
+		return files[cwd] || {};
+	}
+	
+	/**
+	 * Return required cwd option
+	 * 
+	 * @param  String  option name
+	 * @return mixed
+	 */
+	this.option = function(name) {
+		return cwdOptions[name]||'';
+	}
+	
+	/**
+	 * Return file data from current dir or tree by it's hash
+	 * 
+	 * @param  String  file hash
+	 * @return Object
+	 */
+	this.file = function(hash) { 
+		return files[hash]; 
+	};
+	
+	/**
+	 * Return all cached files
+	 * 
+	 * @return Array
+	 */
+	this.files = function() {
+		return $.extend(true, {}, files);
+	}
+	
+	/**
+	 * Return list of file parents hashes include file hash
+	 * 
+	 * @param  String  file hash
+	 * @return Array
+	 */
+	this.parents = function(hash) {
+		var parents = [],
+			dir;
+		
+		while ((dir = this.file(hash))) {
+			parents.unshift(dir.hash);
+			hash = dir.phash;
+		}
+		return parents;
+	}
+	
+	this.path2array = function(hash, i18) {
+		var file, 
+			path = [];
+			
+		while (hash && (file = files[hash]) && file.hash) {
+			path.unshift(i18 && file.i18 ? file.i18 : file.name);
+			hash = file.phash;
+		}
+			
+		return path;
+	}
+	
+	/**
+	 * Return file path
+	 * 
+	 * @param  Object  file
+	 * @return String
+	 */
+	this.path = function(hash, i18) { 
+		return files[hash] && files[hash].path
+			? files[hash].path
+			: this.path2array(hash, i18).join(cwdOptions.separator);
+	}
+	
+	/**
+	 * Return file url if set
+	 * 
+	 * @param  Object  file
+	 * @return String
+	 */
+	this.url = function(hash) {
+		var file = files[hash];
+		
+		if (!file || !file.read) {
+			return '';
+		}
+		
+		if (file.url) {
+			return file.url;
+		}
+		
+		if (cwdOptions.url) {
+			return cwdOptions.url + $.map(this.path2array(hash), function(n) { return encodeURIComponent(n); }).slice(1).join('/')
+		}
+
+		var params = $.extend({}, this.customData, {
+			cmd: 'file',
+			target: file.hash
+		});
+		if (this.oldAPI) {
+			params.cmd = 'open';
+			params.current = file.phash;
+		}
+		return this.options.url + (this.options.url.indexOf('?') === -1 ? '?' : '&') + $.param(params, true);
+	}
+	
+	/**
+	 * Return thumbnail url
+	 * 
+	 * @param  String  file hash
+	 * @return String
+	 */
+	this.tmb = function(hash) {
+		var file = files[hash],
+			url = file && file.tmb && file.tmb != 1 ? cwdOptions['tmbUrl'] + file.tmb : '';
+		
+		if (url && (this.UA.Opera || this.UA.IE)) {
+			url += '?_=' + new Date().getTime();
+		}
+		return url;
+	}
+	
+	/**
+	 * Return selected files hashes
+	 *
+	 * @return Array
+	 **/
+	this.selected = function() {
+		return selected.slice(0);
+	}
+	
+	/**
+	 * Return selected files info
+	 * 
+	 * @return Array
+	 */
+	this.selectedFiles = function() {
+		return $.map(selected, function(hash) { return files[hash] ? $.extend({}, files[hash]) : null });
+	};
+	
+	/**
+	 * Return true if file with required name existsin required folder
+	 * 
+	 * @param  String  file name
+	 * @param  String  parent folder hash
+	 * @return Boolean
+	 */
+	this.fileByName = function(name, phash) {
+		var hash;
+	
+		for (hash in files) {
+			if (files.hasOwnProperty(hash) && files[hash].phash == phash && files[hash].name == name) {
+				return files[hash];
+			}
+		}
+	};
+	
+	/**
+	 * Valid data for required command based on rules
+	 * 
+	 * @param  String  command name
+	 * @param  Object  cammand's data
+	 * @return Boolean
+	 */
+	this.validResponse = function(cmd, data) {
+		return data.error || this.rules[this.rules[cmd] ? cmd : 'defaults'](data);
+	}
+	
+	/**
+	 * Return bytes from ini formated size
+	 * 
+	 * @param  String  ini formated size
+	 * @return Integer
+	 */
+	this.returnBytes = function(val) {
+		if (val == '-1') val = 0;
+		if (val) {
+			// for ex. 1mb, 1KB
+			val = val.replace(/b$/i, '');
+			var last = val.charAt(val.length - 1).toLowerCase();
+			val = val.replace(/[gmk]$/i, '');
+			if (last == 'g') {
+				val = val * 1024 * 1024 * 1024;
+			} else if (last == 'm') {
+				val = val * 1024 * 1024;
+			} else if (last == 'k') {
+				val = val * 1024;
+			}
+		}
+		return val;
+	};
+	
+	/**
+	 * Proccess ajax request.
+	 * Fired events :
+	 * @todo
+	 * @example
+	 * @todo
+	 * @return $.Deferred
+	 */
+	this.request = function(options) { 
+		var self     = this,
+			o        = this.options,
+			dfrd     = $.Deferred(),
+			// request data
+			data     = $.extend({}, o.customData, {mimes : o.onlyMimes}, options.data || options),
+			// command name
+			cmd      = data.cmd,
+			// call default fail callback (display error dialog) ?
+			deffail  = !(options.preventDefault || options.preventFail),
+			// call default success callback ?
+			defdone  = !(options.preventDefault || options.preventDone),
+			// options for notify dialog
+			notify   = $.extend({}, options.notify),
+			// do not normalize data - return as is
+			raw      = !!options.raw,
+			// sync files on request fail
+			syncOnFail = options.syncOnFail,
+			// open notify dialog timeout		
+			timeout, 
+			// request options
+			options = $.extend({
+				url      : o.url,
+				async    : true,
+				type     : this.requestType,
+				dataType : 'json',
+				cache    : false,
+				// timeout  : 100,
+				data     : data
+			}, options.options || {}),
+			/**
+			 * Default success handler. 
+			 * Call default data handlers and fire event with command name.
+			 *
+			 * @param Object  normalized response data
+			 * @return void
+			 **/
+			done = function(data) {
+				data.warning && self.error(data.warning);
+				
+				cmd == 'open' && open($.extend(true, {}, data));
+
+				// fire some event to update cache/ui
+				data.removed && data.removed.length && self.remove(data);
+				data.added   && data.added.length   && self.add(data);
+				data.changed && data.changed.length && self.change(data);
+				
+				// fire event with command name
+				self.trigger(cmd, data);
+				
+				// force update content
+				data.sync && self.sync();
+			},
+			/**
+			 * Request error handler. Reject dfrd with correct error message.
+			 *
+			 * @param jqxhr  request object
+			 * @param String request status
+			 * @return void
+			 **/
+			error = function(xhr, status) {
+				var error;
+				
+				switch (status) {
+					case 'abort':
+						error = xhr.quiet ? '' : ['errConnect', 'errAbort'];
+						break;
+					case 'timeout':	    
+						error = ['errConnect', 'errTimeout'];
+						break;
+					case 'parsererror': 
+						error = ['errResponse', 'errDataNotJSON'];
+						break;
+					default:
+						if (xhr.status == 403) {
+							error = ['errConnect', 'errAccess'];
+						} else if (xhr.status == 404) {
+							error = ['errConnect', 'errNotFound'];
+						} else {
+							error = 'errConnect';
+						} 
+				}
+				
+				dfrd.reject(error, xhr, status);
+			},
+			/**
+			 * Request success handler. Valid response data and reject/resolve dfrd.
+			 *
+			 * @param Object  response data
+			 * @param String request status
+			 * @return void
+			 **/
+			success = function(response) {
+				if (raw) {
+					return dfrd.resolve(response);
+				}
+				
+				if (!response) {
+					return dfrd.reject(['errResponse', 'errDataEmpty'], xhr);
+				} else if (!$.isPlainObject(response)) {
+					return dfrd.reject(['errResponse', 'errDataNotJSON'], xhr);
+				} else if (response.error) {
+					return dfrd.reject(response.error, xhr);
+				} else if (!self.validResponse(cmd, response)) {
+					return dfrd.reject('errResponse', xhr);
+				}
+
+				response = self.normalize(response);
+
+				if (!self.api) {
+					self.api    = response.api || 1;
+					self.newAPI = self.api >= 2;
+					self.oldAPI = !self.newAPI;
+				}
+				
+				if (response.options) {
+					cwdOptions = $.extend({}, cwdOptions, response.options);
+				}
+
+				if (response.netDrivers) {
+					self.netDrivers = response.netDrivers;
+				}
+
+				if (cmd == 'open' && !!data.init) {
+					self.uplMaxSize = self.returnBytes(response.uplMaxSize);
+					self.uplMaxFile = !!response.uplMaxFile? parseInt(response.uplMaxFile) : 20;
+				}
+
+				dfrd.resolve(response);
+				response.debug && self.debug('backend-debug', response.debug);
+			},
+			xhr, _xhr
+			;
+
+		defdone && dfrd.done(done);
+		dfrd.fail(function(error) {
+			if (error) {
+				deffail ? self.error(error) : self.debug('error', self.i18n(error));
+			}
+		})
+		
+		if (!cmd) {
+			return dfrd.reject('errCmdReq');
+		}	
+
+		if (syncOnFail) {
+			dfrd.fail(function(error) {
+				error && self.sync();
+			});
+		}
+
+		if (notify.type && notify.cnt) {
+			timeout = setTimeout(function() {
+				self.notify(notify);
+				dfrd.always(function() {
+					notify.cnt = -(parseInt(notify.cnt)||0);
+					self.notify(notify);
+				})
+			}, self.notifyDelay)
+			
+			dfrd.always(function() {
+				clearTimeout(timeout);
+			});
+		}
+		
+		// quiet abort not completed "open" requests
+		if (cmd == 'open') {
+			while ((_xhr = queue.pop())) {
+				if (_xhr.state() == 'pending') {
+					_xhr.quiet = true;
+					_xhr.abort();
+				}
+			}
+		}
+
+		delete options.preventFail
+
+		xhr = this.transport.send(options).fail(error).done(success);
+		
+		// this.transport.send(options)
+		
+		// add "open" xhr into queue
+		if (cmd == 'open') {
+			queue.unshift(xhr);
+			dfrd.always(function() {
+				var ndx = $.inArray(xhr, queue);
+				
+				ndx !== -1 && queue.splice(ndx, 1);
+			});
+		}
+		
+		return dfrd;
+	};
+	
+	/**
+	 * Compare current files cache with new files and return diff
+	 * 
+	 * @param  Array  new files
+	 * @return Object
+	 */
+	this.diff = function(incoming) {
+		var raw       = {},
+			added     = [],
+			removed   = [],
+			changed   = [],
+			isChanged = function(hash) {
+				var l = changed.length;
+
+				while (l--) {
+					if (changed[l].hash == hash) {
+						return true;
+					}
+				}
+			};
+			
+		$.each(incoming, function(i, f) {
+			raw[f.hash] = f;
+		});
+			
+		// find removed
+		$.each(files, function(hash, f) {
+			!raw[hash] && removed.push(hash);
+		});
+		
+		// compare files
+		$.each(raw, function(hash, file) {
+			var origin = files[hash];
+
+			if (!origin) {
+				added.push(file);
+			} else {
+				$.each(file, function(prop) {
+					if (file[prop] != origin[prop]) {
+						changed.push(file)
+						return false;
+					}
+				});
+			}
+		});
+		
+		// parents of removed dirs mark as changed (required for tree correct work)
+		$.each(removed, function(i, hash) {
+			var file  = files[hash], 
+				phash = file.phash;
+
+			if (phash 
+			&& file.mime == 'directory' 
+			&& $.inArray(phash, removed) === -1 
+			&& raw[phash] 
+			&& !isChanged(phash)) {
+				changed.push(raw[phash]);
+			}
+		});
+		
+		return {
+			added   : added,
+			removed : removed,
+			changed : changed
+		};
+	}
+	
+	/**
+	 * Sync content
+	 * 
+	 * @return jQuery.Deferred
+	 */
+	this.sync = function() {
+		var self  = this,
+			dfrd  = $.Deferred().done(function() { self.trigger('sync'); }),
+			opts1 = {
+				data           : {cmd : 'open', init : 1, target : cwd, tree : this.ui.tree ? 1 : 0},
+				preventDefault : true
+			},
+			opts2 = {
+				data           : {cmd : 'tree', target : (cwd == this.root())? cwd : this.file(cwd).phash},
+				preventDefault : true
+			};
+		
+		$.when(
+			this.request(opts1),
+			this.request(opts2)
+		)
+		.fail(function(error) {
+			dfrd.reject(error);
+			error && self.request({
+				data   : {cmd : 'open', target : self.lastDir(''), tree : 1, init : 1},
+				notify : {type : 'open', cnt : 1, hideCnt : true},
+				preventDefault : true
+			});
+		})
+		.done(function(odata, pdata) {
+			var diff = self.diff(odata.files.concat(pdata && pdata.tree ? pdata.tree : []));
+
+			diff.added.push(odata.cwd)
+			diff.removed.length && self.remove(diff);
+			diff.added.length   && self.add(diff);
+			diff.changed.length && self.change(diff);
+			return dfrd.resolve(diff);
+		});
+		
+		return dfrd;
+	}
+	
+	this.upload = function(files) {
+		return this.transport.upload(files, this);
+	}
+	
+	/**
+	 * Attach listener to events
+	 * To bind to multiply events at once, separate events names by space
+	 * 
+	 * @param  String  event(s) name(s)
+	 * @param  Object  event handler
+	 * @return elFinder
+	 */
+	this.bind = function(event, callback) {
+		var i;
+		
+		if (typeof(callback) == 'function') {
+			event = ('' + event).toLowerCase().split(/\s+/);
+			
+			for (i = 0; i < event.length; i++) {
+				if (listeners[event[i]] === void(0)) {
+					listeners[event[i]] = [];
+				}
+				listeners[event[i]].push(callback);
+			}
+		}
+		return this;
+	};
+	
+	/**
+	 * Remove event listener if exists
+	 *
+	 * @param  String    event name
+	 * @param  Function  callback
+	 * @return elFinder
+	 */
+	this.unbind = function(event, callback) {
+		var l = listeners[('' + event).toLowerCase()] || [],
+			i = l.indexOf(callback);
+
+		i > -1 && l.splice(i, 1);
+		//delete callback; // need this?
+		callback = null
+		return this;
+	};
+	
+	/**
+	 * Fire event - send notification to all event listeners
+	 *
+	 * @param  String   event type
+	 * @param  Object   data to send across event
+	 * @return elFinder
+	 */
+	this.trigger = function(event, data) {
+		var event    = event.toLowerCase(),
+			handlers = listeners[event] || [], i, j;
+		
+		this.debug('event-'+event, data)
+		
+		if (handlers.length) {
+			event = $.Event(event);
+
+			for (i = 0; i < handlers.length; i++) {
+				// to avoid data modifications. remember about "sharing" passing arguments in js :) 
+				event.data = $.extend(true, {}, data);
+
+				try {
+					if (handlers[i](event, this) === false 
+					|| event.isDefaultPrevented()) {
+						this.debug('event-stoped', event.type);
+						break;
+					}
+				} catch (ex) {
+					window.console && window.console.log && window.console.log(ex);
+				}
+				
+			}
+		}
+		return this;
+	}
+	
+	/**
+	 * Bind keybord shortcut to keydown event
+	 *
+	 * @example
+	 *    elfinder.shortcut({ 
+	 *       pattern : 'ctrl+a', 
+	 *       description : 'Select all files', 
+	 *       callback : function(e) { ... }, 
+	 *       keypress : true|false (bind to keypress instead of keydown) 
+	 *    })
+	 *
+	 * @param  Object  shortcut config
+	 * @return elFinder
+	 */
+	this.shortcut = function(s) {
+		var patterns, pattern, code, i, parts;
+		
+		if (this.options.allowShortcuts && s.pattern && $.isFunction(s.callback)) {
+			patterns = s.pattern.toUpperCase().split(/\s+/);
+			
+			for (i= 0; i < patterns.length; i++) {
+				pattern = patterns[i]
+				parts   = pattern.split('+');
+				code    = (code = parts.pop()).length == 1 
+					? code > 0 ? code : code.charCodeAt(0) 
+					: $.ui.keyCode[code];
+
+				if (code && !shortcuts[pattern]) {
+					shortcuts[pattern] = {
+						keyCode     : code,
+						altKey      : $.inArray('ALT', parts)   != -1,
+						ctrlKey     : $.inArray('CTRL', parts)  != -1,
+						shiftKey    : $.inArray('SHIFT', parts) != -1,
+						type        : s.type || 'keydown',
+						callback    : s.callback,
+						description : s.description,
+						pattern     : pattern
+					};
+				}
+			}
+		}
+		return this;
+	}
+	
+	/**
+	 * Registered shortcuts
+	 *
+	 * @type Object
+	 **/
+	this.shortcuts = function() {
+		var ret = [];
+		
+		$.each(shortcuts, function(i, s) {
+			ret.push([s.pattern, self.i18n(s.description)]);
+		});
+		return ret;
+	};
+	
+	/**
+	 * Get/set clipboard content.
+	 * Return new clipboard content.
+	 *
+	 * @example
+	 *   this.clipboard([]) - clean clipboard
+	 *   this.clipboard([{...}, {...}], true) - put 2 files in clipboard and mark it as cutted
+	 * 
+	 * @param  Array    new files hashes
+	 * @param  Boolean  cut files?
+	 * @return Array
+	 */
+	this.clipboard = function(hashes, cut) {
+		var map = function() { return $.map(clipboard, function(f) { return f.hash }); }
+
+		if (hashes !== void(0)) {
+			clipboard.length && this.trigger('unlockfiles', {files : map()});
+			remember = [];
+			
+			clipboard = $.map(hashes||[], function(hash) {
+				var file = files[hash];
+				if (file) {
+					
+					remember.push(hash);
+					
+					return {
+						hash   : hash,
+						phash  : file.phash,
+						name   : file.name,
+						mime   : file.mime,
+						read   : file.read,
+						locked : file.locked,
+						cut    : !!cut
+					}
+				}
+				return null;
+			});
+			this.trigger('changeclipboard', {clipboard : clipboard.slice(0, clipboard.length)});
+			cut && this.trigger('lockfiles', {files : map()});
+		}
+
+		// return copy of clipboard instead of refrence
+		return clipboard.slice(0, clipboard.length);
+	}
+	
+	/**
+	 * Return true if command enabled
+	 * 
+	 * @param  String  command name
+	 * @return Boolean
+	 */
+	this.isCommandEnabled = function(name) {
+		return this._commands[name] ? $.inArray(name, cwdOptions.disabled) === -1 : false;
+	}
+	
+	/**
+	 * Exec command and return result;
+	 *
+	 * @param  String         command name
+	 * @param  String|Array   usualy files hashes
+	 * @param  String|Array   command options
+	 * @return $.Deferred
+	 */		
+	this.exec = function(cmd, files, opts) {
+		return this._commands[cmd] && this.isCommandEnabled(cmd) 
+			? this._commands[cmd].exec(files, opts) 
+			: $.Deferred().reject('No such command');
+	}
+	
+	/**
+	 * Create and return dialog.
+	 *
+	 * @param  String|DOMElement  dialog content
+	 * @param  Object             dialog options
+	 * @return jQuery
+	 */
+	this.dialog = function(content, options) {
+		return $('<div/>').append(content).appendTo(node).elfinderdialog(options);
+	}
+	
+	/**
+	 * Return UI widget or node
+	 *
+	 * @param  String  ui name
+	 * @return jQuery
+	 */
+	this.getUI = function(ui) {
+		return this.ui[ui] || node;
+	}
+	
+	this.command = function(name) {
+		return name === void(0) ? this._commands : this._commands[name];
+	}
+	
+	/**
+	 * Resize elfinder node
+	 * 
+	 * @param  String|Number  width
+	 * @param  Number         height
+	 * @return void
+	 */
+	this.resize = function(w, h) {
+		node.css('width', w).height(h).trigger('resize');
+		this.trigger('resize', {width : node.width(), height : node.height()});
+	}
+	
+	/**
+	 * Restore elfinder node size
+	 * 
+	 * @return elFinder
+	 */
+	this.restoreSize = function() {
+		this.resize(width, height);
+	}
+	
+	this.show = function() {
+		node.show();
+		this.enable().trigger('show');
+	}
+	
+	this.hide = function() {
+		this.disable().trigger('hide');
+		node.hide();
+	}
+	
+	/**
+	 * Destroy this elFinder instance
+	 *
+	 * @return void
+	 **/
+	this.destroy = function() {
+		if (node && node[0].elfinder) {
+			this.trigger('destroy').disable();
+			listeners = {};
+			shortcuts = {};
+			$(document).add(node).unbind('.'+this.namespace);
+			self.trigger = function() { }
+			node.children().remove();
+			node.append(prevContent.contents()).removeClass(this.cssClass).attr('style', prevStyle);
+			node[0].elfinder = null;
+			if (syncInterval) {
+				clearInterval(syncInterval);
+			}
+		}
+	}
+	
+	/*************  init stuffs  ****************/
+	
+	// check jquery ui
+	if (!($.fn.selectable && $.fn.draggable && $.fn.droppable)) {
+		return alert(this.i18n('errJqui'));
+	}
+
+	// check node
+	if (!node.length) {
+		return alert(this.i18n('errNode'));
+	}
+	// check connector url
+	if (!this.options.url) {
+		return alert(this.i18n('errURL'));
+	}
+
+	$.extend($.ui.keyCode, {
+		'F1' : 112,
+		'F2' : 113,
+		'F3' : 114,
+		'F4' : 115,
+		'F5' : 116,
+		'F6' : 117,
+		'F7' : 118,
+		'F8' : 119,
+		'F9' : 120
+	});
+	
+	this.dragUpload = false;
+	this.xhrUpload  = (typeof XMLHttpRequestUpload != 'undefined' || typeof XMLHttpRequestEventTarget != 'undefined') && typeof File != 'undefined' && typeof FormData != 'undefined';
+	
+	// configure transport object
+	this.transport = {}
+
+	if (typeof(this.options.transport) == 'object') {
+		this.transport = this.options.transport;
+		if (typeof(this.transport.init) == 'function') {
+			this.transport.init(this)
+		}
+	}
+	
+	if (typeof(this.transport.send) != 'function') {
+		this.transport.send = function(opts) { return $.ajax(opts); }
+	}
+	
+	if (this.transport.upload == 'iframe') {
+		this.transport.upload = $.proxy(this.uploads.iframe, this);
+	} else if (typeof(this.transport.upload) == 'function') {
+		this.dragUpload = !!this.options.dragUploadAllow;
+	} else if (this.xhrUpload && !!this.options.dragUploadAllow) {
+		this.transport.upload = $.proxy(this.uploads.xhr, this);
+		this.dragUpload = true;
+	} else {
+		this.transport.upload = $.proxy(this.uploads.iframe, this);
+	}
+
+	/**
+	 * Alias for this.trigger('error', {error : 'message'})
+	 *
+	 * @param  String  error message
+	 * @return elFinder
+	 **/
+	this.error = function() {
+		var arg = arguments[0];
+		return arguments.length == 1 && typeof(arg) == 'function'
+			? self.bind('error', arg)
+			: self.trigger('error', {error : arg});
+	}
+	
+	// create bind/trigger aliases for build-in events
+	$.each(['enable', 'disable', 'load', 'open', 'reload', 'select',  'add', 'remove', 'change', 'dblclick', 'getfile', 'lockfiles', 'unlockfiles', 'dragstart', 'dragstop', 'search', 'searchend', 'viewchange'], function(i, name) {
+		self[name] = function() {
+			var arg = arguments[0];
+			return arguments.length == 1 && typeof(arg) == 'function'
+				? self.bind(name, arg)
+				: self.trigger(name, $.isPlainObject(arg) ? arg : {});
+		}
+	});
+	
+	// bind core event handlers
+	this
+		.enable(function() {
+			if (!enabled && self.visible() && self.ui.overlay.is(':hidden')) {
+				enabled = true;
+				$('texarea:focus,input:focus,button').blur();
+				node.removeClass('elfinder-disabled');
+			}
+		})
+		.disable(function() {
+			prevEnabled = enabled;
+			enabled = false;
+			node.addClass('elfinder-disabled');
+		})
+		.open(function() {
+			selected = [];
+		})
+		.select(function(e) {
+			selected = $.map(e.data.selected || e.data.value|| [], function(hash) { return files[hash] ? hash : null; });
+		})
+		.error(function(e) { 
+			var opts  = {
+					cssClass  : 'elfinder-dialog-error',
+					title     : self.i18n(self.i18n('error')),
+					resizable : false,
+					destroyOnClose : true,
+					buttons   : {}
+			};
+
+			opts.buttons[self.i18n(self.i18n('btnClose'))] = function() { $(this).elfinderdialog('close'); };
+
+			self.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-error"/>'+self.i18n(e.data.error), opts);
+		})
+		.bind('tree parents', function(e) {
+			cache(e.data.tree || []);
+		})
+		.bind('tmb', function(e) {
+			$.each(e.data.images||[], function(hash, tmb) {
+				if (files[hash]) {
+					files[hash].tmb = tmb;
+				}
+			})
+		})
+		.add(function(e) {
+			cache(e.data.added||[]);
+		})
+		.change(function(e) {
+			$.each(e.data.changed||[], function(i, file) {
+				var hash = file.hash;
+				if ((files[hash].width && !file.width) || (files[hash].height && !file.height)) {
+					files[hash].width = undefined;
+					files[hash].height = undefined;
+				}
+				files[hash] = files[hash] ? $.extend(files[hash], file) : file;
+			});
+		})
+		.remove(function(e) {
+			var removed = e.data.removed||[],
+				l       = removed.length, 
+				rm      = function(hash) {
+					var file = files[hash];
+					if (file) {
+						if (file.mime == 'directory' && file.dirs) {
+							$.each(files, function(h, f) {
+								f.phash == hash && rm(h);
+							});
+						}
+						delete files[hash];
+					}
+				};
+		
+			while (l--) {
+				rm(removed[l]);
+			}
+			
+		})
+		.bind('search', function(e) {
+			cache(e.data.files);
+		})
+		.bind('rm', function(e) {
+			var play  = beeper.canPlayType && beeper.canPlayType('audio/wav; codecs="1"');
+		
+			play && play != '' && play != 'no' && $(beeper).html('<source src="./sounds/rm.wav" type="audio/wav">')[0].play()
+		})
+		
+		;
+
+	// bind external event handlers
+	$.each(this.options.handlers, function(event, callback) {
+		self.bind(event, callback);
+	});
+
+	/**
+	 * History object. Store visited folders
+	 *
+	 * @type Object
+	 **/
+	this.history = new this.history(this);
+	
+	// in getFileCallback set - change default actions on double click/enter/ctrl+enter
+	if (typeof(this.options.getFileCallback) == 'function' && this.commands.getfile) {
+		this.bind('dblclick', function(e) {
+			e.preventDefault();
+			self.exec('getfile').fail(function() {
+				self.exec('open');
+			});
+		});
+		this.shortcut({
+			pattern     : 'enter',
+			description : this.i18n('cmdgetfile'),
+			callback    : function() { self.exec('getfile').fail(function() { self.exec(self.OS == 'mac' ? 'rename' : 'open') }) }
+		})
+		.shortcut({
+			pattern     : 'ctrl+enter',
+			description : this.i18n(this.OS == 'mac' ? 'cmdrename' : 'cmdopen'),
+			callback    : function() { self.exec(self.OS == 'mac' ? 'rename' : 'open') }
+		});
+		
+	} 
+
+	/**
+	 * Loaded commands
+	 *
+	 * @type Object
+	 **/
+	this._commands = {};
+	
+	if (!$.isArray(this.options.commands)) {
+		this.options.commands = [];
+	}
+	// check required commands
+	$.each(['open', 'reload', 'back', 'forward', 'up', 'home', 'info', 'quicklook', 'getfile', 'help'], function(i, cmd) {
+		$.inArray(cmd, self.options.commands) === -1 && self.options.commands.push(cmd);
+	});
+
+	// load commands
+	$.each(this.options.commands, function(i, name) {
+		var cmd = self.commands[name];
+		if ($.isFunction(cmd) && !self._commands[name]) {
+			cmd.prototype = base;
+			self._commands[name] = new cmd();
+			self._commands[name].setup(name, self.options.commandsOptions[name]||{});
+		}
+	});
+	
+	// prepare node
+	node.addClass(this.cssClass)
+		.bind(mousedown, function() {
+			!enabled && self.enable();
+		});
+	
+	/**
+	 * UI nodes
+	 *
+	 * @type Object
+	 **/
+	this.ui = {
+		// container for nav panel and current folder container
+		workzone : $('<div/>').appendTo(node).elfinderworkzone(this),
+		// container for folders tree / places
+		navbar : $('<div/>').appendTo(node).elfindernavbar(this, this.options.uiOptions.navbar || {}),
+		// contextmenu
+		contextmenu : $('<div/>').appendTo(node).elfindercontextmenu(this),
+		// overlay
+		overlay : $('<div/>').appendTo(node).elfinderoverlay({
+			show : function() { self.disable(); },
+			hide : function() { prevEnabled && self.enable(); }
+		}),
+		// current folder container
+		cwd : $('<div/>').appendTo(node).elfindercwd(this, this.options.uiOptions.cwd || {}),
+		// notification dialog window
+		notify : this.dialog('', {
+			cssClass  : 'elfinder-dialog-notify',
+			position  : {top : '12px', right : '12px'},
+			resizable : false,
+			autoOpen  : false,
+			title     : '&nbsp;',
+			width     : 280
+		}),
+		statusbar : $('<div class="ui-widget-header ui-helper-clearfix ui-corner-bottom elfinder-statusbar"/>').hide().appendTo(node)
+	}
+	
+	// load required ui
+	$.each(this.options.ui || [], function(i, ui) {
+		var name = 'elfinder'+ui,
+			opts = self.options.uiOptions[ui] || {};
+
+		if (!self.ui[ui] && $.fn[name]) {
+			self.ui[ui] = $('<'+(opts.tag || 'div')+'/>').appendTo(node)[name](self, opts);
+		}
+	});
+	
+
+
+	// store instance in node
+	node[0].elfinder = this;
+	
+	// make node resizable
+	this.options.resizable 
+	&& $.fn.resizable 
+	&& node.resizable({
+		handles   : 'se',
+		minWidth  : 300,
+		minHeight : 200
+	});
+
+	if (this.options.width) {
+		width = this.options.width;
+	}
+	
+	if (this.options.height) {
+		height = parseInt(this.options.height);
+	}
+	
+	// update size	
+	self.resize(width, height);
+	
+	// attach events to document
+	$(document)
+		// disable elfinder on click outside elfinder
+		.bind('click.'+this.namespace, function(e) { enabled && !$(e.target).closest(node).length && self.disable(); })
+		// exec shortcuts
+		.bind(keydown+' '+keypress, execShortcut);
+	
+	// send initial request and start to pray >_<
+	this.trigger('init')
+		.request({
+			data        : {cmd : 'open', target : self.lastDir(), init : 1, tree : this.ui.tree ? 1 : 0}, 
+			preventDone : true,
+			notify      : {type : 'open', cnt : 1, hideCnt : true},
+			freeze      : true
+		})
+		.fail(function() {
+			self.trigger('fail').disable().lastDir('');
+			listeners = {};
+			shortcuts = {};
+			$(document).add(node).unbind('.'+this.namespace);
+			self.trigger = function() { };
+		})
+		.done(function(data) {
+			self.load().debug('api', self.api);
+			data = $.extend(true, {}, data);
+			open(data);
+			self.trigger('open', data);
+		});
+	
+	// update ui's size after init
+	this.one('load', function() {
+		node.trigger('resize');
+		if (self.options.sync > 1000) {
+			syncInterval = setInterval(function() {
+				self.sync();
+			}, self.options.sync)
+			
+		}
+
+	});
+
+	// self.timeEnd('load'); 
+
+}
+
+/**
+ * Prototype
+ * 
+ * @type  Object
+ */
+elFinder.prototype = {
+	
+	res : function(type, id) {
+		return this.resources[type] && this.resources[type][id];
+	}, 
+	
+	/**
+	 * Internationalization object
+	 * 
+	 * @type  Object
+	 */
+	i18 : {
+		en : {
+			translator      : '',
+			language        : 'English',
+			direction       : 'ltr',
+			dateFormat      : 'd.m.Y H:i',
+			fancyDateFormat : '$1 H:i',
+			messages        : {}
+		},
+		months : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+		monthsShort : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+
+		days : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+		daysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
+	},
+	
+	/**
+	 * File mimetype to kind mapping
+	 * 
+	 * @type  Object
+	 */
+	kinds : 	{
+			'unknown'                       : 'Unknown',
+			'directory'                     : 'Folder',
+			'symlink'                       : 'Alias',
+			'symlink-broken'                : 'AliasBroken',
+			'application/x-empty'           : 'TextPlain',
+			'application/postscript'        : 'Postscript',
+			'application/vnd.ms-office'     : 'MsOffice',
+			'application/vnd.ms-word'       : 'MsWord',
+			'application/vnd.openxmlformats-officedocument.wordprocessingml.document' : 'MsWord',
+			'application/vnd.ms-word.document.macroEnabled.12'                        : 'MsWord',
+			'application/vnd.openxmlformats-officedocument.wordprocessingml.template' : 'MsWord',
+			'application/vnd.ms-word.template.macroEnabled.12'                        : 'MsWord',
+			'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'       : 'MsWord',
+			'application/vnd.ms-excel'      : 'MsExcel',
+			'application/vnd.ms-excel.sheet.macroEnabled.12'                          : 'MsExcel',
+			'application/vnd.openxmlformats-officedocument.spreadsheetml.template'    : 'MsExcel',
+			'application/vnd.ms-excel.template.macroEnabled.12'                       : 'MsExcel',
+			'application/vnd.ms-excel.sheet.binary.macroEnabled.12'                   : 'MsExcel',
+			'application/vnd.ms-excel.addin.macroEnabled.12'                          : 'MsExcel',
+			'application/vnd.ms-powerpoint' : 'MsPP',
+			'application/vnd.openxmlformats-officedocument.presentationml.presentation' : 'MsPP',
+			'application/vnd.ms-powerpoint.presentation.macroEnabled.12'              : 'MsPP',
+			'application/vnd.openxmlformats-officedocument.presentationml.slideshow'  : 'MsPP',
+			'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'                 : 'MsPP',
+			'application/vnd.openxmlformats-officedocument.presentationml.template'   : 'MsPP',
+			'application/vnd.ms-powerpoint.template.macroEnabled.12'                  : 'MsPP',
+			'application/vnd.ms-powerpoint.addin.macroEnabled.12'                     : 'MsPP',
+			'application/vnd.openxmlformats-officedocument.presentationml.slide'      : 'MsPP',
+			'application/vnd.ms-powerpoint.slide.macroEnabled.12'                     : 'MsPP',
+			'application/pdf'               : 'PDF',
+			'application/xml'               : 'XML',
+			'application/vnd.oasis.opendocument.text' : 'OO',
+			'application/vnd.oasis.opendocument.text-template'         : 'OO',
+			'application/vnd.oasis.opendocument.text-web'              : 'OO',
+			'application/vnd.oasis.opendocument.text-master'           : 'OO',
+			'application/vnd.oasis.opendocument.graphics'              : 'OO',
+			'application/vnd.oasis.opendocument.graphics-template'     : 'OO',
+			'application/vnd.oasis.opendocument.presentation'          : 'OO',
+			'application/vnd.oasis.opendocument.presentation-template' : 'OO',
+			'application/vnd.oasis.opendocument.spreadsheet'           : 'OO',
+			'application/vnd.oasis.opendocument.spreadsheet-template'  : 'OO',
+			'application/vnd.oasis.opendocument.chart'                 : 'OO',
+			'application/vnd.oasis.opendocument.formula'               : 'OO',
+			'application/vnd.oasis.opendocument.database'              : 'OO',
+			'application/vnd.oasis.opendocument.image'                 : 'OO',
+			'application/vnd.openofficeorg.extension'                  : 'OO',
+			'application/x-shockwave-flash' : 'AppFlash',
+			'application/flash-video'       : 'Flash video',
+			'application/x-bittorrent'      : 'Torrent',
+			'application/javascript'        : 'JS',
+			'application/rtf'               : 'RTF',
+			'application/rtfd'              : 'RTF',
+			'application/x-font-ttf'        : 'TTF',
+			'application/x-font-otf'        : 'OTF',
+			'application/x-rpm'             : 'RPM',
+			'application/x-web-config'      : 'TextPlain',
+			'application/xhtml+xml'         : 'HTML',
+			'application/docbook+xml'       : 'DOCBOOK',
+			'application/x-awk'             : 'AWK',
+			'application/x-gzip'            : 'GZIP',
+			'application/x-bzip2'           : 'BZIP',
+			'application/zip'               : 'ZIP',
+			'application/x-zip'               : 'ZIP',
+			'application/x-rar'             : 'RAR',
+			'application/x-tar'             : 'TAR',
+			'application/x-7z-compressed'   : '7z',
+			'application/x-jar'             : 'JAR',
+			'text/plain'                    : 'TextPlain',
+			'text/x-php'                    : 'PHP',
+			'text/html'                     : 'HTML',
+			'text/javascript'               : 'JS',
+			'text/css'                      : 'CSS',
+			'text/rtf'                      : 'RTF',
+			'text/rtfd'                     : 'RTF',
+			'text/x-c'                      : 'C',
+			'text/x-csrc'                   : 'C',
+			'text/x-chdr'                   : 'CHeader',
+			'text/x-c++'                    : 'CPP',
+			'text/x-c++src'                 : 'CPP',
+			'text/x-c++hdr'                 : 'CPPHeader',
+			'text/x-shellscript'            : 'Shell',
+			'application/x-csh'             : 'Shell',
+			'text/x-python'                 : 'Python',
+			'text/x-java'                   : 'Java',
+			'text/x-java-source'            : 'Java',
+			'text/x-ruby'                   : 'Ruby',
+			'text/x-perl'                   : 'Perl',
+			'text/x-sql'                    : 'SQL',
+			'text/xml'                      : 'XML',
+			'text/x-comma-separated-values' : 'CSV',
+			'image/x-ms-bmp'                : 'BMP',
+			'image/jpeg'                    : 'JPEG',
+			'image/gif'                     : 'GIF',
+			'image/png'                     : 'PNG',
+			'image/tiff'                    : 'TIFF',
+			'image/x-targa'                 : 'TGA',
+			'image/vnd.adobe.photoshop'     : 'PSD',
+			'image/xbm'                     : 'XBITMAP',
+			'image/pxm'                     : 'PXM',
+			'audio/mpeg'                    : 'AudioMPEG',
+			'audio/midi'                    : 'AudioMIDI',
+			'audio/ogg'                     : 'AudioOGG',
+			'audio/mp4'                     : 'AudioMPEG4',
+			'audio/x-m4a'                   : 'AudioMPEG4',
+			'audio/wav'                     : 'AudioWAV',
+			'audio/x-mp3-playlist'          : 'AudioPlaylist',
+			'video/x-dv'                    : 'VideoDV',
+			'video/mp4'                     : 'VideoMPEG4',
+			'video/mpeg'                    : 'VideoMPEG',
+			'video/x-msvideo'               : 'VideoAVI',
+			'video/quicktime'               : 'VideoMOV',
+			'video/x-ms-wmv'                : 'VideoWM',
+			'video/x-flv'                   : 'VideoFlash',
+			'video/x-matroska'              : 'VideoMKV',
+			'video/ogg'                     : 'VideoOGG'
+		},
+	
+	/**
+	 * Ajax request data validation rules
+	 * 
+	 * @type  Object
+	 */
+	rules : {
+		defaults : function(data) {
+			if (!data
+			|| (data.added && !$.isArray(data.added))
+			||  (data.removed && !$.isArray(data.removed))
+			||  (data.changed && !$.isArray(data.changed))) {
+				return false;
+			}
+			return true;
+		},
+		open    : function(data) { return data && data.cwd && data.files && $.isPlainObject(data.cwd) && $.isArray(data.files); },
+		tree    : function(data) { return data && data.tree && $.isArray(data.tree); },
+		parents : function(data) { return data && data.tree && $.isArray(data.tree); },
+		tmb     : function(data) { return data && data.images && ($.isPlainObject(data.images) || $.isArray(data.images)); },
+		upload  : function(data) { return data && ($.isPlainObject(data.added) || $.isArray(data.added));},
+		search  : function(data) { return data && data.files && $.isArray(data.files)}
+	},
+
+	
+
+	
+	/**
+	 * Commands costructors
+	 *
+	 * @type Object
+	 */
+	commands : {},
+	
+	parseUploadData : function(text) {
+		var data;
+		
+		if (!$.trim(text)) {
+			return {error : ['errResponse', 'errDataEmpty']};
+		}
+		
+		try {
+			data = $.parseJSON(text);
+		} catch (e) {
+			return {error : ['errResponse', 'errDataNotJSON']}
+		}
+		
+		if (!this.validResponse('upload', data)) {
+			return {error : ['errResponse']};
+		}
+		data = this.normalize(data);
+		data.removed = $.map(data.added||[], function(f) { return f.hash; })
+		return data;
+		
+	},
+	
+	iframeCnt : 0,
+	
+	uploads : {
+		// check droped contents
+		checkFile : function(data, fm) {
+			if (!!data.checked || data.type == 'files') {
+				return data.files;
+			} else if (data.type == 'data') {
+				var dfrd = $.Deferred(),
+				files = [],
+				paths = [],
+				dirctorys = [],
+				entries = [],
+				processing = 0,
+				
+				readEntries = function(dirReader) {
+					var toArray = function(list) {
+						return Array.prototype.slice.call(list || []);
+					};
+					var readFile = function(fileEntry, callback) {
+						var dfrd = $.Deferred();
+						if (typeof fileEntry == 'undefined') {
+							dfrd.reject('empty');
+						} else if (fileEntry.isFile) {
+							fileEntry.file(function (file) {
+								dfrd.resolve(file);
+							}, function(e){
+								dfrd.reject();
+							});
+						} else {
+							dfrd.reject('dirctory');
+						}
+						return dfrd.promise();
+					};
+			
+					dirReader.readEntries(function (results) {
+						if (!results.length) {
+							var len = entries.length - 1;
+							var read = function(i) {
+								readFile(entries[i]).done(function(file){
+									if (! (fm.OS == 'win' && file.name.match(/^(?:desktop\.ini|thumbs\.db)$/i))
+											&&
+										! (fm.OS == 'mac' && file.name.match(/^\.ds_store$/i))) {
+										paths.push(entries[i].fullPath);
+										files.push(file);
+									}
+								}).fail(function(e){
+									if (e == 'dirctory') {
+										// dirctory
+										dirctorys.push(entries[i]);
+									} else if (e == 'empty') {
+										// dirctory is empty
+									} else {
+										// why fail?
+									}
+								}).always(function(){
+									processing--;
+									if (i < len) {
+										processing++;
+										read(++i);
+									}
+								});
+							};
+							processing++;
+							read(0);
+							processing--;
+						} else {
+							entries = entries.concat(toArray(results));
+							readEntries(dirReader);
+						}
+					});
+				},
+				
+				doScan = function(items, isEntry) {
+					var dirReader, entry;
+					entries = [];
+					var length = items.length;
+					for (var i = 0; i < length; i++) {
+						if (! isEntry) {
+							entry = !!items[i].getAsEntry? items[i].getAsEntry() : items[i].webkitGetAsEntry();
+						} else {
+							entry = items[i];
+						}
+						if (entry) {
+							if (entry.isFile) {
+								paths.push('');
+								files.push(data.files.items[i].getAsFile());
+							} else if (entry.isDirectory) {
+								if (processing > 0) {
+									dirctorys.push(entry);
+								} else {
+									processing = 0;
+									dirReader = entry.createReader();
+									processing++;
+									readEntries(dirReader);
+								}
+							}
+						}
+					}
+				};
+				
+				doScan(data.files.items);
+				
+				setTimeout(function wait() {
+					if (processing > 0) {
+						setTimeout(wait, 10);
+					} else {
+						if (dirctorys.length > 0) {
+							doScan([dirctorys.shift()], true);
+							setTimeout(wait, 10);
+						} else {
+							dfrd.resolve([files, paths]);
+						}
+					}
+				}, 10);
+				
+				return dfrd.promise();
+			} else {
+				var ret = [];
+				var regex;
+				var str = data.files[0];
+				if (data.type == 'html') {
+					regex = /<img[^>]+src=["']?([^"'> ]+)/ig;
+					var m = [];
+					var url = '';
+					var links;
+					while (m = regex.exec(str)) {
+						url = m[1].replace(/&amp;/g, '&');
+						if (url.match(/^http|data:/) && $.inArray(url, ret) == -1) ret.push(url);
+					}
+					links = str.match(/<\/a>/i);
+					if (links && links.length == 1) {
+						regex = /<a[^>]+href=["']?([^"'> ]+)((?:.|\s)+)<\/a>/i;
+						if (m = regex.exec(str)) {
+							if (! m[2].match(/<img/i)) {
+								url = m[1].replace(/&amp;/g, '&');
+								if (url.match(/^http/) && $.inArray(url, ret) == -1) ret.push(url);
+							}
+						}
+					}
+				} else {
+					regex = /(http[^<>"{}|\\^\[\]`\s]+)/ig;
+					while (m = regex.exec(str)) {
+						url = m[1].replace(/&amp;/g, '&');
+						if ($.inArray(url, ret) == -1) ret.push(url);
+					}
+				}
+				return ret;
+			}
+		},
+		// upload transport using iframe
+		iframe : function(data, fm) { 
+			var self   = fm ? fm : this,
+				input  = data.input? data.input : false,
+				files  = !input ? self.uploads.checkFile(data, self) : false,
+				dfrd   = $.Deferred()
+					.fail(function(error) {
+						error && self.error(error);
+					})
+					.done(function(data) {
+						data.warning && self.error(data.warning);
+						data.removed && self.remove(data);
+						data.added   && self.add(data);
+						data.changed && self.change(data);
+						self.trigger('upload', data);
+						data.sync && self.sync();
+					}),
+				name = 'iframe-'+self.namespace+(++self.iframeCnt),
+				form = $('<form action="'+self.uploadURL+'" method="post" enctype="multipart/form-data" encoding="multipart/form-data" target="'+name+'" style="display:none"><input type="hidden" name="cmd" value="upload" /></form>'),
+				msie = this.UA.IE,
+				// clear timeouts, close notification dialog, remove form/iframe
+				onload = function() {
+					abortto  && clearTimeout(abortto);
+					notifyto && clearTimeout(notifyto);
+					notify   && self.notify({type : 'upload', cnt : -cnt});
+					
+					setTimeout(function() {
+						msie && $('<iframe src="javascript:false;"/>').appendTo(form);
+						form.remove();
+						iframe.remove();
+					}, 100);
+				},
+				iframe = $('<iframe src="'+(msie ? 'javascript:false;' : 'about:blank')+'" name="'+name+'" style="position:absolute;left:-1000px;top:-1000px" />')
+					.bind('load', function() {
+						iframe.unbind('load')
+							.bind('load', function() {
+								var data = self.parseUploadData(iframe.contents().text());
+								
+								onload();
+								data.error ? dfrd.reject(data.error) : dfrd.resolve(data);
+							});
+							
+							// notify dialog
+							notifyto = setTimeout(function() {
+								notify = true;
+								self.notify({type : 'upload', cnt : cnt});
+							}, self.options.notifyDelay);
+							
+							// emulate abort on timeout
+							if (self.options.iframeTimeout > 0) {
+								abortto = setTimeout(function() {
+									onload();
+									dfrd.reject([errors.connect, errors.timeout]);
+								}, self.options.iframeTimeout);
+							}
+							
+							form.submit();
+					}),
+				cnt, notify, notifyto, abortto
+				
+				;
+
+			if (files && files.length) {
+				$.each(files, function(i, val) {
+					form.append('<input type="hidden" name="upload[]" value="'+val+'"/>');
+				});
+				cnt = 1;
+			} else if (input && $(input).is(':file') && $(input).val()) {
+				form.append(input);
+				cnt = input.files ? input.files.length : 1;
+			} else {
+				return dfrd.reject();
+			}
+			
+			form.append('<input type="hidden" name="'+(self.newAPI ? 'target' : 'current')+'" value="'+self.cwd().hash+'"/>')
+				.append('<input type="hidden" name="html" value="1"/>')
+				.append($(input).attr('name', 'upload[]'));
+			
+			$.each(self.options.onlyMimes||[], function(i, mime) {
+				form.append('<input type="hidden" name="mimes[]" value="'+mime+'"/>');
+			});
+			
+			$.each(self.options.customData, function(key, val) {
+				form.append('<input type="hidden" name="'+key+'" value="'+val+'"/>');
+			});
+			
+			form.appendTo('body');
+			iframe.appendTo('body');
+			
+			return dfrd;
+		},
+		// upload transport using XMLHttpRequest
+		xhr : function(data, fm) { 
+			var self   = fm ? fm : this,
+				dfrd   = $.Deferred()
+					.fail(function(error) {
+						error && self.error(error);
+					})
+					.done(function(data) {
+						data.warning && self.error(data.warning);
+						data.removed && self.remove(data);
+						data.added   && self.add(data);
+						data.changed && self.change(data);
+	 					self.trigger('upload', data);
+						data.sync && self.sync();
+					})
+					.always(function() {
+						notifyto && clearTimeout(notifyto);
+						! data.checked && notify && self.notify({type : 'upload', cnt : -cnt, progress : 100*cnt});
+					}),
+				xhr         = new XMLHttpRequest(),
+				formData    = new FormData(),
+				isDataType  = (data.type == 'data'),
+				files       = data.input ? data.input.files : self.uploads.checkFile(data, self), 
+				cnt         = data.checked? (isDataType? files[0].length : files.length) : files.length,
+				loaded      = 5,
+				notify      = false,
+				startNotify = function() {
+					return setTimeout(function() {
+						notify = true;
+						self.notify({type : 'upload', cnt : cnt, progress : loaded*cnt});
+					}, self.options.notifyDelay);
+				},
+				notifyto, notifyto2;
+			
+			if (!isDataType && !cnt) {
+				return dfrd.reject();
+			}
+			
+			xhr.addEventListener('error', function() {
+				dfrd.reject('errConnect');
+			}, false);
+			
+			xhr.addEventListener('abort', function() {
+				dfrd.reject(['errConnect', 'errAbort']);
+			}, false);
+			
+			xhr.addEventListener('load', function() {
+				var status = xhr.status, data;
+				
+				if (status > 500) {
+					return dfrd.reject('errResponse');
+				}
+				if (status != 200) {
+					return dfrd.reject('errConnect');
+				}
+				if (xhr.readyState != 4) {
+					return dfrd.reject(['errConnect', 'errTimeout']); // am i right?
+				}
+				if (!xhr.responseText) {
+					return dfrd.reject(['errResponse', 'errDataEmpty']);
+				}
+
+				data = self.parseUploadData(xhr.responseText);
+				data.error ? dfrd.reject(data.error) : dfrd.resolve(data);
+			}, false);
+			
+			xhr.upload.addEventListener('progress', function(e) {
+				var prev = loaded, curr;
+
+				if (e.lengthComputable) {
+					
+					curr = parseInt(e.loaded*100 / e.total);
+
+					// to avoid strange bug in safari (not in chrome) with drag&drop.
+					// bug: macos finder opened in any folder,
+					// reset safari cache (option+command+e), reload elfinder page,
+					// drop file from finder
+					// on first attempt request starts (progress callback called ones) but never ends.
+					// any next drop - successfull.
+					if (!data.checked && curr > 0 && !notifyto) {
+						notifyto = startNotify();
+					}
+					
+					if (curr - prev > 4) {
+						loaded = curr;
+						(data.checked || notify) && self.notify({type : 'upload', cnt : 0, progress : (loaded - prev)*cnt});
+					}
+				}
+			}, false);
+			
+			var send = function(files, paths){
+				var size = 0, fcnt = 1, sfiles = [], c = 0, total = cnt, maxFileSize;
+				if (! data.checked) {
+					maxFileSize = fm.option('uploadMaxSize')? fm.option('uploadMaxSize') : fm.uplMaxSize;
+					for (var i=0; i < files.length; i++) {
+						if (maxFileSize && files[i].size >= maxFileSize) {
+							self.error(self.i18n('errUploadFile', files[i].name) + ' ' + self.i18n('errUploadFileSize'));
+							continue;
+						}
+						if ((fm.uplMaxSize && size + files[i].size >= fm.uplMaxSize) || fcnt > fm.uplMaxFile) {
+							size = 0;
+							fcnt = 1;
+							c++;
+						}
+						if (typeof sfiles[c] == 'undefined') {
+							sfiles[c] = [];
+							if (isDataType) {
+								sfiles[c][0] = [];
+								sfiles[c][1] = [];
+							}
+						}
+						if (isDataType) {
+							sfiles[c][0].push(files[i]);
+							sfiles[c][1].push(paths[i]);
+						} else {
+							sfiles[c].push(files[i]);
+						}
+						size += files[i].size;
+						fcnt++;
+					}
+					
+					if (sfiles.length == 0) {
+						data.checked = true;
+						return false;
+					}
+					
+					if (sfiles.length > 1) {
+						notifyto = startNotify();
+						for (var i=0; i < sfiles.length; i++) {
+							fm.exec('upload', {type: data.type, files: sfiles[i], checked: true}).always(function() {
+								if (notify) {
+									var _cnt = (isDataType? this[0] : this).length;
+									total -= _cnt;
+									if (total < 1) {
+										notifyto && clearTimeout(notifyto);
+										self.notify({type : 'upload', cnt : -cnt, progress : 100 * cnt});
+									}
+								}
+							}.bind(sfiles[i]));
+						}
+						return false;
+					}
+					
+					if (isDataType) {
+						files = sfiles[0][0];
+						paths = sfiles[0][1];
+					} else {
+						files = sfiles[0];
+					}
+				}
+				
+				xhr.open('POST', self.uploadURL, true);
+				formData.append('cmd', 'upload');
+				formData.append(self.newAPI ? 'target' : 'current', self.cwd().hash);
+				$.each(self.options.customData, function(key, val) {
+					formData.append(key, val);
+				});
+				$.each(self.options.onlyMimes, function(i, mime) {
+					formData.append('mimes['+i+']', mime);
+				});
+				
+				$.each(files, function(i, file) {
+					formData.append('upload[]', file);
+				});
+				
+				if (isDataType) {
+					$.each(paths, function(i, path) {
+						formData.append('upload_path[]', path);
+					});
+				}
+				
+				xhr.onreadystatechange = function() {
+					if (xhr.readyState == 4 && xhr.status == 0) {
+						// ff bug while send zero sized file
+						// for safari - send directory
+						dfrd.reject(['errConnect', 'errAbort']);
+					}
+				}
+				
+				xhr.send(formData);
+				
+				return true;
+			};
+			
+			if (! isDataType) {
+				if (! send(files)) {
+					dfrd.reject();
+				}
+			} else {
+				if (!! data.checked) {
+					send(files[0], files[1]);
+				} else {
+					notifyto2 = setTimeout(function() {
+						self.notify({type : 'readdir', cnt : 1, hideCnt: true});
+					}, self.options.notifyDelay);
+					files.done(function(result){
+						notifyto2 && clearTimeout(notifyto2);
+						self.notify({type : 'readdir', cnt : -1});
+						cnt = result[0].length;
+						send(result[0], result[1]);
+					}).fail(function(){
+						dfrd.reject();
+					});
+				}
+			}
+
+			if (!isDataType && !data.checked && (!this.UA.Safari || !data.files)) {
+				notifyto = startNotify();
+			}
+			
+			return dfrd;
+		}
+	},
+	
+	
+	/**
+	 * Bind callback to event(s) The callback is executed at most once per event.
+	 * To bind to multiply events at once, separate events names by space
+	 *
+	 * @param  String    event name
+	 * @param  Function  callback
+	 * @return elFinder
+	 */
+	one : function(event, callback) {
+		var self = this,
+			h    = $.proxy(callback, function(event) {
+				setTimeout(function() {self.unbind(event.type, h);}, 3);
+				return callback.apply(this, arguments);
+			});
+		return this.bind(event, h);
+	},
+	
+	/**
+	 * Set/get data into/from localStorage
+	 *
+	 * @param  String       key
+	 * @param  String|void  value
+	 * @return String
+	 */
+	localStorage : function(key, val) {
+		var s = window.localStorage;
+
+		key = 'elfinder-'+key+this.id;
+		
+		if (val === null) {
+			console.log('remove', key)
+			return s.removeItem(key);
+		}
+		
+		if (val !== void(0)) {
+			try {
+				s.setItem(key, val);
+			} catch (e) {
+				s.clear();
+				s.setItem(key, val);
+			}
+		}
+
+		return s.getItem(key);
+	},
+	
+	/**
+	 * Get/set cookie
+	 *
+	 * @param  String       cookie name
+	 * @param  String|void  cookie value
+	 * @return String
+	 */
+	cookie : function(name, value) {
+		var d, o, c, i;
+
+		name = 'elfinder-'+name+this.id;
+
+		if (value === void(0)) {
+			if (document.cookie && document.cookie != '') {
+				c = document.cookie.split(';');
+				name += '=';
+				for (i=0; i<c.length; i++) {
+					c[i] = $.trim(c[i]);
+					if (c[i].substring(0, name.length) == name) {
+						return decodeURIComponent(c[i].substring(name.length));
+					}
+				}
+			}
+			return '';
+		}
+
+		o = $.extend({}, this.options.cookie);
+		if (value === null) {
+			value = '';
+			o.expires = -1;
+		}
+		if (typeof(o.expires) == 'number') {
+			d = new Date();
+			d.setTime(d.getTime()+(o.expires * 86400000));
+			o.expires = d;
+		}
+		document.cookie = name+'='+encodeURIComponent(value)+'; expires='+o.expires.toUTCString()+(o.path ? '; path='+o.path : '')+(o.domain ? '; domain='+o.domain : '')+(o.secure ? '; secure' : '');
+		return value;
+	},
+	
+	/**
+	 * Get/set last opened directory
+	 * 
+	 * @param  String|undefined  dir hash
+	 * @return String
+	 */
+	lastDir : function(hash) { 
+		return this.options.rememberLastDir ? this.storage('lastdir', hash) : '';
+	},
+	
+	/**
+	 * Node for escape html entities in texts
+	 * 
+	 * @type jQuery
+	 */
+	_node : $('<span/>'),
+	
+	/**
+	 * Replace not html-safe symbols to html entities
+	 * 
+	 * @param  String  text to escape
+	 * @return String
+	 */
+	escape : function(name) {
+		return this._node.text(name).html();
+	},
+	
+	/**
+	 * Cleanup ajax data.
+	 * For old api convert data into new api format
+	 * 
+	 * @param  String  command name
+	 * @param  Object  data from backend
+	 * @return Object
+	 */
+	normalize : function(data) {
+		var filter = function(file) { 
+		
+			if (file && file.hash && file.name && file.mime) {
+				if (file.mime == 'application/x-empty') {
+					file.mime = 'text/plain';
+				}
+				return file;
+			}
+			return null;
+			return file && file.hash && file.name && file.mime ? file : null; 
+		};
+		
+
+		if (data.files) {
+			data.files = $.map(data.files, filter);
+		} 
+		if (data.tree) {
+			data.tree = $.map(data.tree, filter);
+		}
+		if (data.added) {
+			data.added = $.map(data.added, filter);
+		}
+		if (data.changed) {
+			data.changed = $.map(data.changed, filter);
+		}
+		if (data.api) {
+			data.init = true;
+		}
+		return data;
+	},
+	
+	/**
+	 * Update sort options
+	 *
+	 * @param {String} sort type
+	 * @param {String} sort order
+	 * @param {Boolean} show folder first
+	 */
+	setSort : function(type, order, stickFolders) {
+		this.storage('sortType', (this.sortType = this.sortRules[type] ? type : 'name'));
+		this.storage('sortOrder', (this.sortOrder = /asc|desc/.test(order) ? order : 'asc'));
+		this.storage('sortStickFolders', (this.sortStickFolders = !!stickFolders) ? 1 : '');
+		this.trigger('sortchange');
+	},
+	
+	_sortRules : {
+		name : function(file1, file2) { return file1.name.toLowerCase().localeCompare(file2.name.toLowerCase()); },
+		size : function(file1, file2) { 
+			var size1 = parseInt(file1.size) || 0,
+				size2 = parseInt(file2.size) || 0;
+				
+			return size1 == size2 ? 0 : size1 > size2 ? 1 : -1;
+			return (parseInt(file1.size) || 0) > (parseInt(file2.size) || 0) ? 1 : -1; },
+		kind : function(file1, file2) { return file1.mime.localeCompare(file2.mime); },
+		date : function(file1, file2) { 
+			var date1 = file1.ts || file1.date,
+				date2 = file2.ts || file2.date;
+
+			return date1 == date2 ? 0 : date1 > date2 ? 1 : -1
+		}
+	},
+	
+	/**
+	 * Compare files based on elFinder.sort
+	 *
+	 * @param  Object  file
+	 * @param  Object  file
+	 * @return Number
+	 */
+	compare : function(file1, file2) {
+		var self  = this,
+			type  = self.sortType,
+			asc   = self.sortOrder == 'asc',
+			stick = self.sortStickFolders,
+			rules = self.sortRules,
+			sort  = rules[type],
+			d1    = file1.mime == 'directory',
+			d2    = file2.mime == 'directory',
+			res;
+			
+		if (stick) {
+			if (d1 && !d2) {
+				return -1;
+			} else if (!d1 && d2) {
+				return 1;
+			}
+		}
+		
+		res = asc ? sort(file1, file2) : sort(file2, file1);
+		
+		return type != 'name' && res == 0
+			? res = asc ? rules.name(file1, file2) : rules.name(file2, file1)
+			: res;
+	},
+	
+	/**
+	 * Sort files based on config
+	 *
+	 * @param  Array  files
+	 * @return Array
+	 */
+	sortFiles : function(files) {
+		return files.sort(this.compare);
+	},
+	
+	/**
+	 * Open notification dialog 
+	 * and append/update message for required notification type.
+	 *
+	 * @param  Object  options
+	 * @example  
+	 * this.notify({
+	 *    type : 'copy',
+	 *    msg : 'Copy files', // not required for known types @see this.notifyType
+	 *    cnt : 3,
+	 *    hideCnt : false, // true for not show count
+	 *    progress : 10 // progress bar percents (use cnt : 0 to update progress bar)
+	 * })
+	 * @return elFinder
+	 */
+	notify : function(opts) {
+		var type     = opts.type,
+			msg      = this.messages['ntf'+type] ? this.i18n('ntf'+type) : this.i18n('ntfsmth'),
+			ndialog  = this.ui.notify,
+			notify   = ndialog.children('.elfinder-notify-'+type),
+			ntpl     = '<div class="elfinder-notify elfinder-notify-{type}"><span class="elfinder-dialog-icon elfinder-dialog-icon-{type}"/><span class="elfinder-notify-msg">{msg}</span> <span class="elfinder-notify-cnt"/><div class="elfinder-notify-progressbar"><div class="elfinder-notify-progress"/></div></div>',
+			delta    = opts.cnt,
+			progress = opts.progress >= 0 ? opts.progress : 0,
+			cnt, total, prc;
+
+		if (!type) {
+			return this;
+		}
+		
+		if (!notify.length) {
+			notify = $(ntpl.replace(/\{type\}/g, type).replace(/\{msg\}/g, msg))
+				.appendTo(ndialog)
+				.data('cnt', 0);
+
+			if (progress) {
+				notify.data({progress : 0, total : 0});
+			}
+		}
+
+		cnt = delta + parseInt(notify.data('cnt'));
+		
+		if (cnt > 0) {
+			!opts.hideCnt && notify.children('.elfinder-notify-cnt').text('('+cnt+')');
+			ndialog.is(':hidden') && ndialog.elfinderdialog('open');
+			notify.data('cnt', cnt);
+			
+			if (progress
+			&& (total = notify.data('total')) >= 0
+			&& (prc = notify.data('progress')) >= 0) {
+
+				total    = delta + parseInt(notify.data('total'));
+				prc      = progress + prc;
+				progress = parseInt(prc/total);
+				notify.data({progress : prc, total : total});
+				
+				ndialog.find('.elfinder-notify-progress')
+					.animate({
+						width : (progress < 100 ? progress : 100)+'%'
+					}, 20);
+			}
+			
+		} else {
+			notify.remove();
+			!ndialog.children().length && ndialog.elfinderdialog('close');
+		}
+		
+		return this;
+	},
+	
+	/**
+	 * Open confirmation dialog 
+	 *
+	 * @param  Object  options
+	 * @example  
+	 * this.confirm({
+	 *    title : 'Remove files',
+	 *    text  : 'Here is question text',
+	 *    accept : {  // accept callback - required
+	 *      label : 'Continue',
+	 *      callback : function(applyToAll) { fm.log('Ok') }
+	 *    },
+	 *    cancel : { // cancel callback - required
+	 *      label : 'Cancel',
+	 *      callback : function() { fm.log('Cancel')}
+	 *    },
+	 *    reject : { // reject callback - optionally
+	 *      label : 'No',
+	 *      callback : function(applyToAll) { fm.log('No')}
+	 *   },
+	 *   all : true  // display checkbox "Apply to all"
+	 * })
+	 * @return elFinder
+	 */
+	confirm : function(opts) {
+		var complete = false,
+			options = {
+				cssClass  : 'elfinder-dialog-confirm',
+				modal     : true,
+				resizable : false,
+				title     : this.i18n(opts.title || 'confirmReq'),
+				buttons   : {},
+				close     : function() { 
+					!complete && opts.cancel.callback();
+					$(this).elfinderdialog('destroy');
+				}
+			},
+			apply = this.i18n('apllyAll'),
+			label, checkbox;
+
+		
+		if (opts.reject) {
+			options.buttons[this.i18n(opts.reject.label)] = function() {
+				opts.reject.callback(!!(checkbox && checkbox.prop('checked')))
+				complete = true;
+				$(this).elfinderdialog('close')
+			};
+		}
+		
+		options.buttons[this.i18n(opts.accept.label)] = function() {
+			opts.accept.callback(!!(checkbox && checkbox.prop('checked')))
+			complete = true;
+			$(this).elfinderdialog('close')
+		};
+		
+		options.buttons[this.i18n(opts.cancel.label)] = function() {
+			$(this).elfinderdialog('close')
+		};
+		
+		if (opts.all) {
+			if (opts.reject) {
+				options.width = 370;
+			}
+			options.create = function() {
+				checkbox = $('<input type="checkbox" />');
+				$(this).next().children().before($('<label>'+apply+'</label>').prepend(checkbox));
+			}
+			
+			options.open = function() {
+				var pane = $(this).next(),
+					width = parseInt(pane.children(':first').outerWidth() + pane.children(':last').outerWidth());
+
+				if (width > parseInt(pane.width())) {
+					$(this).closest('.elfinder-dialog').width(width+30);
+				}
+			}
+		}
+		
+		return this.dialog('<span class="elfinder-dialog-icon elfinder-dialog-icon-confirm"/>' + this.i18n(opts.text), options);
+	},
+	
+	/**
+	 * Create unique file name in required dir
+	 * 
+	 * @param  String  file name
+	 * @param  String  parent dir hash
+	 * @return String
+	 */
+	uniqueName : function(prefix, phash) {
+		var i = 0, ext = '', p, name;
+		
+		prefix = this.i18n(prefix); 
+		phash = phash || this.cwd().hash;
+
+		if ((p = prefix.indexOf('.txt')) != -1) {
+			ext    = '.txt';
+			prefix = prefix.substr(0, p);
+		}
+		
+		name   = prefix+ext;
+		
+		if (!this.fileByName(name, phash)) {
+			return name;
+		}
+		while (i < 10000) {
+			name = prefix + ' ' + (++i) + ext;
+			if (!this.fileByName(name, phash)) {
+				return name;
+			}
+		}
+		return prefix + Math.random() + ext;
+	},
+	
+	/**
+	 * Return message translated onto current language
+	 *
+	 * @param  String|Array  message[s]
+	 * @return String
+	 **/
+	i18n : function() {
+		var self = this,
+			messages = this.messages, 
+			input    = [],
+			ignore   = [], 
+			message = function(m) {
+				var file;
+				if (m.indexOf('#') === 0) {
+					if ((file = self.file(m.substr(1)))) {
+						return file.name;
+					}
+				}
+				return m;
+			},
+			i, j, m;
+			
+		for (i = 0; i< arguments.length; i++) {
+			m = arguments[i];
+			
+			if (typeof m == 'string') {
+				input.push(message(m));
+			} else if ($.isArray(m)) {
+				for (j = 0; j < m.length; j++) {
+					if (typeof m[j] == 'string') {
+						input.push(message(m[j]));
+					}
+				}
+			}
+		}
+		
+		for (i = 0; i < input.length; i++) {
+			// dont translate placeholders
+			if ($.inArray(i, ignore) !== -1) {
+				continue;
+			}
+			m = input[i];
+			// translate message
+			m = messages[m] || m;
+			// replace placeholders in message
+			m = m.replace(/\$(\d+)/g, function(match, placeholder) {
+				placeholder = i + parseInt(placeholder);
+				if (placeholder > 0 && input[placeholder]) {
+					ignore.push(placeholder)
+				}
+				return input[placeholder] || '';
+			});
+
+			input[i] = m;
+		}
+
+		return $.map(input, function(m, i) { return $.inArray(i, ignore) === -1 ? m : null; }).join('<br>');
+	},
+	
+	/**
+	 * Convert mimetype into css classes
+	 * 
+	 * @param  String  file mimetype
+	 * @return String
+	 */
+	mime2class : function(mime) {
+		var prefix = 'elfinder-cwd-icon-';
+		
+		mime = mime.split('/');
+		
+		return prefix+mime[0]+(mime[0] != 'image' && mime[1] ? ' '+prefix+mime[1].replace(/(\.|\+)/g, '-') : '');
+	},
+	
+	/**
+	 * Return localized kind of file
+	 * 
+	 * @param  Object|String  file or file mimetype
+	 * @return String
+	 */
+	mime2kind : function(f) {
+		var mime = typeof(f) == 'object' ? f.mime : f, kind;
+		
+		if (f.alias) {
+			kind = 'Alias';
+		} else if (this.kinds[mime]) {
+			kind = this.kinds[mime];
+		} else {
+			if (mime.indexOf('text') === 0) {
+				kind = 'Text';
+			} else if (mime.indexOf('image') === 0) {
+				kind = 'Image';
+			} else if (mime.indexOf('audio') === 0) {
+				kind = 'Audio';
+			} else if (mime.indexOf('video') === 0) {
+				kind = 'Video';
+			} else if (mime.indexOf('application') === 0) {
+				kind = 'App';
+			} else {
+				kind = mime;
+			}
+		}
+		
+		return this.messages['kind'+kind] ? this.i18n('kind'+kind) : mime;
+		
+		var mime = typeof(f) == 'object' ? f.mime : f,
+			kind = this.kinds[mime]||'unknown';
+
+		if (f.alias) {
+			kind = 'Alias';
+		} else if (kind == 'unknown') {
+			if (mime.indexOf('text') === 0) {
+				kind = 'Text';
+			} else if (mime.indexOf('image') === 0) {
+				kind = 'Image';
+			} else if (mime.indexOf('audio') === 0) {
+				kind = 'Audio';
+			} else if (mime.indexOf('video') === 0) {
+				kind = 'Video';
+			} else if (mime.indexOf('application') === 0) {
+				kind = 'Application';
+			}
+		}
+		
+		return this.i18n(kind);
+	},
+	
+	/**
+	 * Return localized date
+	 * 
+	 * @param  Object  file object
+	 * @return String
+	 */
+	formatDate : function(file, ts) {
+		var self = this, 
+			ts   = ts || file.ts, 
+			i18  = self.i18,
+			date, format, output, d, dw, m, y, h, g, i, s;
+
+		if (self.options.clientFormatDate && ts > 0) {
+
+			date = new Date(ts*1000);
+			
+			h  = date[self.getHours]();
+			g  = h > 12 ? h - 12 : h;
+			i  = date[self.getMinutes]();
+			s  = date[self.getSeconds]();
+			d  = date[self.getDate]();
+			dw = date[self.getDay]();
+			m  = date[self.getMonth]() + 1;
+			y  = date[self.getFullYear]();
+			
+			format = ts >= this.yesterday 
+				? this.fancyFormat 
+				: this.dateFormat;
+
+			output = format.replace(/[a-z]/gi, function(val) {
+				switch (val) {
+					case 'd': return d > 9 ? d : '0'+d;
+					case 'j': return d;
+					case 'D': return self.i18n(i18.daysShort[dw]);
+					case 'l': return self.i18n(i18.days[dw]);
+					case 'm': return m > 9 ? m : '0'+m;
+					case 'n': return m;
+					case 'M': return self.i18n(i18.monthsShort[m-1]);
+					case 'F': return self.i18n(i18.months[m-1]);
+					case 'Y': return y;
+					case 'y': return (''+y).substr(2);
+					case 'H': return h > 9 ? h : '0'+h;
+					case 'G': return h;
+					case 'g': return g;
+					case 'h': return g > 9 ? g : '0'+g;
+					case 'a': return h > 12 ? 'pm' : 'am';
+					case 'A': return h > 12 ? 'PM' : 'AM';
+					case 'i': return i > 9 ? i : '0'+i;
+					case 's': return s > 9 ? s : '0'+s;
+				}
+				return val;
+			});
+			
+			return ts >= this.yesterday
+				? output.replace('$1', this.i18n(ts >= this.today ? 'Today' : 'Yesterday'))
+				: output;
+		} else if (file.date) {
+			return file.date.replace(/([a-z]+)\s/i, function(a1, a2) { return self.i18n(a2)+' '; });
+		}
+		
+		return self.i18n('dateUnknown');
+	},
+	
+	/**
+	 * Return css class marks file permissions
+	 * 
+	 * @param  Object  file 
+	 * @return String
+	 */
+	perms2class : function(o) {
+		var c = '';
+		
+		if (!o.read && !o.write) {
+			c = 'elfinder-na';
+		} else if (!o.read) {
+			c = 'elfinder-wo';
+		} else if (!o.write) {
+			c = 'elfinder-ro';
+		}
+		return c;
+	},
+	
+	/**
+	 * Return localized string with file permissions
+	 * 
+	 * @param  Object  file
+	 * @return String
+	 */
+	formatPermissions : function(f) {
+		var p  = [];
+			
+		f.read && p.push(this.i18n('read'));
+		f.write && p.push(this.i18n('write'));	
+
+		return p.length ? p.join(' '+this.i18n('and')+' ') : this.i18n('noaccess');
+	},
+	
+	/**
+	 * Return formated file size
+	 * 
+	 * @param  Number  file size
+	 * @return String
+	 */
+	formatSize : function(s) {
+		var n = 1, u = 'b';
+		
+		if (s == 'unknown') {
+			return this.i18n('unknown');
+		}
+		
+		if (s > 1073741824) {
+			n = 1073741824;
+			u = 'GB';
+		} else if (s > 1048576) {
+			n = 1048576;
+			u = 'MB';
+		} else if (s > 1024) {
+			n = 1024;
+			u = 'KB';
+		}
+		s = s/n;
+		return (s > 0 ? n >= 1048576 ? s.toFixed(2) : Math.round(s) : 0) +' '+u;
+	},
+	
+	
+	navHash2Id : function(hash) {
+		return 'nav-'+hash;
+	},
+	
+	navId2Hash : function(id) {
+		return typeof(id) == 'string' ? id.substr(4) : false;
+	},
+	
+	log : function(m) { window.console && window.console.log && window.console.log(m); return this; },
+	
+	debug : function(type, m) {
+		var d = this.options.debug;
+
+		if (d == 'all' || d === true || ($.isArray(d) && $.inArray(type, d) != -1)) {
+			window.console && window.console.log && window.console.log('elfinder debug: ['+type+'] ['+this.id+']', m);
+		} 
+		return this;
+	},
+	time : function(l) { window.console && window.console.time && window.console.time(l); },
+	timeEnd : function(l) { window.console && window.console.timeEnd && window.console.timeEnd(l); }
+	
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.version.js
+ */
+
+/**
+ * Application version
+ *
+ * @type String
+ **/
+elFinder.prototype.version = '2.1 (Nightly: 093d077)';
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/jquery.elfinder.js
+ */
+
+$.fn.elfinder = function(o) {
+	
+	if (o == 'instance') {
+		return this.getElFinder();
+	}
+	
+	return this.each(function() {
+		
+		var cmd = typeof(o) == 'string' ? o : '';
+		if (!this.elfinder) {
+			new elFinder(this, typeof(o) == 'object' ? o : {})
+		}
+		
+		switch(cmd) {
+			case 'close':
+			case 'hide':
+				this.elfinder.hide();
+				break;
+				
+			case 'open':
+			case 'show':
+				this.elfinder.show();
+				break;
+				
+			case'destroy':
+				this.elfinder.destroy();
+				break;
+		}
+		
+	})
+}
+
+$.fn.getElFinder = function() {
+	var instance;
+	
+	this.each(function() {
+		if (this.elfinder) {
+			instance = this.elfinder;
+			return false;
+		}
+	});
+	
+	return instance;
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.options.js
+ */
+
+/**
+ * Default elFinder config
+ *
+ * @type  Object
+ * @autor Dmitry (dio) Levashov
+ */
+elFinder.prototype._options = {
+	/**
+	 * Connector url. Required!
+	 *
+	 * @type String
+	 */
+	url : '',
+
+	/**
+	 * Ajax request type.
+	 *
+	 * @type String
+	 * @default "get"
+	 */
+	requestType : 'get',
+
+	/**
+	 * Transport to send request to backend.
+	 * Required for future extensions using websockets/webdav etc.
+	 * Must be an object with "send" method.
+	 * transport.send must return $.Deferred() object
+	 *
+	 * @type Object
+	 * @default null
+	 * @example
+	 *  transport : {
+	 *    init : function(elfinderInstance) { },
+	 *    send : function(options) {
+	 *      var dfrd = $.Deferred();
+	 *      // connect to backend ...
+	 *      return dfrd;
+	 *    },
+	 *    upload : function(data) {
+	 *      var dfrd = $.Deferred();
+	 *      // upload ...
+	 *      return dfrd;
+	 *    }
+	 *    
+	 *  }
+	 **/
+	transport : {},
+
+	/**
+	 * URL to upload file to.
+	 * If not set - connector URL will be used
+	 *
+	 * @type String
+	 * @default  ''
+	 */
+	urlUpload : '',
+
+	/**
+	 * Allow to drag and drop to upload files
+	 *
+	 * @type Boolean|String
+	 * @default  'auto'
+	 */
+	dragUploadAllow : 'auto',
+	
+	/**
+	 * Timeout for upload using iframe
+	 *
+	 * @type Number
+	 * @default  0 - no timeout
+	 */
+	iframeTimeout : 0,
+	
+	/**
+	 * Data to append to all requests and to upload files
+	 *
+	 * @type Object
+	 * @default  {}
+	 */
+	customData : {},
+	
+	/**
+	 * Event listeners to bind on elFinder init
+	 *
+	 * @type Object
+	 * @default  {}
+	 */
+	handlers : {},
+
+	/**
+	 * Interface language
+	 *
+	 * @type String
+	 * @default "en"
+	 */
+	lang : 'en',
+
+	/**
+	 * Additional css class for filemanager node.
+	 *
+	 * @type String
+	 */
+	cssClass : '',
+
+	/**
+	 * Active commands list
+	 * If some required commands will be missed here, elFinder will add its
+	 *
+	 * @type Array
+	 */
+	commands : [
+		'open', 'reload', 'home', 'up', 'back', 'forward', 'getfile', 'quicklook', 
+		'download', 'rm', 'duplicate', 'rename', 'mkdir', 'mkfile', 'upload', 'copy', 
+		'cut', 'paste', 'edit', 'extract', 'archive', 'search', 'info', 'view', 'help', 'resize', 'sort', 'netmount'
+	],
+	
+	/**
+	 * Commands options.
+	 *
+	 * @type Object
+	 **/
+	commandsOptions : {
+		// "getfile" command options.
+		getfile : {
+			onlyURL  : false,
+			// allow to return multiple files info
+			multiple : false,
+			// allow to return filers info
+			folders  : false,
+			// action after callback (""/"close"/"destroy")
+			oncomplete : ''
+		},
+		// "upload" command options.
+		upload : {
+			ui : 'uploadbutton'
+		},
+		// "quicklook" command options.
+		quicklook : {
+			autoplay : true,
+			jplayer  : 'extensions/jplayer'
+		},
+		// "quicklook" command options.
+		edit : {
+			// list of allowed mimetypes to edit
+			// if empty - any text files can be edited
+			mimes : [],
+			// edit files in wysisyg's
+			editors : [
+				// {
+				// 	/**
+				// 	 * files mimetypes allowed to edit in current wysisyg
+				// 	 * @type  Array
+				// 	 */
+				// 	mimes : ['text/html'], 
+				// 	/**
+				// 	 * Called when "edit" dialog loaded.
+				// 	 * Place to init wysisyg.
+				// 	 * Can return wysisyg instance
+				// 	 *
+				// 	 * @param  DOMElement  textarea node
+				// 	 * @return Object
+				// 	 */
+				// 	load : function(textarea) { },
+				// 	/**
+				// 	 * Called before "edit" dialog closed.
+				// 	 * Place to destroy wysisyg instance.
+				// 	 *
+				// 	 * @param  DOMElement  textarea node
+				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)
+				// 	 * @return void
+				// 	 */
+				// 	close : function(textarea, instance) { },
+				// 	/**
+				// 	 * Called before file content send to backend.
+				// 	 * Place to update textarea content if needed.
+				// 	 *
+				// 	 * @param  DOMElement  textarea node
+				// 	 * @param  Object      wysisyg instance (if was returned by "load" callback)
+				// 	 * @return void
+				// 	 */
+				// 	save : function(textarea, editor) {}
+				// 
+				// }
+			]
+		},
+		
+
+		help : {view : ['about', 'shortcuts', 'help']}
+	},
+	
+	/**
+	 * Callback for "getfile" commands.
+	 * Required to use elFinder with WYSIWYG editors etc..
+	 *
+	 * @type Function
+	 * @default null (command not active)
+	 */
+	getFileCallback : null,
+	
+	/**
+	 * Default directory view. icons/list
+	 *
+	 * @type String
+	 * @default "icons"
+	 */
+	defaultView : 'icons',
+	
+	/**
+	 * UI plugins to load.
+	 * Current dir ui and dialogs loads always.
+	 * Here set not required plugins as folders tree/toolbar/statusbar etc.
+	 *
+	 * @type Array
+	 * @default ['toolbar', 'tree', 'path', 'stat']
+	 * @full ['toolbar', 'places', 'tree', 'path', 'stat']
+	 */
+	ui : ['toolbar', 'tree', 'path', 'stat'],
+	
+	/**
+	 * Some UI plugins options.
+	 * @type Object
+	 */
+	uiOptions : {
+		// toolbar configuration
+		toolbar : [
+			['back', 'forward'],
+			['netmount'],
+			// ['reload'],
+			// ['home', 'up'],
+			['mkdir', 'mkfile', 'upload'],
+			['open', 'download', 'getfile'],
+			['info'],
+			['quicklook'],
+			['copy', 'cut', 'paste'],
+			['rm'],
+			['duplicate', 'rename', 'edit', 'resize'],
+			['extract', 'archive'],
+			['search'],
+			['view', 'sort'],
+			['help']
+		],
+		// directories tree options
+		tree : {
+			// expand current root on init
+			openRootOnLoad : true,
+			// auto load current dir parents
+			syncTree : true
+		},
+		// navbar options
+		navbar : {
+			minWidth : 150,
+			maxWidth : 500
+		},
+		cwd : {
+			// display parent folder with ".." name :)
+			oldSchool : false
+		}
+	},
+
+	/**
+	 * Display only required files by types
+	 *
+	 * @type Array
+	 * @default []
+	 * @example
+	 *  onlyMimes : ["image"] - display all images
+	 *  onlyMimes : ["image/png", "application/x-shockwave-flash"] - display png and flash
+	 */
+	onlyMimes : [],
+
+	/**
+	 * Custom files sort rules.
+	 * All default rules (name/size/kind/date) set in elFinder._sortRules
+	 *
+	 * @type {Object}
+	 * @example
+	 * sortRules : {
+	 *   name : function(file1, file2) { return file1.name.toLowerCase().localeCompare(file2.name.toLowerCase()); }
+	 * }
+	 */
+	sortRules : {},
+
+	/**
+	 * Default sort type.
+	 *
+	 * @type {String}
+	 */
+	sortType : 'name',
+	
+	/**
+	 * Default sort order.
+	 *
+	 * @type {String}
+	 * @default "asc"
+	 */
+	sortOrder : 'asc',
+	
+	/**
+	 * Display folders first?
+	 *
+	 * @type {Boolean}
+	 * @default true
+	 */
+	sortStickFolders : true,
+	
+	/**
+	 * If true - elFinder will formating dates itself, 
+	 * otherwise - backend date will be used.
+	 *
+	 * @type Boolean
+	 */
+	clientFormatDate : true,
+	
+	/**
+	 * Show UTC dates.
+	 * Required set clientFormatDate to true
+	 *
+	 * @type Boolean
+	 */
+	UTCDate : false,
+	
+	/**
+	 * File modification datetime format.
+	 * Value from selected language data  is used by default.
+	 * Set format here to overwrite it.
+	 *
+	 * @type String
+	 * @default  ""
+	 */
+	dateFormat : '',
+	
+	/**
+	 * File modification datetime format in form "Yesterday 12:23:01".
+	 * Value from selected language data is used by default.
+	 * Set format here to overwrite it.
+	 * Use $1 for "Today"/"Yesterday" placeholder
+	 *
+	 * @type String
+	 * @default  ""
+	 * @example "$1 H:m:i"
+	 */
+	fancyDateFormat : '',
+	
+	/**
+	 * elFinder width
+	 *
+	 * @type String|Number
+	 * @default  "auto"
+	 */
+	width : 'auto',
+	
+	/**
+	 * elFinder height
+	 *
+	 * @type Number
+	 * @default  "auto"
+	 */
+	height : 400,
+	
+	/**
+	 * Make elFinder resizable if jquery ui resizable available
+	 *
+	 * @type Boolean
+	 * @default  true
+	 */
+	resizable : true,
+	
+	/**
+	 * Timeout before open notifications dialogs
+	 *
+	 * @type Number
+	 * @default  500 (.5 sec)
+	 */
+	notifyDelay : 500,
+	
+	/**
+	 * Allow shortcuts
+	 *
+	 * @type Boolean
+	 * @default  true
+	 */
+	allowShortcuts : true,
+	
+	/**
+	 * Remeber last opened dir to open it after reload or in next session
+	 *
+	 * @type Boolean
+	 * @default  true
+	 */
+	rememberLastDir : true,
+	
+	/**
+	 * Lazy load config.
+	 * How many files display at once?
+	 *
+	 * @type Number
+	 * @default  50
+	 */
+	showFiles : 30,
+	
+	/**
+	 * Lazy load config.
+	 * Distance in px to cwd bottom edge to start display files
+	 *
+	 * @type Number
+	 * @default  50
+	 */
+	showThreshold : 50,
+	
+	/**
+	 * Additional rule to valid new file name.
+	 * By default not allowed empty names or '..'
+	 *
+	 * @type false|RegExp|function
+	 * @default  false
+	 * @example
+	 *  disable names with spaces:
+	 *  validName : /^[^\s]$/
+	 */
+	validName : false,
+	
+	/**
+	 * Sync content interval
+	 * @todo - fix in elFinder
+	 * @type Number
+	 * @default  0 (do not sync)
+	 */
+	sync : 0,
+	
+	/**
+	 * How many thumbnails create in one request
+	 *
+	 * @type Number
+	 * @default  5
+	 */
+	loadTmbs : 5,
+	
+	/**
+	 * Cookie option for browsersdoes not suppot localStorage
+	 *
+	 * @type Object
+	 */
+	cookie         : {
+		expires : 30,
+		domain  : '',
+		path    : '/',
+		secure  : false
+	},
+	
+	/**
+	 * Contextmenu config
+	 *
+	 * @type Object
+	 */
+	contextmenu : {
+		// navbarfolder menu
+		navbar : ['open', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', '|', 'info'],
+		// current directory menu
+		cwd    : ['reload', 'back', '|', 'upload', 'mkdir', 'mkfile', 'paste', '|', 'sort', '|', 'info'],
+		// current directory file menu
+		files  : ['getfile', '|','open', 'quicklook', '|', 'download', '|', 'copy', 'cut', 'paste', 'duplicate', '|', 'rm', '|', 'edit', 'rename', 'resize', '|', 'archive', 'extract', '|', 'info']
+	},
+
+	/**
+	 * Debug config
+	 *
+	 * @type Array|Boolean
+	 */
+	// debug : true
+	debug : ['error', 'warning', 'event-destroy']
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.history.js
+ */
+
+/**
+ * @class elFinder.history
+ * Store visited folders
+ * and provide "back" and "forward" methods
+ *
+ * @author Dmitry (dio) Levashov
+ */
+elFinder.prototype.history = function(fm) {
+	var self = this,
+		/**
+		 * Update history on "open" event?
+		 *
+		 * @type Boolean
+		 */
+		update = true,
+		/**
+		 * Directories hashes storage
+		 *
+		 * @type Array
+		 */
+		history = [],
+		/**
+		 * Current directory index in history
+		 *
+		 * @type Number
+		 */
+		current,
+		/**
+		 * Clear history
+		 *
+		 * @return void
+		 */
+		reset = function() {
+			history = [fm.cwd().hash];
+			current = 0;
+			update  = true;
+		},
+		/**
+		 * Open prev/next folder
+		 *
+		 * @Boolen  open next folder?
+		 * @return jQuery.Deferred
+		 */
+		go = function(fwd) {
+			if ((fwd && self.canForward()) || (!fwd && self.canBack())) {
+				update = false;
+				return fm.exec('open', history[fwd ? ++current : --current]).fail(reset);
+			}
+			return $.Deferred().reject();
+		};
+	
+	/**
+	 * Return true if there is previous visited directories
+	 *
+	 * @return Boolen
+	 */
+	this.canBack = function() {
+		return current > 0;
+	}
+	
+	/**
+	 * Return true if can go forward
+	 *
+	 * @return Boolen
+	 */
+	this.canForward = function() {
+		return current < history.length - 1;
+	}
+	
+	/**
+	 * Go back
+	 *
+	 * @return void
+	 */
+	this.back = go;
+	
+	/**
+	 * Go forward
+	 *
+	 * @return void
+	 */
+	this.forward = function() {
+		return go(true);
+	}
+	
+	// bind to elfinder events
+	fm.open(function(e) {
+		var l = history.length,
+			cwd = fm.cwd().hash;
+
+		if (update) {
+			current >= 0 && l > current + 1 && history.splice(current+1);
+			history[history.length-1] != cwd && history.push(cwd);
+			current = history.length - 1;
+		}
+		update = true;
+	})
+	.reload(reset);
+	
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.command.js
+ */
+
+/**
+ * elFinder command prototype
+ *
+ * @type  elFinder.command
+ * @author  Dmitry (dio) Levashov
+ */
+elFinder.prototype.command = function(fm) {
+
+	/**
+	 * elFinder instance
+	 *
+	 * @type  elFinder
+	 */
+	this.fm = fm;
+	
+	/**
+	 * Command name, same as class name
+	 *
+	 * @type  String
+	 */
+	this.name = '';
+	
+	/**
+	 * Short command description
+	 *
+	 * @type  String
+	 */
+	this.title = '';
+	
+	/**
+	 * Current command state
+	 *
+	 * @example
+	 * this.state = -1; // command disabled
+	 * this.state = 0;  // command enabled
+	 * this.state = 1;  // command active (for example "fullscreen" command while elfinder in fullscreen mode)
+	 * @default -1
+	 * @type  Number
+	 */
+	this.state = -1;
+	
+	/**
+	 * If true, command can not be disabled by connector.
+	 * @see this.update()
+	 *
+	 * @type  Boolen
+	 */
+	this.alwaysEnabled = false;
+	
+	/**
+	 * If true, this means command was disabled by connector.
+	 * @see this.update()
+	 *
+	 * @type  Boolen
+	 */
+	this._disabled = false;
+	
+	this.disableOnSearch = false;
+	
+	this.updateOnSelect = true;
+	
+	/**
+	 * elFinder events defaults handlers.
+	 * Inside handlers "this" is current command object
+	 *
+	 * @type  Object
+	 */
+	this._handlers = {
+		enable  : function() { this.update(void(0), this.value); },
+		disable : function() { this.update(-1, this.value); },
+		'open reload load'    : function(e) { 
+			this._disabled = !(this.alwaysEnabled || this.fm.isCommandEnabled(this.name));
+			this.update(void(0), this.value)
+			this.change(); 
+		}
+	};
+	
+	/**
+	 * elFinder events handlers.
+	 * Inside handlers "this" is current command object
+	 *
+	 * @type  Object
+	 */
+	this.handlers = {}
+	
+	/**
+	 * Shortcuts
+	 *
+	 * @type  Array
+	 */
+	this.shortcuts = [];
+	
+	/**
+	 * Command options
+	 *
+	 * @type  Object
+	 */
+	this.options = {ui : 'button'};
+	
+	/**
+	 * Prepare object -
+	 * bind events and shortcuts
+	 *
+	 * @return void
+	 */
+	this.setup = function(name, opts) {
+		var self = this,
+			fm   = this.fm, i, s;
+
+		this.name      = name;
+		this.title     = fm.messages['cmd'+name] ? fm.i18n('cmd'+name) : name, 
+		this.options   = $.extend({}, this.options, opts);
+		this.listeners = [];
+
+		if (this.updateOnSelect) {
+			this._handlers.select = function() { this.update(void(0), this.value); }
+		}
+
+		$.each($.extend({}, self._handlers, self.handlers), function(cmd, handler) {
+			fm.bind(cmd, $.proxy(handler, self));
+		});
+
+		for (i = 0; i < this.shortcuts.length; i++) {
+			s = this.shortcuts[i];
+			s.callback = $.proxy(s.callback || function() { this.exec() }, this);
+			!s.description && (s.description = this.title);
+			fm.shortcut(s);
+		}
+
+		if (this.disableOnSearch) {
+			fm.bind('search searchend', function(e) {
+				self._disabled = e.type == 'search';
+				self.update(void(0), self.value);
+			});
+		}
+
+		this.init();
+	}
+
+	/**
+	 * Command specific init stuffs
+	 *
+	 * @return void
+	 */
+	this.init = function() { }
+
+	/**
+	 * Exec command
+	 *
+	 * @param  Array         target files hashes
+	 * @param  Array|Object  command value
+	 * @return $.Deferred
+	 */
+	this.exec = function(files, opts) { 
+		return $.Deferred().reject(); 
+	}
+	
+	/**
+	 * Return true if command disabled.
+	 *
+	 * @return Boolen
+	 */
+	this.disabled = function() {
+		return this.state < 0;
+	}
+	
+	/**
+	 * Return true if command enabled.
+	 *
+	 * @return Boolen
+	 */
+	this.enabled = function() {
+		return this.state > -1;
+	}
+	
+	/**
+	 * Return true if command active.
+	 *
+	 * @return Boolen
+	 */
+	this.active = function() {
+		return this.state > 0;
+	}
+	
+	/**
+	 * Return current command state.
+	 * Must be overloaded in most commands
+	 *
+	 * @return Number
+	 */
+	this.getstate = function() {
+		return -1;
+	}
+	
+	/**
+	 * Update command state/value
+	 * and rize 'change' event if smth changed
+	 *
+	 * @param  Number  new state or undefined to auto update state
+	 * @param  mixed   new value
+	 * @return void
+	 */
+	this.update = function(s, v) {
+		var state = this.state,
+			value = this.value;
+
+		if (this._disabled) {
+			this.state = -1;
+		} else {
+			this.state = s !== void(0) ? s : this.getstate();
+		}
+
+		this.value = v;
+		
+		if (state != this.state || value != this.value) {
+			this.change();
+		}
+	}
+	
+	/**
+	 * Bind handler / fire 'change' event.
+	 *
+	 * @param  Function|undefined  event callback
+	 * @return void
+	 */
+	this.change = function(c) {
+		var cmd, i;
+		
+		if (typeof(c) === 'function') {
+			this.listeners.push(c);			
+		} else {
+			for (i = 0; i < this.listeners.length; i++) {
+				cmd = this.listeners[i];
+				try {
+					cmd(this.state, this.value);
+				} catch (e) {
+					this.fm.debug('error', e)
+				}
+			}
+		}
+		return this;
+	}
+	
+
+	/**
+	 * With argument check given files hashes and return list of existed files hashes.
+	 * Without argument return selected files hashes.
+	 *
+	 * @param  Array|String|void  hashes
+	 * @return Array
+	 */
+	this.hashes = function(hashes) {
+		return hashes
+			? $.map($.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) ? hash : null; })
+			: fm.selected();
+	}
+	
+	/**
+	 * Return only existed files from given fils hashes | selected files
+	 *
+	 * @param  Array|String|void  hashes
+	 * @return Array
+	 */
+	this.files = function(hashes) {
+		var fm = this.fm;
+		
+		return hashes
+			? $.map($.isArray(hashes) ? hashes : [hashes], function(hash) { return fm.file(hash) || null })
+			: fm.selectedFiles();
+	}
+}
+
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/elFinder.resources.js
+ */
+
+/**
+ * elFinder resources registry.
+ * Store shared data
+ *
+ * @type Object
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.resources = {
+	'class' : {
+		hover       : 'ui-state-hover',
+		active      : 'ui-state-active',
+		disabled    : 'ui-state-disabled',
+		draggable   : 'ui-draggable',
+		droppable   : 'ui-droppable',
+		adroppable  : 'elfinder-droppable-active',
+		cwdfile     : 'elfinder-cwd-file',
+		cwd         : 'elfinder-cwd',
+		tree        : 'elfinder-tree',
+		treeroot    : 'elfinder-navbar-root',
+		navdir      : 'elfinder-navbar-dir',
+		navdirwrap  : 'elfinder-navbar-dir-wrapper',
+		navarrow    : 'elfinder-navbar-arrow',
+		navsubtree  : 'elfinder-navbar-subtree',
+		navcollapse : 'elfinder-navbar-collapsed',
+		navexpand   : 'elfinder-navbar-expanded',
+		treedir     : 'elfinder-tree-dir',
+		placedir    : 'elfinder-place-dir',
+		searchbtn   : 'elfinder-button-search'
+	},
+	tpl : {
+		perms      : '<span class="elfinder-perms"/>',
+		symlink    : '<span class="elfinder-symlink"/>',
+		navicon    : '<span class="elfinder-nav-icon"/>',
+		navspinner : '<span class="elfinder-navbar-spinner"/>',
+		navdir     : '<div class="elfinder-navbar-wrapper"><span id="{id}" class="ui-corner-all elfinder-navbar-dir {cssclass}"><span class="elfinder-navbar-arrow"/><span class="elfinder-navbar-icon"/>{symlink}{permissions}{name}</span><div class="elfinder-navbar-subtree"/></div>'
+		
+	},
+	
+	mimes : {
+		text : [
+			'application/x-empty',
+			'application/javascript', 
+			'application/xhtml+xml', 
+			'audio/x-mp3-playlist', 
+			'application/x-web-config',
+			'application/docbook+xml',
+			'application/x-php',
+			'application/x-perl',
+			'application/x-awk',
+			'application/x-config',
+			'application/x-csh',
+			'application/xml'
+		]
+	},
+	
+	mixin : {
+		make : function() {
+			var fm   = this.fm,
+				cmd  = this.name,
+				cwd  = fm.getUI('cwd'),
+				dfrd = $.Deferred()
+					.fail(function(error) {
+						cwd.trigger('unselectall');
+						error && fm.error(error);
+					})
+					.always(function() {
+						input.remove();
+						node.remove();
+						fm.enable();
+					}),
+				id    = 'tmp_'+parseInt(Math.random()*100000),
+				phash = fm.cwd().hash,
+				date = new Date(),
+				file   = {
+					hash  : id,
+					name  : fm.uniqueName(this.prefix),
+					mime  : this.mime,
+					read  : true,
+					write : true,
+					date  : 'Today '+date.getHours()+':'+date.getMinutes()
+				},
+				node = cwd.trigger('create.'+fm.namespace, file).find('#'+id),
+				input = $('<input type="text"/>')
+					.keydown(function(e) {
+						e.stopImmediatePropagation();
+
+						if (e.keyCode == $.ui.keyCode.ESCAPE) {
+							dfrd.reject();
+						} else if (e.keyCode == $.ui.keyCode.ENTER) {
+							input.blur();
+						}
+					})
+					.mousedown(function(e) {
+						e.stopPropagation();
+					})
+					.blur(function() {
+						var name   = $.trim(input.val()),
+							parent = input.parent();
+
+						if (parent.length) {
+
+							if (!name) {
+								return dfrd.reject('errInvName');
+							}
+							if (fm.fileByName(name, phash)) {
+								return dfrd.reject(['errExists', name]);
+							}
+
+							parent.html(fm.escape(name));
+
+							fm.lockfiles({files : [id]});
+
+							fm.request({
+									data        : {cmd : cmd, name : name, target : phash}, 
+									notify      : {type : cmd, cnt : 1},
+									preventFail : true,
+									syncOnFail  : true
+								})
+								.fail(function(error) {
+									dfrd.reject(error);
+								})
+								.done(function(data) {
+									dfrd.resolve(data);
+								});
+						}
+					});
+
+
+			if (this.disabled() || !node.length) {
+				return dfrd.reject();
+			}
+
+			fm.disable();
+			node.find('.elfinder-cwd-filename').empty('').append(input.val(file.name));
+			input.select().focus();
+			input[0].setSelectionRange && input[0].setSelectionRange(0, file.name.replace(/\..+$/, '').length);
+
+			return dfrd;
+
+
+
+		}
+		
+	}
+}
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/jquery.dialogelfinder.js
+ */
+
+/**
+ * @class dialogelfinder - open elFinder in dialog window
+ *
+ * @param  Object  elFinder options with dialog options
+ * @example
+ * $(selector).dialogelfinder({
+ *     // some elfinder options
+ *     title          : 'My files', // dialog title, default = "Files"
+ *     width          : 850,        // dialog width, default 840
+ *     autoOpen       : false,      // if false - dialog will not be opened after init, default = true
+ *     destroyOnClose : true        // destroy elFinder on close dialog, default = false
+ * })
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.dialogelfinder = function(opts) {
+	var position = 'elfinderPosition',
+		destroy  = 'elfinderDestroyOnClose';
+	
+	this.not('.elfinder').each(function() {
+
+		
+		var doc     = $(document),
+			toolbar = $('<div class="ui-widget-header dialogelfinder-drag ui-corner-top">'+(opts.title || 'Files')+'</div>'),
+			button  = $('<a href="#" class="dialogelfinder-drag-close ui-corner-all"><span class="ui-icon ui-icon-closethick"/></a>')
+				.appendTo(toolbar)
+				.click(function(e) {
+					e.preventDefault();
+					
+					node.dialogelfinder('close');
+				}),
+			node    = $(this).addClass('dialogelfinder')
+				.css('position', 'absolute')
+				.hide()
+				.appendTo('body')
+				.draggable({ handle : '.dialogelfinder-drag',
+					     containment : 'window' })
+				.elfinder(opts)
+				.prepend(toolbar),
+			elfinder = node.elfinder('instance');
+		
+		
+		node.width(parseInt(node.width()) || 840) // fix width if set to "auto"
+			.data(destroy, !!opts.destroyOnClose)
+			.find('.elfinder-toolbar').removeClass('ui-corner-top');
+		
+		opts.position && node.data(position, opts.position);
+		
+		opts.autoOpen !== false && $(this).dialogelfinder('open');
+
+	});
+	
+	if (opts == 'open') {
+		var node = $(this),
+			pos  = node.data(position) || {
+				top  : parseInt($(document).scrollTop() + ($(window).height() < node.height() ? 2 : ($(window).height() - node.height())/2)),
+				left : parseInt($(document).scrollLeft() + ($(window).width() < node.width()  ? 2 : ($(window).width()  - node.width())/2))
+			},
+			zindex = 100;
+
+		if (node.is(':hidden')) {
+			
+			$('body').find(':visible').each(function() {
+				var $this = $(this), z;
+				
+				if (this !== node[0] && $this.css('position') == 'absolute' && (z = parseInt($this.zIndex())) > zindex) {
+					zindex = z + 1;
+				}
+			});
+
+			node.zIndex(zindex).css(pos).show().trigger('resize')
+
+			setTimeout(function() {
+				// fix resize icon position and make elfinder active
+				node.trigger('resize').mousedown();
+			}, 200);
+		}
+	} else if (opts == 'close') {
+		var node = $(this);
+			
+		if (node.is(':visible')) {
+			!!node.data(destroy)
+				? node.elfinder('destroy').remove()
+				: node.elfinder('close');
+		}
+	} else if (opts == 'instance') {
+		return $(this).getElFinder();
+	}
+
+	return this;
+}
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/i18n/elfinder.en.js
+ */
+
+/**
+ * English translation
+ * @author Troex Nevelin <troex@fury.scancode.ru>
+ * @version 2013-07-03
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.en = {
+		translator : 'Troex Nevelin &lt;troex@fury.scancode.ru&gt;',
+		language   : 'English',
+		direction  : 'ltr',
+		dateFormat : 'M d, Y h:i A', // Mar 13, 2012 05:27 PM
+		fancyDateFormat : '$1 h:i A', // will produce smth like: Today 12:25 PM
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : 'Error',
+			'errUnknown'           : 'Unknown error.',
+			'errUnknownCmd'        : 'Unknown command.',
+			'errJqui'              : 'Invalid jQuery UI configuration. Selectable, draggable and droppable components must be included.',
+			'errNode'              : 'elFinder requires DOM Element to be created.',
+			'errURL'               : 'Invalid elFinder configuration! URL option is not set.',
+			'errAccess'            : 'Access denied.',
+			'errConnect'           : 'Unable to connect to backend.',
+			'errAbort'             : 'Connection aborted.',
+			'errTimeout'           : 'Connection timeout.',
+			'errNotFound'          : 'Backend not found.',
+			'errResponse'          : 'Invalid backend response.',
+			'errConf'              : 'Invalid backend configuration.',
+			'errJSON'              : 'PHP JSON module not installed.',
+			'errNoVolumes'         : 'Readable volumes not available.',
+			'errCmdParams'         : 'Invalid parameters for command "$1".',
+			'errDataNotJSON'       : 'Data is not JSON.',
+			'errDataEmpty'         : 'Data is empty.',
+			'errCmdReq'            : 'Backend request requires command name.',
+			'errOpen'              : 'Unable to open "$1".',
+			'errNotFolder'         : 'Object is not a folder.',
+			'errNotFile'           : 'Object is not a file.',
+			'errRead'              : 'Unable to read "$1".',
+			'errWrite'             : 'Unable to write into "$1".',
+			'errPerm'              : 'Permission denied.',
+			'errLocked'            : '"$1" is locked and can not be renamed, moved or removed.',
+			'errExists'            : 'File named "$1" already exists.',
+			'errInvName'           : 'Invalid file name.',
+			'errFolderNotFound'    : 'Folder not found.',
+			'errFileNotFound'      : 'File not found.',
+			'errTrgFolderNotFound' : 'Target folder "$1" not found.',
+			'errPopup'             : 'Browser prevented opening popup window. To open file enable it in browser options.',
+			'errMkdir'             : 'Unable to create folder "$1".',
+			'errMkfile'            : 'Unable to create file "$1".',
+			'errRename'            : 'Unable to rename "$1".',
+			'errCopyFrom'          : 'Copying files from volume "$1" not allowed.',
+			'errCopyTo'            : 'Copying files to volume "$1" not allowed.',
+			'errUpload'            : 'Upload error.',  // old name - errUploadCommon
+			'errUploadFile'        : 'Unable to upload "$1".', // old name - errUpload
+			'errUploadNoFiles'     : 'No files found for upload.', 
+			'errUploadTotalSize'   : 'Data exceeds the maximum allowed size.', // old name - errMaxSize
+			'errUploadFileSize'    : 'File exceeds maximum allowed size.', //  old name - errFileMaxSize
+			'errUploadMime'        : 'File type not allowed.', 
+			'errUploadTransfer'    : '"$1" transfer error.', 
+			'errNotReplace'        : 'Object "$1" already exists at this location and can not be replaced by object with another type.', // new
+			'errReplace'           : 'Unable to replace "$1".',
+			'errSave'              : 'Unable to save "$1".',
+			'errCopy'              : 'Unable to copy "$1".',
+			'errMove'              : 'Unable to move "$1".',
+			'errCopyInItself'      : 'Unable to copy "$1" into itself.',
+			'errRm'                : 'Unable to remove "$1".',
+			'errRmSrc'             : 'Unable remove source file(s).',
+			'errExtract'           : 'Unable to extract files from "$1".',
+			'errArchive'           : 'Unable to create archive.',
+			'errArcType'           : 'Unsupported archive type.',
+			'errNoArchive'         : 'File is not archive or has unsupported archive type.',
+			'errCmdNoSupport'      : 'Backend does not support this command.',
+			'errReplByChild'       : 'The folder “$1” can’t be replaced by an item it contains.',
+			'errArcSymlinks'       : 'For security reason denied to unpack archives contains symlinks or files with not allowed names.', // edited 24.06.2012
+			'errArcMaxSize'        : 'Archive files exceeds maximum allowed size.',
+			'errResize'            : 'Unable to resize "$1".',
+			'errResizeDegree'      : 'Invalid rotate degree.',  // added 7.3.2013
+			'errResizeRotate'      : 'Image dose not rotated.',  // added 7.3.2013
+			'errResizeSize'        : 'Invalid image size.',  // added 7.3.2013
+			'errResizeNoChange'    : 'Image size not changed.',  // added 7.3.2013
+			'errUsupportType'      : 'Unsupported file type.',
+			'errNotUTF8Content'    : 'File "$1" is not in UTF-8 and cannot be edited.',  // added 9.11.2011
+			'errNetMount'          : 'Unable to mount "$1".', // added 17.04.2012
+			'errNetMountNoDriver'  : 'Unsupported protocol.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Mount failed.',         // added 17.04.2012
+			'errNetMountHostReq'   : 'Host required.', // added 18.04.2012
+			'errSessionExpires'    : 'Your session has expired due to inactivity.',
+			'errCreatingTempDir'   : 'Unable to create temporary directory: "$1"',
+			'errFtpDownloadFile'   : 'Unable to download file from FTP: "$1"',
+			'errFtpUploadFile'     : 'Unable to upload file to FTP: "$1"',
+			'errFtpMkdir'          : 'Unable to create remote directory on FTP: "$1"',
+			'errArchiveExec'       : 'Error while archiving files: "$1"',
+			'errExtractExec'       : 'Error while extracting files: "$1"',
+
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Create archive',
+			'cmdback'      : 'Back',
+			'cmdcopy'      : 'Copy',
+			'cmdcut'       : 'Cut',
+			'cmddownload'  : 'Download',
+			'cmdduplicate' : 'Duplicate',
+			'cmdedit'      : 'Edit file',
+			'cmdextract'   : 'Extract files from archive',
+			'cmdforward'   : 'Forward',
+			'cmdgetfile'   : 'Select files',
+			'cmdhelp'      : 'About this software',
+			'cmdhome'      : 'Home',
+			'cmdinfo'      : 'Get info',
+			'cmdmkdir'     : 'New folder',
+			'cmdmkfile'    : 'New text file',
+			'cmdopen'      : 'Open',
+			'cmdpaste'     : 'Paste',
+			'cmdquicklook' : 'Preview',
+			'cmdreload'    : 'Reload',
+			'cmdrename'    : 'Rename',
+			'cmdrm'        : 'Delete',
+			'cmdsearch'    : 'Find files',
+			'cmdup'        : 'Go to parent directory',
+			'cmdupload'    : 'Upload files',
+			'cmdview'      : 'View',
+			'cmdresize'    : 'Resize & Rotate',
+			'cmdsort'      : 'Sort',
+			'cmdnetmount'  : 'Mount network volume', // added 18.04.2012
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Close',
+			'btnSave'   : 'Save',
+			'btnRm'     : 'Remove',
+			'btnApply'  : 'Apply',
+			'btnCancel' : 'Cancel',
+			'btnNo'     : 'No',
+			'btnYes'    : 'Yes',
+			'btnMount'  : 'Mount',  // added 18.04.2012
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Open folder',
+			'ntffile'     : 'Open file',
+			'ntfreload'   : 'Reload folder content',
+			'ntfmkdir'    : 'Creating directory',
+			'ntfmkfile'   : 'Creating files',
+			'ntfrm'       : 'Delete files',
+			'ntfcopy'     : 'Copy files',
+			'ntfmove'     : 'Move files',
+			'ntfprepare'  : 'Prepare to copy files',
+			'ntfrename'   : 'Rename files',
+			'ntfupload'   : 'Uploading files',
+			'ntfdownload' : 'Downloading files',
+			'ntfsave'     : 'Save files',
+			'ntfarchive'  : 'Creating archive',
+			'ntfextract'  : 'Extracting files from archive',
+			'ntfsearch'   : 'Searching files',
+			'ntfresize'   : 'Resizing images',
+			'ntfsmth'     : 'Doing something',
+			'ntfloadimg'  : 'Loading image',
+			'ntfnetmount' : 'Mounting network volume', // added 18.04.2012
+			'ntfdim'      : 'Acquiring image dimension', // added 20.05.2013
+			'ntfreaddir'  : 'Reading folder infomation', // added 01.07.2013
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : 'unknown',
+			'Today'       : 'Today',
+			'Yesterday'   : 'Yesterday',
+			'Jan'         : 'Jan',
+			'Feb'         : 'Feb',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Apr',
+			'May'         : 'May',
+			'Jun'         : 'Jun',
+			'Jul'         : 'Jul',
+			'Aug'         : 'Aug',
+			'Sep'         : 'Sep',
+			'Oct'         : 'Oct',
+			'Nov'         : 'Nov',
+			'Dec'         : 'Dec',
+
+			/******************************** sort variants ********************************/
+			'sortname'          : 'by name', 
+			'sortkind'          : 'by kind', 
+			'sortsize'          : 'by size',
+			'sortdate'          : 'by date',
+			'sortFoldersFirst'  : 'Folders first',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Confirmation required',
+			'confirmRm'       : 'Are you sure you want to remove files?<br/>This cannot be undone!',
+			'confirmRepl'     : 'Replace old file with new one?',
+			'apllyAll'        : 'Apply to all',
+			'name'            : 'Name',
+			'size'            : 'Size',
+			'perms'           : 'Permissions',
+			'modify'          : 'Modified',
+			'kind'            : 'Kind',
+			'read'            : 'read',
+			'write'           : 'write',
+			'noaccess'        : 'no access',
+			'and'             : 'and',
+			'unknown'         : 'unknown',
+			'selectall'       : 'Select all files',
+			'selectfiles'     : 'Select file(s)',
+			'selectffile'     : 'Select first file',
+			'selectlfile'     : 'Select last file',
+			'viewlist'        : 'List view',
+			'viewicons'       : 'Icons view',
+			'places'          : 'Places',
+			'calc'            : 'Calculate', 
+			'path'            : 'Path',
+			'aliasfor'        : 'Alias for',
+			'locked'          : 'Locked',
+			'dim'             : 'Dimensions',
+			'files'           : 'Files',
+			'folders'         : 'Folders',
+			'items'           : 'Items',
+			'yes'             : 'yes',
+			'no'              : 'no',
+			'link'            : 'Link',
+			'searcresult'     : 'Search results',  
+			'selected'        : 'selected items',
+			'about'           : 'About',
+			'shortcuts'       : 'Shortcuts',
+			'help'            : 'Help',
+			'webfm'           : 'Web file manager',
+			'ver'             : 'Version',
+			'protocolver'     : 'protocol version',
+			'homepage'        : 'Project home',
+			'docs'            : 'Documentation',
+			'github'          : 'Fork us on Github',
+			'twitter'         : 'Follow us on twitter',
+			'facebook'        : 'Join us on facebook',
+			'team'            : 'Team',
+			'chiefdev'        : 'chief developer',
+			'developer'       : 'developer',
+			'contributor'     : 'contributor',
+			'maintainer'      : 'maintainer',
+			'translator'      : 'translator',
+			'icons'           : 'Icons',
+			'dontforget'      : 'and don\'t forget to take your towel',
+			'shortcutsof'     : 'Shortcuts disabled',
+			'dropFiles'       : 'Drop files here',
+			'dropFilesBrowser': 'Drop or paste files from browser', // added 30.05.2012
+			'or'              : 'or',
+			'selectForUpload' : 'Select files to upload',
+			'moveFiles'       : 'Move files',
+			'copyFiles'       : 'Copy files',
+			'rmFromPlaces'    : 'Remove from places',
+			'aspectRatio'     : 'Aspect ratio',
+			'scale'           : 'Scale',
+			'width'           : 'Width',
+			'height'          : 'Height',
+			'resize'          : 'Resize',
+			'crop'            : 'Crop',
+			'rotate'          : 'Rotate',
+			'rotate-cw'       : 'Rotate 90 degrees CW',
+			'rotate-ccw'      : 'Rotate 90 degrees CCW',
+			'degree'          : '°',
+			'netMountDialogTitle' : 'Mount network volume', // added 18.04.2012
+			'protocol'            : 'Protocol', // added 18.04.2012
+			'host'                : 'Host', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'User', // added 18.04.2012
+			'pass'                : 'Password', // added 18.04.2012
+
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Unknown',
+			'kindFolder'      : 'Folder',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : 'Broken alias',
+			// applications
+			'kindApp'         : 'Application',
+			'kindPostscript'  : 'Postscript document',
+			'kindMsOffice'    : 'Microsoft Office document',
+			'kindMsWord'      : 'Microsoft Word document',
+			'kindMsExcel'     : 'Microsoft Excel document',
+			'kindMsPP'        : 'Microsoft Powerpoint presentation',
+			'kindOO'          : 'Open Office document',
+			'kindAppFlash'    : 'Flash application',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent file',
+			'kind7z'          : '7z archive',
+			'kindTAR'         : 'TAR archive',
+			'kindGZIP'        : 'GZIP archive',
+			'kindBZIP'        : 'BZIP archive',
+			'kindZIP'         : 'ZIP archive',
+			'kindRAR'         : 'RAR archive',
+			'kindJAR'         : 'Java JAR file',
+			'kindTTF'         : 'True Type font',
+			'kindOTF'         : 'Open Type font',
+			'kindRPM'         : 'RPM package',
+			// texts
+			'kindText'        : 'Text document',
+			'kindTextPlain'   : 'Plain text',
+			'kindPHP'         : 'PHP source',
+			'kindCSS'         : 'Cascading style sheet',
+			'kindHTML'        : 'HTML document',
+			'kindJS'          : 'Javascript source',
+			'kindRTF'         : 'Rich Text Format',
+			'kindC'           : 'C source',
+			'kindCHeader'     : 'C header source',
+			'kindCPP'         : 'C++ source',
+			'kindCPPHeader'   : 'C++ header source',
+			'kindShell'       : 'Unix shell script',
+			'kindPython'      : 'Python source',
+			'kindJava'        : 'Java source',
+			'kindRuby'        : 'Ruby source',
+			'kindPerl'        : 'Perl script',
+			'kindSQL'         : 'SQL source',
+			'kindXML'         : 'XML document',
+			'kindAWK'         : 'AWK source',
+			'kindCSV'         : 'Comma separated values',
+			'kindDOCBOOK'     : 'Docbook XML document',
+			// images
+			'kindImage'       : 'Image',
+			'kindBMP'         : 'BMP image',
+			'kindJPEG'        : 'JPEG image',
+			'kindGIF'         : 'GIF Image',
+			'kindPNG'         : 'PNG Image',
+			'kindTIFF'        : 'TIFF image',
+			'kindTGA'         : 'TGA image',
+			'kindPSD'         : 'Adobe Photoshop image',
+			'kindXBITMAP'     : 'X bitmap image',
+			'kindPXM'         : 'Pixelmator image',
+			// media
+			'kindAudio'       : 'Audio media',
+			'kindAudioMPEG'   : 'MPEG audio',
+			'kindAudioMPEG4'  : 'MPEG-4 audio',
+			'kindAudioMIDI'   : 'MIDI audio',
+			'kindAudioOGG'    : 'Ogg Vorbis audio',
+			'kindAudioWAV'    : 'WAV audio',
+			'AudioPlaylist'   : 'MP3 playlist',
+			'kindVideo'       : 'Video media',
+			'kindVideoDV'     : 'DV movie',
+			'kindVideoMPEG'   : 'MPEG movie',
+			'kindVideoMPEG4'  : 'MPEG-4 movie',
+			'kindVideoAVI'    : 'AVI movie',
+			'kindVideoMOV'    : 'Quick Time movie',
+			'kindVideoWM'     : 'Windows Media movie',
+			'kindVideoFlash'  : 'Flash movie',
+			'kindVideoMKV'    : 'Matroska movie',
+			'kindVideoOGG'    : 'Ogg movie'
+		}
+	}
+}
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/button.js
+ */
+
+/**
+ * @class  elFinder toolbar button widget.
+ * If command has variants - create menu
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderbutton = function(cmd) {
+	return this.each(function() {
+		
+		var c        = 'class',
+			fm       = cmd.fm,
+			disabled = fm.res(c, 'disabled'),
+			active   = fm.res(c, 'active'),
+			hover    = fm.res(c, 'hover'),
+			item     = 'elfinder-button-menu-item',
+			selected = 'elfinder-button-menu-item-selected',
+			menu,
+			button   = $(this).addClass('ui-state-default elfinder-button')
+				.attr('title', cmd.title)
+				.append('<span class="elfinder-button-icon elfinder-button-icon-'+cmd.name+'"/>')
+				.hover(function(e) { !button.is('.'+disabled) && button[e.type == 'mouseleave' ? 'removeClass' : 'addClass'](hover) /**button.toggleClass(hover);*/ })
+				.click(function(e) { 
+					if (!button.is('.'+disabled)) {
+						if (menu && cmd.variants.length > 1) {
+							// close other menus
+							menu.is(':hidden') && cmd.fm.getUI().click();
+							e.stopPropagation();
+							menu.slideToggle(100);
+						} else {
+							cmd.exec();
+						}
+						
+					}
+				}),
+			hideMenu = function() {
+				menu.hide();
+			};
+			
+		// if command has variants create menu
+		if ($.isArray(cmd.variants)) {
+			button.addClass('elfinder-menubutton');
+			
+			menu = $('<div class="ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')
+				.hide()
+				.appendTo(button)
+				.zIndex(12+button.zIndex())
+				.delegate('.'+item, 'hover', function() { $(this).toggleClass(hover) })
+				.delegate('.'+item, 'click', function(e) {
+					e.preventDefault();
+					e.stopPropagation();
+					button.removeClass(hover);
+					cmd.exec(cmd.fm.selected(), $(this).data('value'));
+				});
+
+			cmd.fm.bind('disable select', hideMenu).getUI().click(hideMenu);
+			
+			cmd.change(function() {
+				menu.html('');
+				$.each(cmd.variants, function(i, variant) {
+					menu.append($('<div class="'+item+'">'+variant[1]+'</div>').data('value', variant[0]).addClass(variant[0] == cmd.value ? selected : ''));
+				});
+			});
+		}	
+			
+		cmd.change(function() {
+			if (cmd.disabled()) {
+				button.removeClass(active+' '+hover).addClass(disabled);
+			} else {
+				button.removeClass(disabled);
+				button[cmd.active() ? 'addClass' : 'removeClass'](active);
+			}
+		})
+		.change();
+	});
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/contextmenu.js
+ */
+
+/**
+ * @class  elFinder contextmenu
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindercontextmenu = function(fm) {
+	
+	return this.each(function() {
+		var menu = $(this).addClass('ui-helper-reset ui-widget ui-state-default ui-corner-all elfinder-contextmenu elfinder-contextmenu-'+fm.direction)
+				.hide()
+				.appendTo('body')
+				.delegate('.elfinder-contextmenu-item', 'mouseenter mouseleave', function() {
+					$(this).toggleClass('ui-state-hover')
+				}),
+			subpos  = fm.direction == 'ltr' ? 'left' : 'right',
+			types = $.extend({}, fm.options.contextmenu),
+			tpl     = '<div class="elfinder-contextmenu-item"><span class="elfinder-button-icon {icon} elfinder-contextmenu-icon"/><span>{label}</span></div>',
+			item = function(label, icon, callback) {
+				return $(tpl.replace('{icon}', icon ? 'elfinder-button-icon-'+icon : '').replace('{label}', label))
+					.click(function(e) {
+						e.stopPropagation();
+						e.stopPropagation();
+						callback();
+					})
+			},
+			
+			open = function(x, y) {
+				var win        = $(window),
+					width      = menu.outerWidth(),
+					height     = menu.outerHeight(),
+					wwidth     = win.width(),
+					wheight    = win.height(),
+					scrolltop  = win.scrollTop(),
+					scrollleft = win.scrollLeft(),
+					css        = {
+						top  : (y + height < wheight ? y : y - height > 0 ? y - height : y) + scrolltop,
+						left : (x + width  < wwidth  ? x : x - width) + scrollleft,
+						'z-index' : 100 + fm.getUI('workzone').zIndex()
+					};
+
+				menu.css(css)
+					.show();
+				
+				css = {'z-index' : css['z-index']+10};
+				css[subpos] = parseInt(menu.width());
+				menu.find('.elfinder-contextmenu-sub').css(css);
+			},
+			
+			close = function() {
+				menu.hide().empty();
+			},
+			
+			create = function(type, targets) {
+				var sep = false;
+				
+				
+				
+				$.each(types[type]||[], function(i, name) {
+					var cmd, node, submenu;
+					
+					if (name == '|' && sep) {
+						menu.append('<div class="elfinder-contextmenu-separator"/>');
+						sep = false;
+						return;
+					}
+					
+					cmd = fm.command(name);
+
+					if (cmd && cmd.getstate(targets) != -1) {
+						if (cmd.variants) {
+							if (!cmd.variants.length) {
+								return;
+							}
+							node = item(cmd.title, cmd.name, function() {});
+							
+							submenu = $('<div class="ui-corner-all elfinder-contextmenu-sub"/>')
+								.appendTo(node.append('<span class="elfinder-contextmenu-arrow"/>'));
+								
+							node.addClass('elfinder-contextmenu-group')
+								.hover(function() {
+									submenu.toggle()
+								})
+								
+							$.each(cmd.variants, function(i, variant) {
+								submenu.append(
+									$('<div class="elfinder-contextmenu-item"><span>'+variant[1]+'</span></div>')
+										.click(function(e) {
+											e.stopPropagation();
+											close();
+											cmd.exec(targets, variant[0]);
+										})
+								);
+							});
+								
+						} else {
+							node = item(cmd.title, cmd.name, function() {
+								close();
+								cmd.exec(targets);
+							})
+							
+						}
+						
+						menu.append(node)
+						sep = true;
+					}
+				})
+			},
+			
+			createFromRaw = function(raw) {
+				$.each(raw, function(i, data) {
+					var node;
+					
+					if (data.label && typeof data.callback == 'function') {
+						node = item(data.label, data.icon, function() {
+							close();
+							data.callback();
+						});
+						menu.append(node);
+					}
+				})
+			};
+		
+		fm.one('load', function() {
+			fm.bind('contextmenu', function(e) {
+				var data = e.data;
+
+				close();
+
+				if (data.type && data.targets) {
+					create(data.type, data.targets);
+				} else if (data.raw) {
+					createFromRaw(data.raw);
+				}
+
+				menu.children().length && open(data.x, data.y);
+			})
+			.one('destroy', function() { menu.remove(); })
+			.bind('disable select', close)
+			.getUI().click(close);
+		});
+		
+	});
+	
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/cwd.js
+ */
+
+/**
+ * elFinder current working directory ui.
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindercwd = function(fm, options) {
+	
+	this.not('.elfinder-cwd').each(function() {
+		// fm.time('cwdLoad');
+		
+		var 
+			list = fm.viewType == 'list',
+
+			undef = 'undefined',
+			/**
+			 * Select event full name
+			 *
+			 * @type String
+			 **/
+			evtSelect = 'select.'+fm.namespace,
+			
+			/**
+			 * Unselect event full name
+			 *
+			 * @type String
+			 **/
+			evtUnselect = 'unselect.'+fm.namespace,
+			
+			/**
+			 * Disable event full name
+			 *
+			 * @type String
+			 **/
+			evtDisable = 'disable.'+fm.namespace,
+			
+			/**
+			 * Disable event full name
+			 *
+			 * @type String
+			 **/
+			evtEnable = 'enable.'+fm.namespace,
+			
+			c = 'class',
+			/**
+			 * File css class
+			 *
+			 * @type String
+			 **/
+			clFile       = fm.res(c, 'cwdfile'),
+			
+			/**
+			 * Selected css class
+			 *
+			 * @type String
+			 **/
+			fileSelector = '.'+clFile,
+			
+			/**
+			 * Selected css class
+			 *
+			 * @type String
+			 **/
+			clSelected = 'ui-selected',
+			
+			/**
+			 * Disabled css class
+			 *
+			 * @type String
+			 **/
+			clDisabled = fm.res(c, 'disabled'),
+			
+			/**
+			 * Draggable css class
+			 *
+			 * @type String
+			 **/
+			clDraggable = fm.res(c, 'draggable'),
+			
+			/**
+			 * Droppable css class
+			 *
+			 * @type String
+			 **/
+			clDroppable = fm.res(c, 'droppable'),
+			
+			/**
+			 * Hover css class
+			 *
+			 * @type String
+			 **/
+			clHover     = fm.res(c, 'hover'), 
+
+			/**
+			 * Hover css class
+			 *
+			 * @type String
+			 **/
+			clDropActive = fm.res(c, 'adroppable'),
+
+			/**
+			 * Css class for temporary nodes (for mkdir/mkfile) commands
+			 *
+			 * @type String
+			 **/
+			clTmp = clFile+'-tmp',
+
+			/**
+			 * Number of thumbnails to load in one request (new api only)
+			 *
+			 * @type Number
+			 **/
+			tmbNum = fm.options.loadTmbs > 0 ? fm.options.loadTmbs : 5,
+			
+			/**
+			 * Current search query.
+			 *
+			 * @type String
+			 */
+			query = '',
+			
+			lastSearch = [],
+
+			/**
+			 * File templates
+			 *
+			 * @type Object
+			 **/
+			templates = {
+				icon : '<div id="{hash}" class="'+clFile+' {permsclass} {dirclass} ui-corner-all" title="{tooltip}"><div class="elfinder-cwd-file-wrapper ui-corner-all"><div class="elfinder-cwd-icon {mime} ui-corner-all" unselectable="on" {style}/>{marker}</div><div class="elfinder-cwd-filename" title="{name}">{name}</div></div>',
+				row  : '<tr id="{hash}" class="'+clFile+' {permsclass} {dirclass}" title="{tooltip}"><td><div class="elfinder-cwd-file-wrapper"><span class="elfinder-cwd-icon {mime}"/>{marker}<span class="elfinder-cwd-filename">{name}</span></div></td><td>{perms}</td><td>{date}</td><td>{size}</td><td>{kind}</td></tr>'
+			},
+			
+			permsTpl = fm.res('tpl', 'perms'),
+			
+			symlinkTpl = fm.res('tpl', 'symlink'),
+			
+			/**
+			 * Template placeholders replacement rules
+			 *
+			 * @type Object
+			 **/
+			replacement = {
+				permsclass : function(f) {
+					return fm.perms2class(f);
+				},
+				perms : function(f) {
+					return fm.formatPermissions(f);
+				},
+				dirclass : function(f) {
+					return f.mime == 'directory' ? 'directory' : '';
+				},
+				mime : function(f) {
+					return fm.mime2class(f.mime);
+				},
+				size : function(f) {
+					return fm.formatSize(f.size);
+				},
+				date : function(f) {
+					return fm.formatDate(f);
+				},
+				kind : function(f) {
+					return fm.mime2kind(f);
+				},
+				marker : function(f) {
+					return (f.alias || f.mime == 'symlink-broken' ? symlinkTpl : '')+(!f.read || !f.write ? permsTpl : '');
+				},
+				tooltip : function(f) {
+					var title = fm.formatDate(f) + (f.size > 0 ? ' ('+fm.formatSize(f.size)+')' : '');
+					return f.tooltip? fm.escape(f.tooltip).replace(/"/g, '&quot;').replace(/\r/g, '&#13;') + '&#13;' + title : title;
+				}
+			},
+			
+			/**
+			 * Return file html
+			 *
+			 * @param  Object  file info
+			 * @return String
+			 **/
+			itemhtml = function(f) {
+				f.name = fm.escape(f.name);
+				return templates[list ? 'row' : 'icon']
+						.replace(/\{([a-z]+)\}/g, function(s, e) { 
+							return replacement[e] ? replacement[e](f) : (f[e] ? f[e] : ''); 
+						});
+			},
+			
+			/**
+			 * Flag. Required for msie to avoid unselect files on dragstart
+			 *
+			 * @type Boolean
+			 **/
+			selectLock = false,
+			
+			/**
+			 * Move selection to prev/next file
+			 *
+			 * @param String  move direction
+			 * @param Boolean append to current selection
+			 * @return void
+			 * @rise select			
+			 */
+			select = function(keyCode, append) {
+				var code     = $.ui.keyCode,
+					prev     = keyCode == code.LEFT || keyCode == code.UP,
+					sel      = cwd.find('[id].'+clSelected),
+					selector = prev ? 'first:' : 'last',
+					s, n, sib, top, left;
+
+				function sibling(n, direction) {
+					return n[direction+'All']('[id]:not(.'+clDisabled+'):not(.elfinder-cwd-parent):first');
+				}
+				
+				if (sel.length) {
+					s = sel.filter(prev ? ':first' : ':last');
+					sib = sibling(s, prev ? 'prev' : 'next');
+					
+					if (!sib.length) {
+						// there is no sibling on required side - do not move selection
+						n = s;
+					} else if (list || keyCode == code.LEFT || keyCode == code.RIGHT) {
+						// find real prevoius file
+						n = sib;
+					} else {
+						// find up/down side file in icons view
+						top = s.position().top;
+						left = s.position().left;
+
+						n = s;
+						if (prev) {
+							do {
+								n = n.prev('[id]');
+							} while (n.length && !(n.position().top < top && n.position().left <= left));
+
+							if (n.is('.'+clDisabled)) {
+								n = sibling(n, 'next');
+							}
+						} else {
+							do {
+								n = n.next('[id]');
+							} while (n.length && !(n.position().top > top && n.position().left >= left));
+							
+							if (n.is('.'+clDisabled)) {
+								n = sibling(n, 'prev');
+							}
+							// there is row before last one - select last file
+							if (!n.length) {
+								sib = cwd.find('[id]:not(.'+clDisabled+'):last');
+								if (sib.position().top > top) {
+									n = sib;
+								}
+							}
+						}
+					}
+					// !append && unselectAll();
+				} else {
+					// there are no selected file - select first/last one
+					n = cwd.find('[id]:not(.'+clDisabled+'):not(.elfinder-cwd-parent):'+(prev ? 'last' : 'first'));
+				}
+				
+				if (n && n.length && !n.is('.elfinder-cwd-parent')) {
+					if (append) {
+						// append new files to selected
+						n = s.add(s[prev ? 'prevUntil' : 'nextUntil']('#'+n.attr('id'))).add(n);
+					} else {
+						// unselect selected files
+						sel.trigger(evtUnselect);
+					}
+					// select file(s)
+					n.trigger(evtSelect);
+					// set its visible
+					scrollToView(n.filter(prev ? ':first' : ':last'));
+					// update cache/view
+					trigger();
+				}
+			},
+			
+			selectedFiles = [],
+			
+			selectFile = function(hash) {
+				cwd.find('#'+hash).trigger(evtSelect);
+			},
+			
+			selectAll = function() {
+				var phash = fm.cwd().hash;
+
+				cwd.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').trigger(evtSelect); 
+				selectedFiles = $.map(fm.files(), function(f) { return f.phash == phash ? f.hash : null ;});
+				trigger();
+			},
+			
+			/**
+			 * Unselect all files
+			 *
+			 * @return void
+			 */
+			unselectAll = function() {
+				selectedFiles = [];
+				cwd.find('[id].'+clSelected).trigger(evtUnselect); 
+				trigger();
+			},
+			
+			/**
+			 * Return selected files hashes list
+			 *
+			 * @return Array
+			 */
+			selected = function() {
+				return selectedFiles;
+			},
+			
+			/**
+			 * Fire elfinder "select" event and pass selected files to it
+			 *
+			 * @return void
+			 */
+			trigger = function() {
+				fm.trigger('select', {selected : selectedFiles});
+			},
+			
+			/**
+			 * Scroll file to set it visible
+			 *
+			 * @param DOMElement  file/dir node
+			 * @return void
+			 */
+			scrollToView = function(o) {
+				var ftop    = o.position().top,
+					fheight = o.outerHeight(true),
+					wtop    = wrapper.scrollTop(),
+					wheight = wrapper.innerHeight();
+
+				if (ftop + fheight > wtop + wheight) {
+					wrapper.scrollTop(parseInt(ftop + fheight - wheight));
+				} else if (ftop < wtop) {
+					wrapper.scrollTop(ftop);
+				}
+			},
+			
+			/**
+			 * Files we get from server but not show yet
+			 *
+			 * @type Array
+			 **/
+			buffer = [],
+			
+			/**
+			 * Return index of elements with required hash in buffer 
+			 *
+			 * @param String  file hash
+			 * @return Number
+			 */
+			index = function(hash) {
+				var l = buffer.length;
+				
+				while (l--) {
+					if (buffer[l].hash == hash) {
+						return l;
+					}
+				}
+				return -1;
+			},
+			
+			/**
+			 * Scroll event name
+			 *
+			 * @type String
+			 **/
+			scrollEvent = 'scroll.'+fm.namespace,
+
+			/**
+			 * Cwd scroll event handler.
+			 * Lazy load - append to cwd not shown files
+			 *
+			 * @return void
+			 */
+			render = function() {
+				var html  = [],  
+					dirs  = false, 
+					ltmb  = [],
+					atmb  = {},
+					last  = cwd.find('[id]:last'),
+					top   = !last.length,
+					place = list ? cwd.children('table').children('tbody') : cwd,
+					files;
+
+				if (!buffer.length) {
+					return wrapper.unbind(scrollEvent);
+				}
+				
+				while ((!last.length || last.position().top <= wrapper.height() + wrapper.scrollTop() + fm.options.showThreshold)
+					&& (files = buffer.splice(0, fm.options.showFiles)).length) {
+					
+					html = $.map(files, function(f) {
+						if (f.hash && f.name) {
+							if (f.mime == 'directory') {
+								dirs = true;
+							}
+							if (f.tmb) {
+								f.tmb === 1 ? ltmb.push(f.hash) : (atmb[f.hash] = f.tmb);
+							} 
+							return itemhtml(f);
+						}
+						return null;
+					});
+
+					place.append(html.join(''));
+					last = cwd.find('[id]:last');
+					// scroll top on dir load to avoid scroll after page reload
+					top && cwd.scrollTop(0);
+					
+				}
+
+				// load/attach thumbnails
+				attachThumbnails(atmb);
+				ltmb.length && loadThumbnails(ltmb);
+
+				// make directory droppable
+				dirs && makeDroppable();
+				
+				if (selectedFiles.length) {
+					place.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').each(function() {
+						var id = this.id;
+						
+						$.inArray(id, selectedFiles) !== -1 && $(this).trigger(evtSelect);
+					});
+				}
+				
+			},
+			
+			/**
+			 * Droppable options for cwd.
+			 * Do not add class on childs file over
+			 *
+			 * @type Object
+			 */
+			droppable = $.extend({}, fm.droppable, {
+				over : function(e, ui) { 
+					var hash = fm.cwd().hash;
+					$.each(ui.helper.data('files'), function(i, h) {
+						if (fm.file(h).phash == hash) {
+							cwd.removeClass(clDropActive);
+							return false;
+						}
+					});
+				}
+			}),
+			
+			/**
+			 * Make directory droppable
+			 *
+			 * @return void
+			 */
+			makeDroppable = function() {
+				setTimeout(function() {
+					cwd.find('.directory:not(.'+clDroppable+',.elfinder-na,.elfinder-ro)').droppable(fm.droppable);
+				}, 20);
+			},
+			
+			/**
+			 * Preload required thumbnails and on load add css to files.
+			 * Return false if required file is not visible yet (in buffer) -
+			 * required for old api to stop loading thumbnails.
+			 *
+			 * @param  Object  file hash -> thumbnail map
+			 * @return Boolean
+			 */
+			attachThumbnails = function(images) {
+				var url = fm.option('tmbUrl'),
+					ret = true, 
+					ndx;
+				
+				$.each(images, function(hash, tmb) {
+					var node = cwd.find('#'+hash);
+
+					if (node.length) {
+
+						(function(node, tmb) {
+							$('<img/>')
+								.load(function() { node.find('.elfinder-cwd-icon').css('background', "url('"+tmb+"') center center no-repeat"); })
+								.attr('src', tmb);
+						})(node, url+tmb);
+					} else {
+						ret = false;
+						if ((ndx = index(hash)) != -1) {
+							buffer[ndx].tmb = tmb;
+						}
+					}
+				});
+				return ret;
+			},
+			
+			/**
+			 * Load thumbnails from backend.
+			 *
+			 * @param  Array|Boolean  files hashes list for new api | true for old api
+			 * @return void
+			 */
+			loadThumbnails = function(files) {
+				var tmbs = [];
+				
+				if (fm.oldAPI) {
+					fm.request({
+						data : {cmd : 'tmb', current : fm.cwd().hash},
+						preventFail : true
+						})
+						.done(function(data) {
+							if (attachThumbnails(data.images||[]) && data.tmb) {
+								loadThumbnails();
+							}
+						});
+					return;
+				} 
+
+				tmbs = tmbs = files.splice(0, tmbNum);
+				if (tmbs.length) {
+					fm.request({
+						data : {cmd : 'tmb', targets : tmbs},
+						preventFail : true
+					})
+					.done(function(data) {
+						if (attachThumbnails(data.images||[])) {
+							loadThumbnails(files);
+						}
+					});
+				}
+			},
+			
+			/**
+			 * Add new files to cwd/buffer
+			 *
+			 * @param  Array  new files
+			 * @return void
+			 */
+			add = function(files) {
+				var place    = list ? cwd.find('tbody') : cwd,
+					l        = files.length, 
+					ltmb     = [],
+					atmb     = {},
+					dirs     = false,
+					findNode = function(file) {
+						var pointer = cwd.find('[id]:first'), file2;
+
+						while (pointer.length) {
+							file2 = fm.file(pointer.attr('id'));
+							if (!pointer.is('.elfinder-cwd-parent') && file2 && fm.compare(file, file2) < 0) {
+								return pointer;
+							}
+							pointer = pointer.next('[id]');
+						}
+					},
+					findIndex = function(file) {
+						var l = buffer.length, i;
+						
+						for (i =0; i < l; i++) {
+							if (fm.compare(file, buffer[i]) < 0) {
+								return i;
+							}
+						}
+						return l || -1;
+					},
+					file, hash, node, ndx;
+
+				
+				while (l--) {
+					file = files[l];
+					hash = file.hash;
+					
+					if (cwd.find('#'+hash).length) {
+						continue;
+					}
+					
+					if ((node = findNode(file)) && node.length) {
+						node.before(itemhtml(file)); 
+					} else if ((ndx = findIndex(file)) >= 0) {
+						buffer.splice(ndx, 0, file);
+					} else {
+						place.append(itemhtml(file));
+					}
+					
+					if (cwd.find('#'+hash).length) {
+						if (file.mime == 'directory') {
+							dirs = true;
+						} else if (file.tmb) {
+							file.tmb === 1 ? ltmb.push(hash) : (atmb[hash] = file.tmb);
+						}
+					}
+				}
+				
+				attachThumbnails(atmb);
+				ltmb.length && loadThumbnails(ltmb);
+				dirs && makeDroppable();
+			},
+			
+			/**
+			 * Remove files from cwd/buffer
+			 *
+			 * @param  Array  files hashes
+			 * @return void
+			 */
+			remove = function(files) {
+				var l = files.length, hash, n, ndx;
+				
+				while (l--) {
+					hash = files[l];
+					if ((n = cwd.find('#'+hash)).length) {
+						try {
+							n.detach();
+						} catch(e) {
+							fm.debug('error', e);
+						}
+					} else if ((ndx = index(hash)) != -1) {
+						buffer.splice(ndx, 1);
+					}
+				}
+			},
+			
+			msg = {
+				name : fm.i18n('name'),
+				perm : fm.i18n('perms'),
+				mod  : fm.i18n('modify'),
+				size : fm.i18n('size'),
+				kind : fm.i18n('kind')
+			},
+			
+			/**
+			 * Update directory content
+			 *
+			 * @param  Array  files
+			 * @return void
+			 */
+			content = function(files, any) {
+				var phash = fm.cwd().hash; 
+				// console.log(files)
+				
+				unselectAll();
+				
+				try {
+					// to avoid problem with draggable
+					cwd.children('table,'+fileSelector).remove();
+				} catch (e) {
+					cwd.html('');
+				}
+
+				cwd.removeClass('elfinder-cwd-view-icons elfinder-cwd-view-list')
+					.addClass('elfinder-cwd-view-'+(list ? 'list' :'icons'));
+
+				wrapper[list ? 'addClass' : 'removeClass']('elfinder-cwd-wrapper-list');
+
+				list && cwd.html('<table><thead><tr class="ui-state-default"><td >'+msg.name+'</td><td>'+msg.perm+'</td><td>'+msg.mod+'</td><td>'+msg.size+'</td><td>'+msg.kind+'</td></tr></thead><tbody/></table>');
+		
+				buffer = $.map(files, function(f) { return any || f.phash == phash ? f : null; });
+				
+				buffer = fm.sortFiles(buffer);
+		
+				wrapper.bind(scrollEvent, render).trigger(scrollEvent);
+		
+				phash = fm.cwd().phash;
+				
+				if (options.oldSchool && phash && !query) {
+					var parent = $.extend(true, {}, fm.file(phash), {name : '..', mime : 'directory'});
+					parent = $(itemhtml(parent))
+						.addClass('elfinder-cwd-parent')
+						.bind('mousedown click mouseup touchstart touchmove touchend dblclick mouseenter', function(e) {
+						//.bind('mousedown click mouseup dblclick mouseenter', function(e) {
+							e.preventDefault();
+							e.stopPropagation();
+						})
+						.dblclick(function() {
+							fm.exec('open', this.id);
+						});
+
+					(list ? cwd.find('tbody') : cwd).prepend(parent);
+				}
+				
+			},
+			
+			/**
+			 * CWD node itself
+			 *
+			 * @type JQuery
+			 **/
+			cwd = $(this)
+				.addClass('ui-helper-clearfix elfinder-cwd')
+				.attr('unselectable', 'on')
+				// fix ui.selectable bugs and add shift+click support 
+				.delegate(fileSelector, 'click.'+fm.namespace, function(e) {
+					var p    = this.id ? $(this) : $(this).parents('[id]:first'), 
+						prev = p.prevAll('.'+clSelected+':first'),
+						next = p.nextAll('.'+clSelected+':first'),
+						pl   = prev.length,
+						nl   = next.length,
+						sib;
+
+					e.stopImmediatePropagation();
+
+					if (e.shiftKey && (pl || nl)) {
+						sib = pl ? p.prevUntil('#'+prev.attr('id')) : p.nextUntil('#'+next.attr('id'));
+						sib.add(p).trigger(evtSelect);
+					} else if (e.ctrlKey || e.metaKey) {
+						p.trigger(p.is('.'+clSelected) ? evtUnselect : evtSelect);
+					} else {
+						if ($(this).data('touching') && p.is('.'+clSelected)) {
+							$(this).data('touching', null);
+							fm.dblclick({file : this.id});
+							unselectAll();
+						} else {
+							unselectAll();
+							p.trigger(evtSelect);
+						}
+					}
+
+					trigger();
+				})
+				// call fm.open()
+				.delegate(fileSelector, 'dblclick.'+fm.namespace, function(e) {
+					fm.dblclick({file : this.id});
+				})
+				// for touch device
+				.delegate(fileSelector, 'touchstart.'+fm.namespace, function(e) {
+					$(this).data('touching', true);
+					var p = this.id ? $(this) : $(this).parents('[id]:first'),
+					  sel = p.prevAll('.'+clSelected+':first').length +
+					        p.nextAll('.'+clSelected+':first').length;
+					$(this).data('longtap', setTimeout(function(){
+						// long tap
+						p.trigger(p.is('.'+clSelected) ? evtUnselect : evtSelect);
+						trigger();
+						if (sel == 0 && p.is('.'+clSelected)) {
+							p.trigger('click');
+							trigger();
+						} 
+					}, 500));
+				})
+				.delegate(fileSelector, 'touchmove.'+fm.namespace+' touchend.'+fm.namespace, function(e) {
+					clearTimeout($(this).data('longtap'));
+				})
+				// attach draggable
+				.delegate(fileSelector, 'mouseenter.'+fm.namespace, function(e) {
+					var $this = $(this),
+						target = list ? $this : $this.children();
+
+					if (!$this.is('.'+clTmp) && !target.is('.'+clDraggable+',.'+clDisabled)) {
+						target.draggable(fm.draggable);
+					}
+				})
+				// add hover class to selected file
+				.delegate(fileSelector, evtSelect, function(e) {
+					var $this = $(this), 
+						id    = $this.attr('id');
+					
+					if (!selectLock && !$this.is('.'+clDisabled)) {
+						$this.addClass(clSelected).children().addClass(clHover);
+						if ($.inArray(id, selectedFiles) === -1) {
+							selectedFiles.push(id);
+						}
+					}
+				})
+				// remove hover class from unselected file
+				.delegate(fileSelector, evtUnselect, function(e) {
+					var $this = $(this), 
+						id    = $this.attr('id'),
+						ndx;
+					
+					if (!selectLock) {
+						$(this).removeClass(clSelected).children().removeClass(clHover);
+						ndx = $.inArray(id, selectedFiles);
+						if (ndx !== -1) {
+							selectedFiles.splice(ndx, 1);
+						}
+					}
+					
+				})
+				// disable files wich removing or moving
+				.delegate(fileSelector, evtDisable, function() {
+					var $this  = $(this).removeClass(clSelected).addClass(clDisabled), 
+						target = (list ? $this : $this.children()).removeClass(clHover);
+					
+					$this.is('.'+clDroppable) && $this.droppable('disable');
+					target.is('.'+clDraggable) && target.draggable('disable');
+					!list && target.removeClass(clDisabled);
+				})
+				// if any files was not removed/moved - unlock its
+				.delegate(fileSelector, evtEnable, function() {
+					var $this  = $(this).removeClass(clDisabled), 
+						target = list ? $this : $this.children();
+					
+					$this.is('.'+clDroppable) && $this.droppable('enable');	
+					target.is('.'+clDraggable) && target.draggable('enable');
+				})
+				.delegate(fileSelector, 'scrolltoview', function() {
+					scrollToView($(this));
+				})
+				.delegate(fileSelector, 'hover', function(e) {
+					fm.trigger('hover', {hash : $(this).attr('id'), type : e.type});
+				})
+				.bind('contextmenu.'+fm.namespace, function(e) {
+					var file = $(e.target).closest('.'+clFile);
+					
+					if (file.length) {
+						e.stopPropagation();
+						e.preventDefault();
+						if (!file.is('.'+clDisabled)) {
+							if (!file.is('.'+clSelected)) {
+								// cwd.trigger('unselectall');
+								unselectAll();
+								file.trigger(evtSelect);
+								trigger();
+							}
+							fm.trigger('contextmenu', {
+								'type'    : 'files',
+								'targets' : fm.selected(),
+								'x'       : e.clientX,
+								'y'       : e.clientY
+							});
+
+						}
+						
+					}
+					// e.preventDefault();
+					
+					
+				})
+				
+				// make files selectable
+				.selectable({
+					filter     : fileSelector,
+					stop       : trigger,
+					selected   : function(e, ui) { $(ui.selected).trigger(evtSelect); },
+					unselected : function(e, ui) { $(ui.unselected).trigger(evtUnselect); }
+				})
+				// make cwd itself droppable for folders from nav panel
+				.droppable(droppable)
+				// prepend fake file/dir
+				.bind('create.'+fm.namespace, function(e, file) {
+					var parent = list ? cwd.find('tbody') : cwd,
+						p = parent.find('.elfinder-cwd-parent'),
+						file = $(itemhtml(file)).addClass(clTmp);
+						
+					unselectAll();
+
+					if (p.length) {
+						p.after(file);
+					} else {
+						parent.prepend(file);
+					}
+					
+					cwd.scrollTop(0);
+				})
+				// unselect all selected files
+				.bind('unselectall', unselectAll)
+				.bind('selectfile', function(e, id) {
+					cwd.find('#'+id).trigger(evtSelect);
+					trigger();
+				}),
+			wrapper = $('<div class="elfinder-cwd-wrapper"/>')
+				.bind('contextmenu', function(e) {
+					e.preventDefault();
+					fm.trigger('contextmenu', {
+						'type'    : 'cwd',
+						'targets' : [fm.cwd().hash],
+						'x'       : e.clientX,
+						'y'       : e.clientY
+					});
+					
+				}),
+			
+			resize = function() {
+				var h = 0;
+
+				wrapper.siblings('.elfinder-panel:visible').each(function() {
+					h += $(this).outerHeight(true);
+				});
+
+				wrapper.height(wz.height() - h);
+			},
+			
+			// elfinder node
+			parent = $(this).parent().resize(resize),
+			// workzone node
+			wz = parent.children('.elfinder-workzone').append(wrapper.append(this))
+			;
+			
+		
+		if (fm.dragUpload) {
+			wrapper[0].addEventListener('dragenter', function(e) {
+				e.preventDefault();
+				e.stopPropagation();
+				
+				wrapper.addClass(clDropActive);
+			}, false);
+
+			wrapper[0].addEventListener('dragleave', function(e) {
+				e.preventDefault();
+				e.stopPropagation();
+				e.target == cwd[0] && wrapper.removeClass(clDropActive);
+			}, false);
+
+			wrapper[0].addEventListener('dragover', function(e) {
+				e.preventDefault();
+				e.stopPropagation();
+			}, false);
+
+			wrapper[0].addEventListener('drop', function(e) {
+			  	e.preventDefault();
+				wrapper.removeClass(clDropActive);
+				var file = false;
+				var type = '';
+				if (e.dataTransfer.getData('text/html')) {
+					file = [ e.dataTransfer.getData('text/html') ];
+					type = 'html';
+				} else if (e.dataTransfer.getData('text')) {
+					file = [ e.dataTransfer.getData('text') ];
+					type = 'text';
+				} else if (e.dataTransfer && e.dataTransfer.items &&  e.dataTransfer.items.length) {
+					file = e.dataTransfer;
+					type = 'data';
+				} else if (e.dataTransfer && e.dataTransfer.files &&  e.dataTransfer.files.length) {
+					file = e.dataTransfer.files;
+					type = 'files';
+				}
+				if (file) {
+					fm.exec('upload', {files : file, type : type});
+				}
+			}, false);
+		}
+
+		fm
+			.bind('open', function(e) {
+				content(e.data.files);
+			})
+			.bind('search', function(e) {
+				lastSearch = e.data.files;
+				content(lastSearch, true);
+			})
+			.bind('searchend', function() {
+				lastSearch = [];
+				if (query) {
+					query = '';
+					content(fm.files());
+				}
+			})
+			.bind('searchstart', function(e) {
+				query = e.data.query;
+			})
+			.bind('sortchange', function() {
+				content(query ? lastSearch : fm.files(), !!query);
+			})
+			.bind('viewchange', function() {
+				var sel = fm.selected(),
+					l   = fm.storage('view') == 'list';
+				
+				if (l != list) {
+					list = l;
+					content(fm.files());
+
+					$.each(sel, function(i, h) {
+						selectFile(h);
+					});
+					trigger();
+				}
+				resize();
+			})
+			.add(function(e) {
+				var phash = fm.cwd().hash,
+					files = query
+						? $.map(e.data.added || [], function(f) { return f.name.indexOf(query) === -1 ? null : f ;})
+						: $.map(e.data.added || [], function(f) { return f.phash == phash ? f : null; })
+						;
+				add(files);
+			})
+			.change(function(e) {
+				var phash = fm.cwd().hash,
+					sel   = fm.selected(),
+					files;
+
+				if (query) {
+					$.each(e.data.changed || [], function(i, file) {
+						remove([file.hash]);
+						if (file.name.indexOf(query) !== -1) {
+							add([file]);
+							$.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
+						}
+					});
+				} else {
+					$.each($.map(e.data.changed || [], function(f) { return f.phash == phash ? f : null; }), function(i, file) {
+						remove([file.hash]);
+						add([file]);
+						$.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
+					});
+				}
+				
+				trigger();
+			})
+			.remove(function(e) {
+				remove(e.data.removed || []);
+				trigger();
+			})
+			// fix cwd height if it less then wrapper
+			.bind('open add search searchend', function() {
+				cwd.css('height', 'auto');
+
+				if (cwd.outerHeight(true) < wrapper.height()) {
+					cwd.height(wrapper.height() - (cwd.outerHeight(true) - cwd.height()) - 2);
+				} 
+			})
+			// select dragged file if no selected, disable selectable
+			.dragstart(function(e) {
+				var target = $(e.data.target),
+					oe     = e.data.originalEvent;
+
+				if (target.is(fileSelector)) {
+					
+					if (!target.is('.'+clSelected)) {
+						!(oe.ctrlKey || oe.metaKey || oe.shiftKey) && unselectAll();
+						target.trigger(evtSelect);
+						trigger();
+					}
+					cwd.droppable('disable');
+				}
+				
+				cwd.selectable('disable').removeClass(clDisabled);
+				selectLock = true;
+			})
+			// enable selectable
+			.dragstop(function() {
+				cwd.selectable('enable').droppable('enable');
+				selectLock = false;
+			})
+			.bind('lockfiles unlockfiles', function(e) {
+				var event = e.type == 'lockfiles' ? evtDisable : evtEnable,
+					files = e.data.files || [], 
+					l     = files.length;
+				
+				while (l--) {
+					cwd.find('#'+files[l]).trigger(event);
+				}
+				trigger();
+			})
+			// select new files after some actions
+			.bind('mkdir mkfile duplicate upload rename archive extract', function(e) {
+				var phash = fm.cwd().hash, files;
+				
+				unselectAll();
+
+				$.each(e.data.added || [], function(i, file) { 
+					file && file.phash == phash && selectFile(file.hash);
+				});
+				trigger();
+			})
+			.shortcut({
+				pattern     :'ctrl+a', 
+				description : 'selectall',
+				callback    : selectAll
+			})
+			.shortcut({
+				pattern     : 'left right up down shift+left shift+right shift+up shift+down',
+				description : 'selectfiles',
+				type        : 'keydown' , //fm.UA.Firefox || fm.UA.Opera ? 'keypress' : 'keydown',
+				callback    : function(e) { select(e.keyCode, e.shiftKey); }
+			})
+			.shortcut({
+				pattern     : 'home',
+				description : 'selectffile',
+				callback    : function(e) { 
+					unselectAll();
+					scrollToView(cwd.find('[id]:first').trigger(evtSelect));
+					trigger();
+				}
+			})
+			.shortcut({
+				pattern     : 'end',
+				description : 'selectlfile',
+				callback    : function(e) { 
+					unselectAll();
+					scrollToView(cwd.find('[id]:last').trigger(evtSelect)) ;
+					trigger();
+				}
+			});
+		
+	});
+	
+	// fm.timeEnd('cwdLoad')
+	
+	return this;
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/dialog.js
+ */
+
+/**
+ * @class  elFinder dialog
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderdialog = function(opts) {
+	var dialog;
+	
+	if (typeof(opts) == 'string' && (dialog = this.closest('.ui-dialog')).length) {
+		if (opts == 'open') {
+			dialog.css('display') == 'none' && dialog.fadeIn(120, function() {
+				dialog.trigger('open');
+			});
+		} else if (opts == 'close') {
+			dialog.css('display') != 'none' && dialog.hide().trigger('close');
+		} else if (opts == 'destroy') {
+			dialog.hide().remove();
+		} else if (opts == 'toTop') {
+			dialog.trigger('totop');
+		}
+	}
+	
+	opts = $.extend({}, $.fn.elfinderdialog.defaults, opts);
+
+	this.filter(':not(.ui-dialog-content)').each(function() {
+		var self       = $(this).addClass('ui-dialog-content ui-widget-content'),
+			parent     = self.parent(),
+			clactive   = 'elfinder-dialog-active',
+			cldialog   = 'elfinder-dialog',
+			clnotify   = 'elfinder-dialog-notify',
+			clhover    = 'ui-state-hover',
+			id         = parseInt(Math.random()*1000000),
+			overlay    = parent.children('.elfinder-overlay'),
+			buttonset  = $('<div class="ui-dialog-buttonset"/>'),
+			buttonpane = $('<div class=" ui-helper-clearfix ui-dialog-buttonpane ui-widget-content"/>')
+				.append(buttonset),
+			
+			dialog = $('<div class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable std42-dialog  '+cldialog+' '+opts.cssClass+'"/>')
+				.hide()
+				.append(self)
+				.appendTo(parent)
+				.draggable({ handle : '.ui-dialog-titlebar',
+					     containment : 'document' })
+				.css({
+					width  : opts.width,
+					height : opts.height
+				})
+				.mousedown(function(e) {
+					e.stopPropagation();
+					
+					$(document).mousedown();
+
+					if (!dialog.is('.'+clactive)) {
+						parent.find('.'+cldialog+':visible').removeClass(clactive);
+						dialog.addClass(clactive).zIndex(maxZIndex() + 1);
+					}
+				})
+				.bind('open', function() {
+					dialog.trigger('totop');
+					typeof(opts.open) == 'function' && $.proxy(opts.open, self[0])();
+
+					if (!dialog.is('.'+clnotify)) {
+						
+						parent.find('.'+cldialog+':visible').not('.'+clnotify).each(function() {
+							var d     = $(this),
+								top   = parseInt(d.css('top')),
+								left  = parseInt(d.css('left')),
+								_top  = parseInt(dialog.css('top')),
+								_left = parseInt(dialog.css('left'))
+								;
+
+							if (d[0] != dialog[0] && (top == _top || left == _left)) {
+								dialog.css({
+									top  : (top+10)+'px',
+									left : (left+10)+'px'
+								});
+							}
+						});
+					} 
+				})
+				.bind('close', function() {
+					var dialogs = parent.find('.elfinder-dialog:visible'),
+						z = maxZIndex();
+					
+					$(this).data('modal') && overlay.elfinderoverlay('hide');
+					
+					// get focus to next dialog
+					if (dialogs.length) {
+						dialogs.each(function() {
+							var d = $(this);
+							if (d.zIndex() >= z) {
+								d.trigger('totop');
+								return false;
+							}
+						})
+					} else {
+						// return focus to parent
+						setTimeout(function() {
+							parent.mousedown().click();
+						}, 10);
+						
+					}
+					
+					if (typeof(opts.close) == 'function') {
+						$.proxy(opts.close, self[0])();
+					} else if (opts.destroyOnClose) {
+						dialog.hide().remove();
+					}
+				})
+				.bind('totop', function() {
+					$(this).mousedown().find('.ui-button:first').focus().end().find(':text:first').focus();
+					$(this).data('modal') && overlay.elfinderoverlay('show');
+					overlay.zIndex($(this).zIndex());
+				})
+				.data({modal: opts.modal}),
+				maxZIndex = function() {
+					var z = parent.zIndex() + 10;
+					parent.find('.'+cldialog+':visible').each(function() {
+						var _z;
+						if (this != dialog[0]) {
+							_z = $(this).zIndex();
+							if (_z > z) {
+								z = _z;
+							}
+						}
+					})
+					return z;
+				},
+				top
+			;
+		
+		if (!opts.position) {
+			top = parseInt((parent.height() - dialog.outerHeight())/2 - 42);
+			opts.position = {
+				top  : (top > 0 ? top : 0)+'px',
+				left : parseInt((parent.width() - dialog.outerWidth())/2)+'px'
+			}
+		} 
+			
+		dialog.css(opts.position);
+
+		if (opts.closeOnEscape) {
+			$(document).bind('keyup.'+id, function(e) {
+				if (e.keyCode == $.ui.keyCode.ESCAPE && dialog.is('.'+clactive)) {
+					self.elfinderdialog('close');
+					$(document).unbind('keyup.'+id);
+				}
+			})
+		}
+		dialog.prepend(
+			$('<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">'+opts.title+'</div>')
+				.prepend($('<a href="#" class="ui-dialog-titlebar-close ui-corner-all"><span class="ui-icon ui-icon-closethick"/></a>')
+					.mousedown(function(e) {
+						e.preventDefault();
+						self.elfinderdialog('close');
+					}))
+
+		);
+			
+		
+			
+		$.each(opts.buttons, function(name, cb) {
+			var button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+name+'</span></button>')
+				.click($.proxy(cb, self[0]))
+				.hover(function(e) { $(this)[e.type == 'mouseenter' ? 'focus' : 'blur']() })
+				.focus(function() { $(this).addClass(clhover) })
+				.blur(function() { $(this).removeClass(clhover) })
+				.keydown(function(e) { 
+					var next;
+					
+					if (e.keyCode == $.ui.keyCode.ENTER) {
+						$(this).click();
+					}  else if (e.keyCode == $.ui.keyCode.TAB) {
+						next = $(this).next('.ui-button');
+						next.length ? next.focus() : $(this).parent().children('.ui-button:first').focus()
+					}
+				})
+			buttonset.append(button);
+		})
+			
+		buttonset.children().length && dialog.append(buttonpane);
+		if (opts.resizable && $.fn.resizable) {
+			dialog.resizable({
+					minWidth   : opts.minWidth,
+					minHeight  : opts.minHeight,
+					alsoResize : this
+				});
+		} 
+			
+		typeof(opts.create) == 'function' && $.proxy(opts.create, this)();
+			
+		opts.autoOpen && self.elfinderdialog('open');
+
+	});
+	
+	return this;
+}
+
+$.fn.elfinderdialog.defaults = {
+	cssClass  : '',
+	title     : '',
+	modal     : false,
+	resizable : true,
+	autoOpen  : true,
+	closeOnEscape : true,
+	destroyOnClose : false,
+	buttons   : {},
+	position  : null,
+	width     : 320,
+	height    : 'auto',
+	minWidth  : 200,
+	minHeight : 110
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/navbar.js
+ */
+
+/**
+ * @class elfindernav - elFinder container for diretories tree and places
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindernavbar = function(fm, opts) {
+
+	this.not('.elfinder-navbar').each(function() {
+		var nav    = $(this).addClass('ui-state-default elfinder-navbar'),
+			parent = nav.parent()
+				.resize(function() {
+					nav.height(wz.height() - delta);
+				}),
+			wz     = parent.children('.elfinder-workzone').append(nav),
+			delta  = nav.outerHeight() - nav.height(),
+			ltr    = fm.direction == 'ltr',
+			handle;
+
+		
+		if ($.fn.resizable) {
+			handle = nav.resizable({
+					handles : ltr ? 'e' : 'w',
+					minWidth : opts.minWidth || 150,
+					maxWidth : opts.maxWidth || 500
+				})
+				.bind('resize scroll', function() {
+					var offset = (fm.UA.Opera && nav.scrollLeft())? 20 : 2;
+					handle.css({
+						top  : parseInt(nav.scrollTop())+'px',
+						left : ltr ? 'auto' : parseInt(nav.scrollLeft() + offset),
+						right: ltr ? parseInt(nav.scrollLeft() - offset) * -1 : 'auto'
+					});
+				})
+				.find('.ui-resizable-handle').zIndex(nav.zIndex() + 10);
+
+			if (!ltr) {
+				nav.resize(function() {
+					nav.css('left', null).css('right', 0);
+				});
+			}
+
+			fm.one('open', function() {
+				setTimeout(function() {
+					nav.trigger('resize');
+				}, 150);
+			});
+		}
+	});
+	
+	return this;
+};
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/overlay.js
+ */
+
+
+$.fn.elfinderoverlay = function(opts) {
+	
+	this.filter(':not(.elfinder-overlay)').each(function() {
+		opts = $.extend({}, opts);
+		$(this).addClass('ui-widget-overlay elfinder-overlay')
+			.hide()
+			.mousedown(function(e) {
+				e.preventDefault();
+				e.stopPropagation();
+			})
+			.data({
+				cnt  : 0,
+				show : typeof(opts.show) == 'function' ? opts.show : function() { },
+				hide : typeof(opts.hide) == 'function' ? opts.hide : function() { }
+			});
+	});
+	
+	if (opts == 'show') {
+		var o    = this.eq(0),
+			cnt  = o.data('cnt') + 1,
+			show = o.data('show');
+
+		o.data('cnt', cnt);
+
+		if (o.is(':hidden')) {
+			o.zIndex(o.parent().zIndex()+1);
+			o.show();
+			show();
+		}
+	} 
+	
+	if (opts == 'hide') {
+		var o    = this.eq(0),
+			cnt  = o.data('cnt') - 1,
+			hide = o.data('hide');
+		
+		o.data('cnt', cnt);
+			
+		if (cnt == 0 && o.is(':visible')) {
+			o.hide();
+			hide();        
+		}
+	}
+	
+	return this;
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/panel.js
+ */
+
+$.fn.elfinderpanel = function(fm) {
+	
+	return this.each(function() {
+		var panel = $(this).addClass('elfinder-panel ui-state-default ui-corner-all'),
+			margin = 'margin-'+(fm.direction == 'ltr' ? 'left' : 'right');
+		
+		fm.one('load', function(e) {
+			var navbar = fm.getUI('navbar');
+			
+			panel.css(margin, parseInt(navbar.outerWidth(true)));
+			navbar.bind('resize', function() {
+				panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true)))
+			})
+		})
+	})
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/path.js
+ */
+
+/**
+ * @class elFinder ui
+ * Display current folder path in statusbar.
+ * Click on folder name in path - open folder
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderpath = function(fm) {
+	return this.each(function() {
+		var path = $(this).addClass('elfinder-path').html('&nbsp;')
+				.delegate('a', 'click', function(e) {
+					var hash = $(this).attr('href').substr(1);
+
+					e.preventDefault();
+					hash != fm.cwd().hash && fm.exec('open', hash);
+				})
+				.prependTo(fm.getUI('statusbar').show())
+
+			fm.bind('open searchend', function() {
+				var dirs = [];
+
+				$.each(fm.parents(fm.cwd().hash), function(i, hash) {
+					dirs.push('<a href="#'+hash+'">'+fm.escape(fm.file(hash).name)+'</a>');
+				});
+
+				path.html(dirs.join(fm.option('separator')));
+			})
+			.bind('search', function() {
+				path.html(fm.i18n('searcresult'));
+			});
+	});
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/places.js
+ */
+
+/**
+ * @class elFinder places/favorites ui
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderplaces = function(fm, opts) {
+	return this.each(function() {
+		var dirs      = [],
+			c         = 'class',
+			navdir    = fm.res(c, 'navdir'),
+			collapsed = fm.res(c, 'navcollapse'),
+			expanded  = fm.res(c, 'navexpand'),
+			hover     = fm.res(c, 'hover'),
+			clroot    = fm.res(c, 'treeroot'),
+			tpl       = fm.res('tpl', 'navdir'),
+			ptpl      = fm.res('tpl', 'perms'),
+			spinner   = $(fm.res('tpl', 'navspinner')),
+			/**
+			 * Convert places dir node into dir hash
+			 *
+			 * @param  String  directory id
+			 * @return String
+			 **/
+			id2hash   = function(id) { return id.substr(6);	},
+			/**
+			 * Convert places dir node into dir hash
+			 *
+			 * @param  String  directory id
+			 * @return String
+			 **/
+			hash2id   = function(hash) { return 'place-'+hash; },
+			
+			/**
+			 * Save current places state
+			 *
+			 * @return void
+			 **/
+			save      = function() { fm.storage('places', dirs.join(',')); },
+			/**
+			 * Return node for given dir object
+			 *
+			 * @param  Object  directory object
+			 * @return jQuery
+			 **/
+			create    = function(dir) {
+				return $(tpl.replace(/\{id\}/, hash2id(dir.hash))
+						.replace(/\{name\}/, fm.escape(dir.name))
+						.replace(/\{cssclass\}/, fm.perms2class(dir))
+						.replace(/\{permissions\}/, !dir.read || !dir.write ? ptpl : '')
+						.replace(/\{symlink\}/, ''));
+			},
+			/**
+			 * Add new node into places
+			 *
+			 * @param  Object  directory object
+			 * @return void
+			 **/
+			add = function(dir) {
+				var node = create(dir);
+
+				if (subtree.children().length) {
+					$.each(subtree.children(), function() {
+						var current =  $(this);
+						
+						if (dir.name.localeCompare(current.children('.'+navdir).text()) < 0) {
+							return !node.insertBefore(current);
+						}
+					});
+				} 
+				
+				dirs.push(dir.hash);
+				!node.parent().length && subtree.append(node);
+				root.addClass(collapsed);
+				node.draggable({
+					appendTo : 'body',
+					revert   : false,
+					helper   : function() {
+						var dir = $(this);
+							
+						dir.children().removeClass('ui-state-hover');
+						
+						return $('<div class="elfinder-place-drag elfinder-'+fm.direction+'"/>')
+								.append(dir.clone())
+								.data('hash', id2hash(dir.children(':first').attr('id')));
+
+					},
+					start    : function() { $(this).hide(); },
+					stop     : function(e, ui) {
+						var top    = places.offset().top,
+							left   = places.offset().left,
+							width  = places.width(),
+							height = places.height(),
+							x      = e.clientX,
+							y      = e.clientY;
+						
+						if (x > left && x < left+width && y > top && y < y+height) {
+							$(this).show();
+						} else {
+							remove(ui.helper.data('hash'));
+							save();
+						}
+					}
+				});
+			}, 
+			/**
+			 * Remove dir from places
+			 *
+			 * @param  String  directory id
+			 * @return void
+			 **/
+			remove = function(hash) {
+				var ndx = $.inArray(hash, dirs);
+
+				if (ndx !== -1) {
+					dirs.splice(ndx, 1);
+					subtree.find('#'+hash2id(hash)).parent().remove();
+					!subtree.children().length && root.removeClass(collapsed+' '+expanded);
+				}
+			},
+			/**
+			 * Remove all dir from places
+			 *
+			 * @return void
+			 **/
+			clear = function() {
+				subtree.empty();
+				root.removeClass(collapsed+' '+expanded);
+			},
+			/**
+			 * Node - wrapper for places root
+			 *
+			 * @type jQuery
+			 **/
+			wrapper = create({
+					hash  : 'root-'+fm.namespace, 
+					name  : fm.i18n(opts.name, 'places'),
+					read  : true,
+					write : true
+				}),
+			/**
+			 * Places root node
+			 *
+			 * @type jQuery
+			 **/
+			root = wrapper.children('.'+navdir)
+				.addClass(clroot)
+				.click(function() {
+					if (root.is('.'+collapsed)) {
+						places.toggleClass(expanded);
+						subtree.slideToggle();
+						fm.storage('placesState', places.is('.'+expanded)? 1 : 0);
+					}
+				}),
+			/**
+			 * Container for dirs
+			 *
+			 * @type jQuery
+			 **/
+			subtree = wrapper.children('.'+fm.res(c, 'navsubtree')),
+			/**
+			 * Main places container
+			 *
+			 * @type jQuery
+			 **/
+			places = $(this).addClass(fm.res(c, 'tree')+' elfinder-places ui-corner-all')
+				.hide()
+				.append(wrapper)
+				.appendTo(fm.getUI('navbar'))
+				.delegate('.'+navdir, 'hover', function() {
+					$(this).toggleClass('ui-state-hover');
+				})
+				.delegate('.'+navdir, 'click', function(e) {
+					fm.exec('open', $(this).attr('id').substr(6));
+				})
+				.delegate('.'+navdir+':not(.'+clroot+')', 'contextmenu', function(e) {
+					var hash = $(this).attr('id').substr(6);
+					
+					e.preventDefault();
+					
+					fm.trigger('contextmenu', {
+						raw : [{
+							label    : fm.i18n('rmFromPlaces'),
+							icon     : 'rm',
+							callback : function() { remove(hash); save(); }
+						}],
+						'x'       : e.clientX,
+						'y'       : e.clientY
+					})
+					
+				})
+				.droppable({
+					tolerance  : 'pointer',
+					accept     : '.elfinder-cwd-file-wrapper,.elfinder-tree-dir,.elfinder-cwd-file',
+					hoverClass : fm.res('class', 'adroppable'),
+					drop       : function(e, ui) {
+						var resolve = true;
+						
+						$.each(ui.helper.data('files'), function(i, hash) {
+							var dir = fm.file(hash);
+							
+							if (dir && dir.mime == 'directory' && $.inArray(dir.hash, dirs) === -1) {
+								add(dir);
+							} else {
+								resolve = false;
+							}
+						})
+						save();
+						resolve && ui.helper.hide();
+					}
+				});
+	
+
+		// on fm load - show places and load files from backend
+		fm.one('load', function() {
+			if (fm.oldAPI) {
+				return;
+			}
+			
+			places.show().parent().show();
+
+			dirs = $.map(fm.storage('places').split(','), function(hash) { return hash || null});
+			
+			if (dirs.length) {
+				root.prepend(spinner);
+				
+				fm.request({
+					data : {cmd : 'info', targets : dirs},
+					preventDefault : true
+				})
+				.done(function(data) {
+					dirs = [];
+					$.each(data.files, function(i, file) {
+						file.mime == 'directory' && add(file);
+					});
+					save();
+					if (fm.storage('placesState') > 0) {
+						root.click();
+					}
+				})
+				.always(function() {
+					spinner.remove();
+				})
+			}
+			
+
+			fm.remove(function(e) {
+				$.each(e.data.removed, function(i, hash) {
+					remove(hash);
+				});
+				save();
+			})
+			.change(function(e) {
+				$.each(e.data.changed, function(i, file) {
+					if ($.inArray(file.hash, dirs) !== -1) {
+						remove(file.hash);
+						file.mime == 'directory' && add(file);
+					}
+				});
+				save();
+			})
+			.bind('sync', function() {
+				if (dirs.length) {
+					root.prepend(spinner);
+
+					fm.request({
+						data : {cmd : 'info', targets : dirs},
+						preventDefault : true
+					})
+					.done(function(data) {
+						$.each(data.files || [], function(i, file) {
+							if ($.inArray(file.hash, dirs) === -1) {
+								remove(file.hash);
+							}
+						});
+						save();
+					})
+					.always(function() {
+						spinner.remove();
+					});
+				}
+			})
+			
+		})
+		
+	});
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/searchbutton.js
+ */
+
+/**
+ * @class  elFinder toolbar search button widget.
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindersearchbutton = function(cmd) {
+	return this.each(function() {
+		var result = false,
+			button = $(this).hide().addClass('ui-widget-content elfinder-button '+cmd.fm.res('class', 'searchbtn')+''),
+			search = function() {
+				var val = $.trim(input.val());
+				if (val) {
+					cmd.exec(val).done(function() {
+						result = true;
+						input.focus();
+					});
+					
+				} else {
+					cmd.fm.trigger('searchend')
+				}
+			},
+			abort = function() {
+				input.val('');
+				if (result) {
+					result = false;
+					cmd.fm.trigger('searchend');
+				}
+			},
+			input  = $('<input type="text" size="42"/>')
+				.appendTo(button)
+				// to avoid fm shortcuts on arrows
+				.keypress(function(e) {
+					e.stopPropagation();
+				})
+				.keydown(function(e) {
+					e.stopPropagation();
+					
+					e.keyCode == 13 && search();
+					
+					if (e.keyCode== 27) {
+						e.preventDefault();
+						abort();
+					}
+				});
+		
+		$('<span class="ui-icon ui-icon-search" title="'+cmd.title+'"/>')
+			.appendTo(button)
+			.click(search);
+		
+		$('<span class="ui-icon ui-icon-close"/>')
+			.appendTo(button)
+			.click(abort)
+		
+		// wait when button will be added to DOM
+		setTimeout(function() {
+			button.parent().detach();
+			cmd.fm.getUI('toolbar').prepend(button.show());
+			// position icons for ie7
+			if (cmd.fm.UA.ltIE7) {
+				var icon = button.children(cmd.fm.direction == 'ltr' ? '.ui-icon-close' : '.ui-icon-search');
+				icon.css({
+					right : '',
+					left  : parseInt(button.width())-icon.outerWidth(true)
+				});
+			}
+		}, 200);
+		
+		cmd.fm
+			.error(function() {
+				input.unbind('keydown');
+			})
+			.select(function() {
+				input.blur();
+			})
+			.bind('searchend', function() {
+				input.val('');
+			})
+			.viewchange(abort)
+			.shortcut({
+				pattern     : 'ctrl+f f3',
+				description : cmd.title,
+				callback    : function() { input.select().focus(); }
+			});
+
+	});
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/sortbutton.js
+ */
+
+/**
+ * @class  elFinder toolbar button menu with sort variants.
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindersortbutton = function(cmd) {
+	
+	return this.each(function() {
+		var fm       = cmd.fm,
+			name     = cmd.name,
+			c        = 'class',
+			disabled = fm.res(c, 'disabled'),
+			hover    = fm.res(c, 'hover'),
+			item     = 'elfinder-button-menu-item',
+			selected = item+'-selected',
+			asc      = selected+'-asc',
+			desc     = selected+'-desc',
+			button   = $(this).addClass('ui-state-default elfinder-button elfinder-menubutton elfiner-button-'+name)
+				.attr('title', cmd.title)
+				.append('<span class="elfinder-button-icon elfinder-button-icon-'+name+'"/>')
+				.hover(function(e) { !button.is('.'+disabled) && button.toggleClass(hover); })
+				.click(function(e) {
+					if (!button.is('.'+disabled)) {
+						e.stopPropagation();
+						menu.is(':hidden') && cmd.fm.getUI().click();
+						menu.slideToggle(100);
+					}
+				}),
+			menu = $('<div class="ui-widget ui-widget-content elfinder-button-menu ui-corner-all"/>')
+				.hide()
+				.appendTo(button)
+				.zIndex(12+button.zIndex())
+				.delegate('.'+item, 'hover', function() { $(this).toggleClass(hover) })
+				.delegate('.'+item, 'click', function(e) {
+					e.preventDefault();
+					e.stopPropagation();
+					hide();
+				}),
+			update = function() {
+				menu.children(':not(:last)').removeClass(selected+' '+asc+' '+desc)
+					.filter('[rel="'+fm.sortType+'"]')
+					.addClass(selected+' '+(fm.sortOrder == 'asc' ? asc : desc));
+
+				menu.children(':last').toggleClass(selected, fm.sortStickFolders);
+			},
+			hide = function() { menu.hide(); };
+			
+			
+		$.each(fm.sortRules, function(name, value) {
+			menu.append($('<div class="'+item+'" rel="'+name+'"><span class="ui-icon ui-icon-arrowthick-1-n"/><span class="ui-icon ui-icon-arrowthick-1-s"/>'+fm.i18n('sort'+name)+'</div>').data('type', name));
+		});
+		
+		menu.children().click(function(e) {
+			var type = $(this).attr('rel');
+			
+			cmd.exec([], {
+				type  : type, 
+				order : type == fm.sortType ? fm.sortOrder == 'asc' ? 'desc' : 'asc' : fm.sortOrder, 
+				stick : fm.sortStickFolders
+			});
+		})
+		
+		$('<div class="'+item+' '+item+'-separated"><span class="ui-icon ui-icon-check"/>'+fm.i18n('sortFoldersFirst')+'</div>')
+			.appendTo(menu)
+			.click(function() {
+				cmd.exec([], {type : fm.sortType, order : fm.sortOrder, stick : !fm.sortStickFolders});
+			});		
+		
+		fm.bind('disable select', hide).getUI().click(hide);
+			
+		fm.bind('sortchange', update)
+		
+		if (menu.children().length > 1) {
+			cmd.change(function() {
+					button.toggleClass(disabled, cmd.disabled());
+					update();
+				})
+				.change();
+			
+		} else {
+			button.addClass(disabled);
+		}
+
+	});
+	
+}
+
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/stat.js
+ */
+
+/**
+ * @class elFinder ui
+ * Display number of files/selected files and its size in statusbar
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderstat = function(fm) {
+	return this.each(function() {
+		var size       = $(this).addClass('elfinder-stat-size'),
+			sel        = $('<div class="elfinder-stat-selected"/>'),
+			titlesize  = fm.i18n('size').toLowerCase(),
+			titleitems = fm.i18n('items').toLowerCase(),
+			titlesel   = fm.i18n('selected'),
+			setstat    = function(files, cwd) {
+				var c = 0, 
+					s = 0;
+
+				$.each(files, function(i, file) {
+					if (!cwd || file.phash == cwd) {
+						c++;
+						s += parseInt(file.size)||0;
+					}
+				})
+				size.html(titleitems+': '+c+', '+titlesize+': '+fm.formatSize(s));
+			};
+
+		fm.getUI('statusbar').prepend(size).append(sel).show();
+		
+		fm
+		.bind('open reload add remove change searchend', function() {
+			setstat(fm.files(), fm.cwd().hash)
+		})
+		.search(function(e) {
+			setstat(e.data.files);
+		})
+		.select(function() {
+			var s = 0,
+				c = 0,
+				files = fm.selectedFiles();
+
+			if (files.length == 1) {
+				s = files[0].size;
+				sel.html(fm.escape(files[0].name)+(s > 0 ? ', '+fm.formatSize(s) : ''));
+				
+				return;
+			}
+
+			$.each(files, function(i, file) {
+				c++;
+				s += parseInt(file.size)||0;
+			});
+
+			sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : '&nbsp;');
+		})
+
+		;
+	})
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/toolbar.js
+ */
+
+/**
+ * @class  elFinder toolbar
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindertoolbar = function(fm, opts) {
+	this.not('.elfinder-toolbar').each(function() {
+		var commands = fm._commands,
+			self     = $(this).addClass('ui-helper-clearfix ui-widget-header ui-corner-top elfinder-toolbar'),
+			panels   = opts || [],
+			l        = panels.length,
+			i, cmd, panel, button;
+		
+		self.prev().length && self.parent().prepend(this);
+
+		while (l--) {
+			if (panels[l]) {
+				panel = $('<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>');
+				i = panels[l].length;
+				while (i--) {
+					if ((cmd = commands[panels[l][i]])) {
+						button = 'elfinder'+cmd.options.ui;
+						$.fn[button] && panel.prepend($('<div/>')[button](cmd));
+					}
+				}
+				
+				panel.children().length && self.prepend(panel);
+				panel.children(':gt(0)').before('<span class="ui-widget-content elfinder-toolbar-button-separator"/>');
+
+			}
+		}
+		
+		self.children().length && self.show();
+	});
+	
+	return this;
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/tree.js
+ */
+
+/**
+ * @class  elFinder folders tree
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfindertree = function(fm, opts) {
+	var treeclass = fm.res('class', 'tree');
+	
+	this.not('.'+treeclass).each(function() {
+
+		var c = 'class',
+			
+			/**
+			 * Root directory class name
+			 *
+			 * @type String
+			 */
+			root      = fm.res(c, 'treeroot'),
+
+			/**
+			 * Open root dir if not opened yet
+			 *
+			 * @type Boolean
+			 */
+			openRoot  = opts.openRootOnLoad,
+
+			/**
+			 * Subtree class name
+			 *
+			 * @type String
+			 */
+			subtree   = fm.res(c, 'navsubtree'),
+			
+			/**
+			 * Directory class name
+			 *
+			 * @type String
+			 */
+			navdir    = fm.res(c, 'treedir'),
+			
+			/**
+			 * Collapsed arrow class name
+			 *
+			 * @type String
+			 */
+			collapsed = fm.res(c, 'navcollapse'),
+			
+			/**
+			 * Expanded arrow class name
+			 *
+			 * @type String
+			 */
+			expanded  = fm.res(c, 'navexpand'),
+			
+			/**
+			 * Class name to mark arrow for directory with already loaded children
+			 *
+			 * @type String
+			 */
+			loaded    = 'elfinder-subtree-loaded',
+			
+			/**
+			 * Arraw class name
+			 *
+			 * @type String
+			 */
+			arrow = fm.res(c, 'navarrow'),
+			
+			/**
+			 * Current directory class name
+			 *
+			 * @type String
+			 */
+			active    = fm.res(c, 'active'),
+			
+			/**
+			 * Droppable dirs dropover class
+			 *
+			 * @type String
+			 */
+			dropover = fm.res(c, 'adroppable'),
+			
+			/**
+			 * Hover class name
+			 *
+			 * @type String
+			 */
+			hover    = fm.res(c, 'hover'),
+			
+			/**
+			 * Disabled dir class name
+			 *
+			 * @type String
+			 */
+			disabled = fm.res(c, 'disabled'),
+			
+			/**
+			 * Draggable dir class name
+			 *
+			 * @type String
+			 */
+			draggable = fm.res(c, 'draggable'),
+			
+			/**
+			 * Droppable dir  class name
+			 *
+			 * @type String
+			 */
+			droppable = fm.res(c, 'droppable'),
+			
+			insideNavbar = function(x) {
+				var left = navbar.offset().left;
+					
+				return left <= x && x <= left + navbar.width();
+			},
+			
+			drop = fm.droppable.drop,
+			
+			/**
+			 * Droppable options
+			 *
+			 * @type Object
+			 */
+			droppableopts = $.extend(true, {}, fm.droppable, {
+				// show subfolders on dropover
+				over : function(e) { 
+					var link = $(this),
+						cl   = hover+' '+dropover;
+
+					if (insideNavbar(e.clientX)) {
+						link.addClass(cl)
+						if (link.is('.'+collapsed+':not(.'+expanded+')')) {
+							setTimeout(function() {
+								link.is('.'+dropover) && link.children('.'+arrow).click();
+							}, 500);
+						}
+					} else {
+						link.removeClass(cl);
+					}
+				},
+				out : function() { $(this).removeClass(hover+' '+dropover); },
+				drop : function(e, ui) { insideNavbar(e.clientX) && drop.call(this, e, ui); }
+			}),
+			
+			spinner = $(fm.res('tpl', 'navspinner')),
+			
+			/**
+			 * Directory html template
+			 *
+			 * @type String
+			 */
+			tpl = fm.res('tpl', 'navdir'),
+			
+			/**
+			 * Permissions marker html template
+			 *
+			 * @type String
+			 */
+			ptpl = fm.res('tpl', 'perms'),
+			
+			/**
+			 * Symlink marker html template
+			 *
+			 * @type String
+			 */
+			stpl = fm.res('tpl', 'symlink'),
+			
+			/**
+			 * Html template replacement methods
+			 *
+			 * @type Object
+			 */
+			replace = {
+				id          : function(dir) { return fm.navHash2Id(dir.hash) },
+				cssclass    : function(dir) { return (dir.phash ? '' : root)+' '+navdir+' '+fm.perms2class(dir)+' '+(dir.dirs && !dir.link ? collapsed : ''); },
+				permissions : function(dir) { return !dir.read || !dir.write ? ptpl : ''; },
+				symlink     : function(dir) { return dir.alias ? stpl : ''; }
+			},
+			
+			/**
+			 * Return html for given dir
+			 *
+			 * @param  Object  directory
+			 * @return String
+			 */
+			itemhtml = function(dir) {
+				dir.name = fm.escape(dir.i18 || dir.name);
+				
+				return tpl.replace(/(?:\{([a-z]+)\})/ig, function(m, key) {
+					return dir[key] || (replace[key] ? replace[key](dir) : '');
+				});
+			},
+			
+			/**
+			 * Return only dirs from files list
+			 *
+			 * @param  Array  files list
+			 * @return Array
+			 */
+			filter = function(files) {
+				return $.map(files||[], function(f) { return f.mime == 'directory' ? f : null });
+			},
+			
+			/**
+			 * Find parent subtree for required directory
+			 *
+			 * @param  String  dir hash
+			 * @return jQuery
+			 */
+			findSubtree = function(hash) {
+				return hash ? tree.find('#'+fm.navHash2Id(hash)).next('.'+subtree) : tree;
+			},
+			
+			/**
+			 * Find directory (wrapper) in required node
+			 * before which we can insert new directory
+			 *
+			 * @param  jQuery  parent directory
+			 * @param  Object  new directory
+			 * @return jQuery
+			 */
+			findSibling = function(subtree, dir) {
+				var node = subtree.children(':first'),
+					info;
+
+				while (node.length) {
+					info = fm.file(fm.navId2Hash(node.children('[id]').attr('id')));
+					
+					if ((info = fm.file(fm.navId2Hash(node.children('[id]').attr('id')))) 
+					&& dir.name.toLowerCase().localeCompare(info.name.toLowerCase()) < 0) {
+						return node;
+					}
+					node = node.next();
+				}
+				return $('');
+			},
+			
+			/**
+			 * Add new dirs in tree
+			 *
+			 * @param  Array  dirs list
+			 * @return void
+			 */
+			updateTree = function(dirs) {
+				var length  = dirs.length,
+					orphans = [],
+					i = dirs.length, 
+					dir, html, parent, sibling;
+
+				var firstVol = true; // check for netmount volume
+				while (i--) {
+					dir = dirs[i];
+
+					if (tree.find('#'+fm.navHash2Id(dir.hash)).length) {
+						continue;
+					}
+					
+					if ((parent = findSubtree(dir.phash)).length) {
+						html = itemhtml(dir);
+						if (dir.phash && (sibling = findSibling(parent, dir)).length) {
+							sibling.before(html);
+						} else {
+							parent[firstVol || dir.phash ? 'append' : 'prepend'](html);
+							firstVol = false;
+						}
+					} else {
+						orphans.push(dir);
+					}
+				}
+
+				if (orphans.length && orphans.length < length) {
+					return updateTree(orphans);
+				} 
+				
+				setTimeout(function() {
+					updateDroppable();
+				}, 10);
+				
+			},
+			
+			/**
+			 * Mark current directory as active
+			 * If current directory is not in tree - load it and its parents
+			 *
+			 * @param {Boolean} do not recursive call
+			 * @return void
+			 */
+			sync = function(stopRec) {
+				var cwd     = fm.cwd().hash,
+					current = tree.find('#'+fm.navHash2Id(cwd)), 
+					rootNode, dir;
+				
+				if (openRoot) {
+					rootNode = tree.find('#'+fm.navHash2Id(fm.root()));
+					rootNode.is('.'+loaded) && rootNode.addClass(expanded).next('.'+subtree).show();
+					openRoot = false;
+				}
+				
+				if (!current.is('.'+active)) {
+					tree.find('.'+navdir+'.'+active).removeClass(active);
+					current.addClass(active);
+				}
+
+				if (opts.syncTree) {
+					if (current.length) {
+						return current.parentsUntil('.'+root).filter('.'+subtree).show().prev('.'+navdir).addClass(expanded);
+					}
+					if (fm.newAPI) {
+						dir = fm.file(cwd);
+						if (dir && dir.phash && tree.find('#'+fm.navHash2Id(dir.phash)).length) {
+							updateTree([dir]);
+							return sync();
+						}
+						fm.request({
+							data : {cmd : 'parents', target : cwd},
+							preventFail : true
+						})
+						.done(function(data) {
+							var dirs = filter(data.tree);
+							updateTree(dirs);
+							updateArrows(dirs, loaded);
+							cwd == fm.cwd().hash && sync(true);
+						})
+						;
+					}
+					
+				}
+			},
+			
+			/**
+			 * Make writable and not root dirs droppable
+			 *
+			 * @return void
+			 */
+			updateDroppable = function() {
+				tree.find('.'+navdir+':not(.'+droppable+',.elfinder-ro,.elfinder-na)').droppable(droppableopts);
+			},
+			
+			/**
+			 * Check required folders for subfolders and update arrow classes
+			 *
+			 * @param  Array  folders to check
+			 * @param  String css class 
+			 * @return void
+			 */
+			updateArrows = function(dirs, cls) {
+				var sel = cls == loaded
+						? '.'+collapsed+':not(.'+loaded+')'
+						: ':not(.'+collapsed+')';
+				
+						
+				//tree.find('.'+subtree+':has(*)').prev(':not(.'+collapsed+')').addClass(collapsed)
+
+				$.each(dirs, function(i, dir) {
+					tree.find('#'+fm.navHash2Id(dir.phash)+sel)
+						.filter(function() { return $(this).next('.'+subtree).children().length > 0 })
+						.addClass(cls);
+				})
+			},
+			
+			
+			
+			/**
+			 * Navigation tree
+			 *
+			 * @type JQuery
+			 */
+			tree = $(this).addClass(treeclass)
+				// make dirs draggable and toggle hover class
+				.delegate('.'+navdir, 'hover', function(e) {
+					var link  = $(this), 
+						enter = e.type == 'mouseenter';
+					
+					if (!link.is('.'+dropover+' ,.'+disabled)) {
+						enter && !link.is('.'+root+',.'+draggable+',.elfinder-na,.elfinder-wo') && link.draggable(fm.draggable);
+						link.toggleClass(hover, enter);
+					}
+				})
+				// add/remove dropover css class
+				.delegate('.'+navdir, 'dropover dropout drop', function(e) {
+					$(this)[e.type == 'dropover' ? 'addClass' : 'removeClass'](dropover+' '+hover);
+				})
+				// open dir or open subfolders in tree
+				.delegate('.'+navdir, 'click', function(e) {
+					var link = $(this),
+						hash = fm.navId2Hash(link.attr('id')),
+						file = fm.file(hash);
+				
+					fm.trigger('searchend');
+				
+					if (hash != fm.cwd().hash && !link.is('.'+disabled)) {
+						fm.exec('open', file.thash || hash);
+					} else if (link.is('.'+collapsed)) {
+						link.children('.'+arrow).click();
+					}
+				})
+				// toggle subfolders in tree
+				.delegate('.'+navdir+'.'+collapsed+' .'+arrow, 'click', function(e) {
+					var arrow = $(this),
+						link  = arrow.parent('.'+navdir),
+						stree = link.next('.'+subtree);
+
+					e.stopPropagation();
+
+					if (link.is('.'+loaded)) {
+						link.toggleClass(expanded);
+						stree.slideToggle()
+					} else {
+						spinner.insertBefore(arrow);
+						link.removeClass(collapsed);
+
+						fm.request({cmd : 'tree', target : fm.navId2Hash(link.attr('id'))})
+							.done(function(data) { 
+								updateTree(filter(data.tree)); 
+								
+								if (stree.children().length) {
+									link.addClass(collapsed+' '+expanded);
+									stree.slideDown();
+								} 
+								sync();
+							})
+							.always(function(data) {
+								spinner.remove();
+								link.addClass(loaded);
+							});
+					}
+				})
+				.delegate('.'+navdir, 'contextmenu', function(e) {
+					e.preventDefault();
+
+					fm.trigger('contextmenu', {
+						'type'    : 'navbar',
+						'targets' : [fm.navId2Hash($(this).attr('id'))],
+						'x'       : e.clientX,
+						'y'       : e.clientY
+					});
+				}),
+			// move tree into navbar
+			navbar = fm.getUI('navbar').append(tree).show()
+				
+			;
+
+		fm.open(function(e) {
+			var data = e.data,
+				dirs = filter(data.files);
+
+			data.init && tree.empty();
+
+			if (dirs.length) {
+				updateTree(dirs);
+				updateArrows(dirs, loaded);
+			} 
+			sync();
+		})
+		// add new dirs
+		.add(function(e) {
+			var dirs = filter(e.data.added);
+
+			if (dirs.length) {
+				updateTree(dirs);
+				updateArrows(dirs, collapsed);
+			}
+		})
+		// update changed dirs
+		.change(function(e) {
+			var dirs = filter(e.data.changed),
+				l    = dirs.length,
+				dir, node, tmp, realParent, reqParent, realSibling, reqSibling, isExpanded, isLoaded;
+			
+			while (l--) {
+				dir = dirs[l];
+				if ((node = tree.find('#'+fm.navHash2Id(dir.hash))).length) {
+					if (dir.phash) {
+						realParent  = node.closest('.'+subtree);
+						reqParent   = findSubtree(dir.phash);
+						realSibling = node.parent().next();
+						reqSibling  = findSibling(reqParent, dir);
+						
+						if (!reqParent.length) {
+							continue;
+						}
+						
+						if (reqParent[0] !== realParent[0] || realSibling.get(0) !== reqSibling.get(0)) {
+							reqSibling.length ? reqSibling.before(node) : reqParent.append(node);
+						}
+					}
+					isExpanded = node.is('.'+expanded);
+					isLoaded   = node.is('.'+loaded);
+					tmp        = $(itemhtml(dir));
+					node.replaceWith(tmp.children('.'+navdir));
+					
+					if (dir.dirs 
+					&& (isExpanded || isLoaded) 
+					&& (node = tree.find('#'+fm.navHash2Id(dir.hash))) 
+					&& node.next('.'+subtree).children().length) {
+						isExpanded && node.addClass(expanded);
+						isLoaded && node.addClass(loaded);
+					}
+				}
+			}
+
+			sync();
+			updateDroppable();
+		})
+		// remove dirs
+		.remove(function(e) {
+			var dirs = e.data.removed,
+				l    = dirs.length,
+				node, stree;
+			
+			while (l--) {
+				if ((node = tree.find('#'+fm.navHash2Id(dirs[l]))).length) {
+					stree = node.closest('.'+subtree);
+					node.parent().detach();
+					if (!stree.children().length) {
+						stree.hide().prev('.'+navdir).removeClass(collapsed+' '+expanded+' '+loaded);
+					}
+				}
+			}
+		})
+		// add/remove active class for current dir
+		.bind('search searchend', function(e) {
+			tree.find('#'+fm.navHash2Id(fm.cwd().hash))[e.type == 'search' ? 'removeClass' : 'addClass'](active);
+		})
+		// lock/unlock dirs while moving
+		.bind('lockfiles unlockfiles', function(e) {
+			var lock = e.type == 'lockfiles',
+				act  = lock ? 'disable' : 'enable',
+				dirs = $.map(e.data.files||[], function(h) {  
+					var dir = fm.file(h);
+					return dir && dir.mime == 'directory' ? h : null;
+				})
+				
+			$.each(dirs, function(i, hash) {
+				var dir = tree.find('#'+fm.navHash2Id(hash));
+				
+				if (dir.length) {
+					dir.is('.'+draggable) && dir.draggable(act);
+					dir.is('.'+droppable) && dir.droppable(active);
+					dir[lock ? 'addClass' : 'removeClass'](disabled);
+				}
+			});
+		})
+
+	});
+	
+	return this;
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/uploadButton.js
+ */
+
+/**
+ * @class  elFinder toolbar's button tor upload file
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderuploadbutton = function(cmd) {
+	return this.each(function() {
+		var button = $(this).elfinderbutton(cmd)
+				.unbind('click'), 
+			form = $('<form/>').appendTo(button),
+			input = $('<input type="file" multiple="true"/>')
+				.change(function() {
+					var _input = $(this);
+					if (_input.val()) {
+						cmd.exec({input : _input.remove()[0]});
+						input.clone(true).appendTo(form);
+					} 
+				});
+
+		form.append(input.clone(true));
+				
+		cmd.change(function() {
+			form[cmd.disabled() ? 'hide' : 'show']();
+		})
+		.change();
+	});
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/viewbutton.js
+ */
+
+/**
+ * @class  elFinder toolbar button to switch current directory view.
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderviewbutton = function(cmd) {
+	return this.each(function() {
+		var button = $(this).elfinderbutton(cmd),
+			icon   = button.children('.elfinder-button-icon');
+
+		cmd.change(function() {
+			var icons = cmd.value == 'icons';
+
+			icon.toggleClass('elfinder-button-icon-view-list', icons);
+			button.attr('title', cmd.fm.i18n(icons ? 'viewlist' : 'viewicons'));
+		});
+	});
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/ui/workzone.js
+ */
+
+/**
+ * @class elfinderworkzone - elFinder container for nav and current directory
+ * @author Dmitry (dio) Levashov
+ **/
+$.fn.elfinderworkzone = function(fm) {
+	var cl = 'elfinder-workzone';
+	
+	this.not('.'+cl).each(function() {
+		var wz     = $(this).addClass(cl),
+			wdelta = wz.outerHeight(true) - wz.height(),
+			parent = wz.parent();
+			
+		parent.add(window).bind('resize', function() {
+				var height = parent.height();
+
+				parent.children(':visible:not(.'+cl+')').each(function() {
+					var ch = $(this);
+
+					if (ch.css('position') != 'absolute') {
+						height -= ch.outerHeight(true);
+					}
+				});
+				
+				wz.height(height - wdelta);
+			});
+	});
+	return this;
+}
+
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/archive.js
+ */
+
+/**
+ * @class  elFinder command "archive"
+ * Archive selected files
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.archive = function() {
+	var self  = this,
+		fm    = self.fm,
+		mimes = [];
+		
+	this.variants = [];
+	
+	this.disableOnSearch = true;
+	
+	/**
+	 * Update mimes on open/reload
+	 *
+	 * @return void
+	 **/
+	fm.bind('open reload', function() {
+		self.variants = [];
+		$.each((mimes = fm.option('archivers')['create'] || []), function(i, mime) {
+			self.variants.push([mime, fm.mime2kind(mime)])
+		});
+		self.change();
+	});
+	
+	this.getstate = function() {
+		return !this._disabled && mimes.length && fm.selected().length && fm.cwd().write ? 0 : -1;
+	}
+	
+	this.exec = function(hashes, type) {
+		var files = this.files(hashes),
+			cnt   = files.length,
+			mime  = type || mimes[0],
+			cwd   = fm.cwd(),
+			error = ['errArchive', 'errPerm', 'errCreatingTempDir', 'errFtpDownloadFile', 'errFtpUploadFile', 'errFtpMkdir', 'errArchiveExec', 'errExtractExec', 'errRm'],
+			dfrd  = $.Deferred().fail(function(error) {
+				error && fm.error(error);
+			}), 
+			i;
+
+		if (!(this.enabled() && cnt && mimes.length && $.inArray(mime, mimes) !== -1)) {
+			return dfrd.reject();
+		}
+		
+		if (!cwd.write) {
+			return dfrd.reject(error);
+		}
+		
+		for (i = 0; i < cnt; i++) {
+			if (!files[i].read) {
+				return dfrd.reject(error);
+			}
+		}
+
+		return fm.request({
+			data       : {cmd : 'archive', targets : this.hashes(hashes), type : mime},
+			notify     : {type : 'archive', cnt : 1},
+			syncOnFail : true
+		});
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/back.js
+ */
+
+/**
+ * @class  elFinder command "back"
+ * Open last visited folder
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.back = function() {
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+	this.shortcuts      = [{
+		pattern     : 'ctrl+left backspace'
+	}];
+	
+	this.getstate = function() {
+		return this.fm.history.canBack() ? 0 : -1;
+	}
+	
+	this.exec = function() {
+		return this.fm.history.back();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/copy.js
+ */
+
+/**
+ * @class elFinder command "copy".
+ * Put files in filemanager clipboard.
+ *
+ * @type  elFinder.command
+ * @author  Dmitry (dio) Levashov
+ */
+elFinder.prototype.commands.copy = function() {
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+c ctrl+insert'
+	}];
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+
+		return cnt && $.map(sel, function(f) { return f.phash && f.read ? f : null  }).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var fm   = this.fm,
+			dfrd = $.Deferred()
+				.fail(function(error) {
+					fm.error(error);
+				});
+
+		$.each(this.files(hashes), function(i, file) {
+			if (!(file.read && file.phash)) {
+				return !dfrd.reject(['errCopy', file.name, 'errPerm']);
+			}
+		});
+		
+		return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes)));
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/cut.js
+ */
+
+/**
+ * @class elFinder command "copy".
+ * Put files in filemanager clipboard.
+ *
+ * @type  elFinder.command
+ * @author  Dmitry (dio) Levashov
+ */
+elFinder.prototype.commands.cut = function() {
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+x shift+insert'
+	}];
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+		
+		return cnt && $.map(sel, function(f) { return f.phash && f.read && !f.locked ? f : null  }).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var fm     = this.fm,
+			dfrd   = $.Deferred()
+				.fail(function(error) {
+					fm.error(error);
+				});
+
+		$.each(this.files(hashes), function(i, file) {
+			if (!(file.read && file.phash) ) {
+				return !dfrd.reject(['errCopy', file.name, 'errPerm']);
+			}
+			if (file.locked) {
+				return !dfrd.reject(['errLocked', file.name]);
+			}
+		});
+		
+		return dfrd.state() == 'rejected' ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes), true));
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/download.js
+ */
+
+/**
+ * @class elFinder command "download". 
+ * Download selected files.
+ * Only for new api
+ *
+ * @author Dmitry (dio) Levashov, dio@std42.ru
+ **/
+elFinder.prototype.commands.download = function() {
+	var self   = this,
+		fm     = this.fm,
+		filter = function(hashes) {
+			return $.map(self.files(hashes), function(f) { return f.mime == 'directory' ? null : f });
+		};
+	
+	this.shortcuts = [{
+		pattern     : 'shift+enter'
+	}];
+	
+	this.getstate = function() {
+		var sel = this.fm.selected(),
+			cnt = sel.length;
+		
+		return  !this._disabled && cnt && (!fm.UA.IE || cnt == 1) && cnt == filter(sel).length ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var fm      = this.fm,
+			base    = fm.options.url,
+			files   = filter(hashes),
+			dfrd    = $.Deferred(),
+			iframes = '',
+			cdata   = '',
+			i, url;
+			
+		if (this.disabled()) {
+			return dfrd.reject();
+		}
+			
+		if (fm.oldAPI) {
+			fm.error('errCmdNoSupport');
+			return dfrd.reject();
+		}
+		
+		cdata = $.param(fm.options.customData || {});
+		if (cdata) {
+			cdata = '&' + cdata;
+		}
+		
+		base += base.indexOf('?') === -1 ? '?' : '&';
+		
+		for (i = 0; i < files.length; i++) {
+			iframes += '<iframe class="downloader" id="downloader-' + files[i].hash+'" style="display:none" src="'+base + 'cmd=file&target=' + files[i].hash+'&download=1'+cdata+'"/>';
+		}
+		$(iframes)
+			.appendTo('body')
+			.ready(function() {
+				setTimeout(function() {
+					$(iframes).each(function() {
+						$('#' + $(this).attr('id')).remove();
+					});
+				}, fm.UA.Firefox? (20000 + (10000 * i)) : 1000); // give mozilla 20 sec + 10 sec for each file to be saved
+			});
+		fm.trigger('download', {files : files});
+		return dfrd.resolve(hashes);
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/duplicate.js
+ */
+
+/**
+ * @class elFinder command "duplicate"
+ * Create file/folder copy with suffix "copy Number"
+ *
+ * @type  elFinder.command
+ * @author  Dmitry (dio) Levashov
+ */
+elFinder.prototype.commands.duplicate = function() {
+	var fm = this.fm;
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+
+		return !this._disabled && cnt && fm.cwd().write && $.map(sel, function(f) { return f.phash && f.read ? f : null  }).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var fm     = this.fm,
+			files  = this.files(hashes),
+			cnt    = files.length,
+			dfrd   = $.Deferred()
+				.fail(function(error) {
+					error && fm.error(error);
+				}), 
+			args = [];
+			
+		if (!cnt || this._disabled) {
+			return dfrd.reject();
+		}
+		
+		$.each(files, function(i, file) {
+			if (!file.read || !fm.file(file.phash).write) {
+				return !dfrd.reject(['errCopy', file.name, 'errPerm']);
+			}
+		});
+		
+		if (dfrd.state() == 'rejected') {
+			return dfrd;
+		}
+		
+		return fm.request({
+			data   : {cmd : 'duplicate', targets : this.hashes(hashes)},
+			notify : {type : 'copy', cnt : cnt}
+		});
+		
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/edit.js
+ */
+
+/**
+ * @class elFinder command "edit". 
+ * Edit text file in dialog window
+ *
+ * @author Dmitry (dio) Levashov, dio@std42.ru
+ **/
+elFinder.prototype.commands.edit = function() {
+	var self  = this,
+		fm    = this.fm,
+		mimes = fm.res('mimes', 'text') || [],
+		
+		/**
+		 * Return files acceptable to edit
+		 *
+		 * @param  Array  files hashes
+		 * @return Array
+		 **/
+		filter = function(files) {
+			return $.map(files, function(file) {
+				return (file.mime.indexOf('text/') === 0 || $.inArray(file.mime, mimes) !== -1) 
+					&& file.mime.indexOf('text/rtf')
+					&& (!self.onlyMimes.length || $.inArray(file.mime, self.onlyMimes) !== -1)
+					&& file.read && file.write ? file : null;
+			});
+		},
+		
+		/**
+		 * Open dialog with textarea to edit file
+		 *
+		 * @param  String  id       dialog id
+		 * @param  Object  file     file object
+		 * @param  String  content  file content
+		 * @return $.Deferred
+		 **/
+		dialog = function(id, file, content) {
+
+			var dfrd = $.Deferred(),
+				ta   = $('<textarea class="elfinder-file-edit" rows="20" id="'+id+'-ta">'+fm.escape(content)+'</textarea>'),
+				save = function() {
+					ta.editor && ta.editor.save(ta[0], ta.editor.instance);
+					dfrd.resolve(ta.getContent());
+					ta.elfinderdialog('close');
+				},
+				cancel = function() {
+					dfrd.reject();
+					ta.elfinderdialog('close');
+				},
+				opts = {
+					title   : file.name,
+					width   : self.options.dialogWidth || 450,
+					buttons : {},
+					close   : function() { 
+						ta.editor && ta.editor.close(ta[0], ta.editor.instance);
+						$(this).elfinderdialog('destroy'); 
+					},
+					open    : function() { 
+						fm.disable();
+						ta.focus(); 
+						ta[0].setSelectionRange && ta[0].setSelectionRange(0, 0);
+						ta.editor && ta.editor.load(ta[0]);
+					}
+					
+				};
+				
+				ta.getContent = function() {
+					return ta.val()
+				}
+				
+				$.each(self.options.editors || [], function(i, editor) {
+					if ($.inArray(file.mime, editor.mimes || []) !== -1 
+					&& typeof editor.load == 'function'
+					&& typeof editor.save == 'function') {
+						ta.editor = {
+							load     : editor.load,
+							save     : editor.save,
+							close    : typeof editor.close == 'function' ? editor.close : function() {},
+							instance : null
+						}
+						
+						return false;
+					}
+				});
+				
+				if (!ta.editor) {
+					ta.keydown(function(e) {
+						var code = e.keyCode,
+							value, start;
+						
+						e.stopPropagation();
+						if (code == 9) {
+							e.preventDefault();
+							// insert tab on tab press
+							if (this.setSelectionRange) {
+								value = this.value;
+								start = this.selectionStart;
+								this.value = value.substr(0, start) + "\t" + value.substr(this.selectionEnd);
+								start += 1;
+								this.setSelectionRange(start, start);
+							}
+						}
+						
+						if (e.ctrlKey || e.metaKey) {
+							// close on ctrl+w/q
+							if (code == 81 || code == 87) {
+								e.preventDefault();
+								cancel();
+							}
+							if (code == 83) {
+								e.preventDefault();
+								save();
+							}
+						}
+						
+					})
+				}
+				
+				opts.buttons[fm.i18n('Save')]   = save;
+				opts.buttons[fm.i18n('Cancel')] = cancel
+				
+				fm.dialog(ta, opts).attr('id', id);
+				return dfrd.promise();
+		},
+		
+		/**
+		 * Get file content and
+		 * open dialog with textarea to edit file content
+		 *
+		 * @param  String  file hash
+		 * @return jQuery.Deferred
+		 **/
+		edit = function(file) {
+			var hash   = file.hash,
+				opts   = fm.options,
+				dfrd   = $.Deferred(), 
+				data   = {cmd : 'file', target : hash},
+				url    = fm.url(hash) || fm.options.url,
+				id    = 'edit-'+fm.namespace+'-'+file.hash,
+				d = fm.getUI().find('#'+id), 
+				error;
+			
+			
+			if (d.length) {
+				d.elfinderdialog('toTop');
+				return dfrd.resolve();
+			}
+			
+			if (!file.read || !file.write) {
+				error = ['errOpen', file.name, 'errPerm']
+				fm.error(error)
+				return dfrd.reject(error);
+			}
+			
+			fm.request({
+				data   : {cmd : 'get', target  : hash},
+				notify : {type : 'openfile', cnt : 1},
+				syncOnFail : true
+			})
+			.done(function(data) {
+				dialog(id, file, data.content)
+					.done(function(content) {
+						fm.request({
+							options : {type : 'post'},
+							data : {
+								cmd     : 'put',
+								target  : hash,
+								content : content
+							},
+							notify : {type : 'save', cnt : 1},
+							syncOnFail : true
+						})
+						.fail(function(error) {
+							dfrd.reject(error);
+						})
+						.done(function(data) {
+							data.changed && data.changed.length && fm.change(data);
+							dfrd.resolve(data);
+						});
+					})
+			})
+			.fail(function(error) {
+				dfrd.reject(error);
+			})
+
+			return dfrd.promise();
+		};
+	
+	
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+e'
+	}];
+	
+	this.init = function() {
+		this.onlyMimes = this.options.mimes || []
+	}
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+
+		return !this._disabled && cnt && filter(sel).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var files = filter(this.files(hashes)),
+			list  = [],
+			file;
+
+		if (this.disabled()) {
+			return $.Deferred().reject();
+		}
+
+		while ((file = files.shift())) {
+			list.push(edit(file));
+		}
+		
+		return list.length 
+			? $.when.apply(null, list)
+			: $.Deferred().reject();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/extract.js
+ */
+
+/**
+ * @class  elFinder command "extract"
+ * Extract files from archive
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.extract = function() {
+	var self    = this,
+		fm      = self.fm,
+		mimes   = [],
+		filter  = function(files) {
+			return $.map(files, function(file) { 
+				return file.read && $.inArray(file.mime, mimes) !== -1 ? file : null
+				
+			})
+		};
+	
+	this.disableOnSearch = true;
+	
+	// Update mimes list on open/reload
+	fm.bind('open reload', function() {
+		mimes = fm.option('archivers')['extract'] || [];
+		self.change();
+	});
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+		
+		return !this._disabled && cnt && this.fm.cwd().write && filter(sel).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var files    = this.files(hashes),
+			dfrd     = $.Deferred(),
+			cnt      = files.length, 
+			i, error,
+			decision;
+
+		var overwriteAll = false;
+		var omitAll = false;
+
+		var names = $.map(fm.files(hashes), function(file) { return file.name; });
+		var map = {};
+		$.map(fm.files(hashes), function(file) { map[file.name] = file; });
+		
+		var decide = function(decision) {
+			switch (decision) {
+				case 'overwrite_all' :
+					overwriteAll = true;
+					break;
+				case 'omit_all':
+					omitAll = true;
+					break;
+			}
+		};
+
+		var unpack = function(file) {
+			if (!(file.read && fm.file(file.phash).write)) {
+				error = ['errExtract', file.name, 'errPerm'];
+				fm.error(error);
+				dfrd.reject(error);
+			} else if ($.inArray(file.mime, mimes) === -1) {
+				error = ['errExtract', file.name, 'errNoArchive'];
+				fm.error(error);
+				dfrd.reject(error);
+			} else {
+				fm.request({
+					data:{cmd:'extract', target:file.hash},
+					notify:{type:'extract', cnt:1},
+					syncOnFail:true
+				})
+				.fail(function (error) {
+					if (dfrd.state() != 'rejected') {
+						dfrd.reject(error);
+					}
+				})
+				.done(function () {
+				});
+			}
+		};
+		
+		var confirm = function(files, index) {
+			var file = files[index];
+			var name = file.name.replace(/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/ig, '');
+			var existed = ($.inArray(name, names) >= 0);
+			if(existed && map[name].mime != 'directory') {
+				fm.confirm(
+					{
+						title : fm.i18n('ntfextract'),
+						text  : fm.i18n(['errExists', name, 'confirmRepl']),
+						accept:{
+							label : 'btnYes',
+							callback:function (all) {
+								decision = all ? 'overwrite_all' : 'overwrite';
+								decide(decision);
+								if(!overwriteAll && !omitAll) {
+									if('overwrite' == decision) {
+										unpack(file);
+									}
+									if((index+1) < cnt) {
+										confirm(files, index+1);
+									} else {
+										dfrd.resolve();
+									}
+								} else if(overwriteAll) {
+									for (i = 0; i < cnt; i++) {
+										unpack(files[i]);
+									}
+									dfrd.resolve();
+								}
+							}
+						},
+						reject : {
+							label : 'btnNo',
+							callback:function (all) {
+								decision = all ? 'omit_all' : 'omit';
+								decide(decision);
+								if(!overwriteAll && !omitAll && (index+1) < cnt) {
+									confirm(files, index+1);
+								} else if (omitAll) {
+									dfrd.resolve();
+								}
+							}
+						},
+						cancel : {
+							label : 'btnCancel',
+							callback:function () {
+								dfrd.resolve();
+							}
+						},
+						all : (cnt > 1)
+					}
+				);
+			} else {
+				unpack(file);
+				if((index+1) < cnt) {
+					confirm(files, index+1);
+				} else {
+					dfrd.resolve();
+				}
+			}
+		};
+		
+		if (!(this.enabled() && cnt && mimes.length)) {
+			return dfrd.reject();
+		}
+		
+		if(cnt > 0) {
+			confirm(files, 0);
+		}
+
+		return dfrd;
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/forward.js
+ */
+
+/**
+ * @class  elFinder command "forward"
+ * Open next visited folder
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.forward = function() {
+	this.alwaysEnabled = true;
+	this.updateOnSelect = true;
+	this.shortcuts = [{
+		pattern     : 'ctrl+right'
+	}];
+	
+	this.getstate = function() {
+		return this.fm.history.canForward() ? 0 : -1;
+	}
+	
+	this.exec = function() {
+		return this.fm.history.forward();
+	}
+	
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/getfile.js
+ */
+
+/**
+ * @class elFinder command "getfile". 
+ * Return selected files info into outer callback.
+ * For use elFinder with wysiwyg editors etc.
+ *
+ * @author Dmitry (dio) Levashov, dio@std42.ru
+ **/
+elFinder.prototype.commands.getfile = function() {
+	var self   = this,
+		fm     = this.fm,
+		filter = function(files) {
+			var o = self.options;
+
+			files = $.map(files, function(file) {
+				return file.mime != 'directory' || o.folders ? file : null;
+			});
+
+			return o.multiple || files.length == 1 ? files : [];
+		};
+	
+	this.alwaysEnabled = true;
+	this.callback      = fm.options.getFileCallback;
+	this._disabled     = typeof(this.callback) == 'function';
+	
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+			
+		return this.callback && cnt && filter(sel).length == cnt ? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var fm    = this.fm,
+			opts  = this.options,
+			files = this.files(hashes),
+			cnt   = files.length,
+			url   = fm.option('url'),
+			tmb   = fm.option('tmbUrl'),
+			dfrd  = $.Deferred()
+				.done(function(data) {
+					fm.trigger('getfile', {files : data});
+					self.callback(data, fm);
+					
+					if (opts.oncomplete == 'close') {
+						fm.hide();
+					} else if (opts.oncomplete == 'destroy') {
+						fm.destroy();
+					}
+				}),
+			result = function(file) {
+				return opts.onlyURL
+					? opts.multiple ? $.map(files, function(f) { return f.url; }) : files[0].url
+					: opts.multiple ? files : files[0];
+			},
+			req = [], 
+			i, file, dim;
+
+		if (this.getstate() == -1) {
+			return dfrd.reject();
+		}
+			
+		for (i = 0; i < cnt; i++) {
+			file = files[i];
+			if (file.mime == 'directory' && !opts.folders) {
+				return dfrd.reject();
+			}
+			file.baseUrl = url;
+			file.url     = fm.url(file.hash);
+			file.path    = fm.path(file.hash);
+			if (file.tmb && file.tmb != 1) {
+				file.tmb = tmb + file.tmb;
+			}
+			if (!file.width && !file.height) {
+				if (file.dim) {
+					dim = file.dim.split('x');
+					file.width = dim[0];
+					file.height = dim[1];
+				} else if (file.mime.indexOf('image') !== -1) {
+					req.push(fm.request({
+						data : {cmd : 'dim', target : file.hash},
+						notify : {type : 'dim', cnt : 1, hideCnt : true},
+						preventDefault : true
+					})
+					.done(function(data) {
+						if (data.dim) {
+							var dim = data.dim.split('x');
+							var rfile = fm.file(this.hash);
+							rfile.width = this.width = dim[0];
+							rfile.height = this.height = dim[1];
+						}
+					}.bind(file)));
+				}
+			}
+		}
+		
+		if (req.length) {
+			$.when.apply(null, req).always(function() {
+				dfrd.resolve(result(files));
+			})
+			return dfrd;
+		}
+		
+		return dfrd.resolve(result(files));
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/help.js
+ */
+
+/**
+ * @class  elFinder command "help"
+ * "About" dialog
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.help = function() {
+	var fm   = this.fm,
+		self = this,
+		linktpl = '<div class="elfinder-help-link"> <a href="{url}">{link}</a></div>',
+		linktpltgt = '<div class="elfinder-help-link"> <a href="{url}" target="_blank">{link}</a></div>',
+		atpl    = '<div class="elfinder-help-team"><div>{author}</div>{work}</div>',
+		url     = /\{url\}/,
+		link    = /\{link\}/,
+		author  = /\{author\}/,
+		work    = /\{work\}/,
+		r       = 'replace',
+		prim    = 'ui-priority-primary',
+		sec     = 'ui-priority-secondary',
+		lic     = 'elfinder-help-license',
+		tab     = '<li class="ui-state-default ui-corner-top"><a href="#{id}">{title}</a></li>',
+		html    = ['<div class="ui-tabs ui-widget ui-widget-content ui-corner-all elfinder-help">', 
+				'<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">'],
+		stpl    = '<div class="elfinder-help-shortcut"><div class="elfinder-help-shortcut-pattern">{pattern}</div> {descrip}</div>',
+		sep     = '<div class="elfinder-help-separator"/>',
+		
+		
+		about = function() {
+			html.push('<div id="about" class="ui-tabs-panel ui-widget-content ui-corner-bottom"><div class="elfinder-help-logo"/>')
+			html.push('<h3>elFinder</h3>');
+			html.push('<div class="'+prim+'">'+fm.i18n('webfm')+'</div>');
+			html.push('<div class="'+sec+'">'+fm.i18n('ver')+': '+fm.version+', '+fm.i18n('protocolver')+': <span id="apiver"></span></div>');
+			html.push('<div class="'+sec+'">jQuery/jQuery UI: '+$().jquery+'/'+$.ui.version+'</div>');
+
+			html.push(sep);
+			
+			html.push(linktpltgt[r](url, 'http://elfinder.org/')[r](link, fm.i18n('homepage')));
+			html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder/wiki')[r](link, fm.i18n('docs')));
+			html.push(linktpltgt[r](url, 'https://github.com/Studio-42/elFinder')[r](link, fm.i18n('github')));
+			html.push(linktpltgt[r](url, 'http://twitter.com/elrte_elfinder')[r](link, fm.i18n('twitter')));
+			
+			html.push(sep);
+			
+			html.push('<div class="'+prim+'">'+fm.i18n('team')+'</div>');
+			
+			html.push(atpl[r](author, 'Dmitry "dio" Levashov &lt;dio@std42.ru&gt;')[r](work, fm.i18n('chiefdev')));
+			html.push(atpl[r](author, 'Troex Nevelin &lt;troex@fury.scancode.ru&gt;')[r](work, fm.i18n('maintainer')));
+			html.push(atpl[r](author, 'Alexey Sukhotin &lt;strogg@yandex.ru&gt;')[r](work, fm.i18n('contributor')));
+			html.push(atpl[r](author, 'Naoki Sawada &lt;hypweb@gmail.com&gt;')[r](work, fm.i18n('contributor')));
+			
+			fm.i18[fm.lang].translator && html.push(atpl[r](author, fm.i18[fm.lang].translator)[r](work, fm.i18n('translator')+' ('+fm.i18[fm.lang].language+')'));
+			
+			html.push(sep);
+			html.push('<div class="'+lic+'">'+fm.i18n('icons')+': Pixelmixer, <a href="http://p.yusukekamiyamane.com" target="_blank">Fugue</a></div>');
+			
+			html.push(sep);
+			html.push('<div class="'+lic+'">Licence: BSD Licence</div>');
+			html.push('<div class="'+lic+'">Copyright © 2009-2011, Studio 42</div>');
+			html.push('<div class="'+lic+'">„ …'+fm.i18n('dontforget')+' ”</div>');
+			html.push('</div>');
+		},
+		shortcuts = function() {
+			var sh = fm.shortcuts();
+			// shortcuts tab
+			html.push('<div id="shortcuts" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');
+			
+			if (sh.length) {
+				html.push('<div class="ui-widget-content elfinder-help-shortcuts">');
+				$.each(sh, function(i, s) {
+					html.push(stpl.replace(/\{pattern\}/, s[0]).replace(/\{descrip\}/, s[1]));
+				});
+			
+				html.push('</div>');
+			} else {
+				html.push('<div class="elfinder-help-disabled">'+fm.i18n('shortcutsof')+'</div>')
+			}
+			
+			
+			html.push('</div>')
+			
+		},
+		help = function() {
+			// help tab
+			html.push('<div id="help" class="ui-tabs-panel ui-widget-content ui-corner-bottom">');
+			html.push('<a href="http://elfinder.org/forum/" target="_blank" class="elfinder-dont-panic"><span>DON\'T PANIC</span></a>');
+			html.push('</div>');
+			// end help
+		},
+		content;
+	
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+	this.state = 0;
+	
+	this.shortcuts = [{
+		pattern     : 'f1',
+		description : this.title
+	}];
+	
+	setTimeout(function() {
+		var parts = self.options.view || ['about', 'shortcuts', 'help'];
+		
+		$.each(parts, function(i, title) {
+			html.push(tab[r](/\{id\}/, title)[r](/\{title\}/, fm.i18n(title)));
+		});
+		
+		html.push('</ul>');
+
+		$.inArray('about', parts) !== -1 && about();
+		$.inArray('shortcuts', parts) !== -1 && shortcuts();
+		$.inArray('help', parts) !== -1 && help();
+		
+		html.push('</div>');
+		content = $(html.join(''));
+		
+		fm.one('load', function setapi() { content.find('#apiver').text(fm.api); });
+		
+		content.find('.ui-tabs-nav li')
+			.hover(function() {
+				$(this).toggleClass('ui-state-hover')
+			})
+			.children()
+			.click(function(e) {
+				var link = $(this);
+				
+				e.preventDefault();
+				e.stopPropagation();
+				
+				if (!link.is('.ui-tabs-selected')) {
+					link.parent().addClass('ui-tabs-selected ui-state-active').siblings().removeClass('ui-tabs-selected').removeClass('ui-state-active');
+					content.find('.ui-tabs-panel').hide().filter(link.attr('href')).show();
+				}
+				
+			})
+			.filter(':first').click();
+		
+	}, 200)
+	
+	this.getstate = function() {
+		return 0;
+	}
+	
+	this.exec = function() {
+		if (!this.dialog) {
+			this.dialog = this.fm.dialog(content, {title : this.title, width : 530, autoOpen : false, destroyOnClose : false});
+		}
+		
+		this.dialog.elfinderdialog('open').find('.ui-tabs-nav li a:first').click();
+	}
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/home.js
+ */
+
+
+elFinder.prototype.commands.home = function() {
+	this.title = 'Home';
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+	this.shortcuts = [{
+		pattern     : 'ctrl+home ctrl+shift+up',
+		description : 'Home'
+	}];
+	
+	this.getstate = function() {
+		var root = this.fm.root(),
+			cwd  = this.fm.cwd().hash;
+			
+		return root && cwd && root != cwd ? 0: -1;
+	}
+	
+	this.exec = function() {
+		return this.fm.exec('open', this.fm.root());
+	}
+	
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/info.js
+ */
+
+/**
+ * @class elFinder command "info". 
+ * Display dialog with file properties.
+ *
+ * @author Dmitry (dio) Levashov, dio@std42.ru
+ **/
+elFinder.prototype.commands.info = function() {
+	var m   = 'msg',
+		fm  = this.fm,
+		spclass = 'elfinder-info-spinner',
+		msg = {
+			calc     : fm.i18n('calc'),
+			size     : fm.i18n('size'),
+			unknown  : fm.i18n('unknown'),
+			path     : fm.i18n('path'),
+			aliasfor : fm.i18n('aliasfor'),
+			modify   : fm.i18n('modify'),
+			perms    : fm.i18n('perms'),
+			locked   : fm.i18n('locked'),
+			dim      : fm.i18n('dim'),
+			kind     : fm.i18n('kind'),
+			files    : fm.i18n('files'),
+			folders  : fm.i18n('folders'),
+			items    : fm.i18n('items'),
+			yes      : fm.i18n('yes'),
+			no       : fm.i18n('no'),
+			link     : fm.i18n('link')
+		};
+		
+	this.tpl = {
+		main       : '<div class="ui-helper-clearfix elfinder-info-title"><span class="elfinder-cwd-icon {class} ui-corner-all"/>{title}</div><table class="elfinder-info-tb">{content}</table>',
+		itemTitle  : '<strong>{name}</strong><span class="elfinder-info-kind">{kind}</span>',
+		groupTitle : '<strong>{items}: {num}</strong>',
+		row        : '<tr><td>{label} : </td><td>{value}</td></tr>',
+		spinner    : '<span>{text}</span> <span class="'+spclass+'"/>'
+	}
+	
+	this.alwaysEnabled = true;
+	this.updateOnSelect = false;
+	this.shortcuts = [{
+		pattern     : 'ctrl+i'
+	}];
+	
+	this.init = function() {
+		$.each(msg, function(k, v) {
+			msg[k] = fm.i18n(v);
+		});
+	}
+	
+	this.getstate = function() {
+		return 0;
+	}
+	
+	this.exec = function(hashes) {
+		var files   = this.files(hashes);
+		if (! files.length) {
+			files   = this.files([ this.fm.cwd().hash ]);
+		}
+		var self    = this,
+			fm      = this.fm,
+			tpl     = this.tpl,
+			row     = tpl.row,
+			cnt     = files.length,
+			content = [],
+			view    = tpl.main,
+			l       = '{label}',
+			v       = '{value}',
+			opts    = {
+				title : this.title,
+				width : 'auto',
+				close : function() { $(this).elfinderdialog('destroy'); }
+			},
+			count = [],
+			replSpinner = function(msg) { dialog.find('.'+spclass).parent().text(msg); },
+			id = fm.namespace+'-info-'+$.map(files, function(f) { return f.hash }).join('-'),
+			dialog = fm.getUI().find('#'+id), 
+			size, tmb, file, title, dcnt;
+			
+		if (!cnt) {
+			return $.Deferred().reject();
+		}
+			
+		if (dialog.length) {
+			dialog.elfinderdialog('toTop');
+			return $.Deferred().resolve();
+		}
+		
+			
+		if (cnt == 1) {
+			file  = files[0];
+			
+			view  = view.replace('{class}', fm.mime2class(file.mime));
+			title = tpl.itemTitle.replace('{name}', fm.escape(file.i18 || file.name)).replace('{kind}', fm.mime2kind(file));
+
+			if (file.tmb) {
+				tmb = fm.option('tmbUrl')+file.tmb;
+			}
+			
+			if (!file.read) {
+				size = msg.unknown;
+			} else if (file.mime != 'directory' || file.alias) {
+				size = fm.formatSize(file.size);
+			} else {
+				size = tpl.spinner.replace('{text}', msg.calc);
+				count.push(file.hash);
+			}
+			
+			content.push(row.replace(l, msg.size).replace(v, size));
+			file.alias && content.push(row.replace(l, msg.aliasfor).replace(v, file.alias));
+			content.push(row.replace(l, msg.path).replace(v, fm.escape(fm.path(file.hash, true))));
+			file.read && content.push(row.replace(l, msg.link).replace(v,  '<a href="'+fm.url(file.hash)+'" target="_blank">'+file.name+'</a>'));
+			
+			if (file.dim) { // old api
+				content.push(row.replace(l, msg.dim).replace(v, file.dim));
+			} else if (file.mime.indexOf('image') !== -1) {
+				if (file.width && file.height) {
+					content.push(row.replace(l, msg.dim).replace(v, file.width+'x'+file.height));
+				} else {
+					content.push(row.replace(l, msg.dim).replace(v, tpl.spinner.replace('{text}', msg.calc)));
+					fm.request({
+						data : {cmd : 'dim', target : file.hash},
+						preventDefault : true
+					})
+					.fail(function() {
+						replSpinner(msg.unknown);
+					})
+					.done(function(data) {
+						replSpinner(data.dim || msg.unknown);
+						if (data.dim) {
+							var dim = data.dim.split('x');
+							var rfile = fm.file(file.hash);
+							rfile.width = dim[0];
+							rfile.height = dim[1];
+						}
+					});
+				}
+			}
+			
+			
+			content.push(row.replace(l, msg.modify).replace(v, fm.formatDate(file)));
+			content.push(row.replace(l, msg.perms).replace(v, fm.formatPermissions(file)));
+			content.push(row.replace(l, msg.locked).replace(v, file.locked ? msg.yes : msg.no));
+		} else {
+			view  = view.replace('{class}', 'elfinder-cwd-icon-group');
+			title = tpl.groupTitle.replace('{items}', msg.items).replace('{num}', cnt);
+			dcnt  = $.map(files, function(f) { return f.mime == 'directory' ? 1 : null }).length;
+			if (!dcnt) {
+				size = 0;
+				$.each(files, function(h, f) { 
+					var s = parseInt(f.size);
+					
+					if (s >= 0 && size >= 0) {
+						size += s;
+					} else {
+						size = 'unknown';
+					}
+				});
+				content.push(row.replace(l, msg.kind).replace(v, msg.files));
+				content.push(row.replace(l, msg.size).replace(v, fm.formatSize(size)));
+			} else {
+				content.push(row.replace(l, msg.kind).replace(v, dcnt == cnt ? msg.folders : msg.folders+' '+dcnt+', '+msg.files+' '+(cnt-dcnt)))
+				content.push(row.replace(l, msg.size).replace(v, tpl.spinner.replace('{text}', msg.calc)));
+				count = $.map(files, function(f) { return f.hash });
+				
+			}
+		}
+		
+		view = view.replace('{title}', title).replace('{content}', content.join(''));
+		
+		dialog = fm.dialog(view, opts);
+		dialog.attr('id', id)
+
+		// load thumbnail
+		if (tmb) {
+			$('<img/>')
+				.load(function() { dialog.find('.elfinder-cwd-icon').css('background', 'url("'+tmb+'") center center no-repeat'); })
+				.attr('src', tmb);
+		}
+		
+		// send request to count total size
+		if (count.length) {
+			fm.request({
+					data : {cmd : 'size', targets : count},
+					preventDefault : true
+				})
+				.fail(function() {
+					replSpinner(msg.unknown);
+				})
+				.done(function(data) {
+					var size = parseInt(data.size);
+					replSpinner(size >= 0 ? fm.formatSize(size) : msg.unknown);
+				});
+		}
+		
+	}
+	
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/mkdir.js
+ */
+
+/**
+ * @class  elFinder command "mkdir"
+ * Create new folder
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.mkdir = function() {
+	this.disableOnSearch = true;
+	this.updateOnSelect  = false;
+	this.mime            = 'directory';
+	this.prefix          = 'untitled folder';
+	this.exec            = $.proxy(this.fm.res('mixin', 'make'), this);
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+shift+n'
+	}];
+	
+	this.getstate = function() {
+		return !this._disabled && this.fm.cwd().write ? 0 : -1;
+	}
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/mkfile.js
+ */
+
+/**
+ * @class  elFinder command "mkfile"
+ * Create new empty file
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.mkfile = function() {
+	this.disableOnSearch = true;
+	this.updateOnSelect  = false;
+	this.mime            = 'text/plain';
+	this.prefix          = 'untitled file.txt';
+	this.exec            = $.proxy(this.fm.res('mixin', 'make'), this);
+	
+	this.getstate = function() {
+		return !this._disabled && this.fm.cwd().write ? 0 : -1;
+	}
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/netmount.js
+ */
+
+/**
+ * @class  elFinder command "netmount"
+ * Mount network volume with user credentials.
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.netmount = function() {
+	var self = this;
+
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+
+	this.drivers = [];
+	
+	this.handlers = {
+		load : function() {
+			this.drivers = this.fm.netDrivers;
+		}
+	}
+
+	this.getstate = function() {
+		return this.drivers.length ? 0 : -1;
+	}
+	
+	this.exec = function() {
+		var fm = self.fm,
+			dfrd = $.Deferred(),
+			create = function() {
+				var inputs = {
+						protocol : $('<select/>'),
+						host     : $('<input type="text"/>'),
+						port     : $('<input type="text"/>'),
+						path     : $('<input type="text" value="/"/>'),
+						user     : $('<input type="text"/>'),
+						pass     : $('<input type="password"/>')
+					},
+					opts = {
+						title          : fm.i18n('netMountDialogTitle'),
+						resizable      : false,
+						modal          : true,
+						destroyOnClose : true,
+						close          : function() { 
+							delete self.dialog; 
+							dfrd.state() == 'pending' && dfrd.reject();
+						},
+						buttons        : {}
+					},
+					content = $('<table class="elfinder-info-tb elfinder-netmount-tb"/>');
+
+				$.each(self.drivers, function(i, protocol) {
+					inputs.protocol.append('<option value="'+protocol+'">'+fm.i18n(protocol)+'</option>');
+				});
+
+
+				$.each(inputs, function(name, input) {
+					name != 'protocol' && input.addClass('ui-corner-all');
+					content.append($('<tr/>').append($('<td>'+fm.i18n(name)+'</td>')).append($('<td/>').append(input)));
+				});
+
+				opts.buttons[fm.i18n('btnMount')] = function() {
+					var data = {cmd : 'netmount'};
+
+					$.each(inputs, function(name, input) {
+						var val = $.trim(input.val());
+
+						if (val) {
+							data[name] = val;
+						}
+					});
+
+					if (!data.host) {
+						return self.fm.trigger('error', {error : 'errNetMountHostReq'});
+					}
+
+					self.fm.request({data : data, notify : {type : 'netmount', cnt : 1}})
+						.done(function() { dfrd.resolve(); })
+						.fail(function(error) { dfrd.reject(error); });
+
+					self.dialog.elfinderdialog('close');	
+				}
+
+				opts.buttons[fm.i18n('btnCancel')] = function() {
+					self.dialog.elfinderdialog('close');
+				}
+
+				return fm.dialog(content, opts);
+			}
+			;
+
+		if (!self.dialog) {
+			self.dialog = create()
+		}
+
+		return dfrd.promise();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/open.js
+ */
+
+/**
+ * @class  elFinder command "open"
+ * Enter folder or open files in new windows
+ *
+ * @author Dmitry (dio) Levashov
+ **/  
+elFinder.prototype.commands.open = function() {
+	this.alwaysEnabled = true;
+	
+	this._handlers = {
+		dblclick : function(e) { e.preventDefault(); this.exec() },
+		'select enable disable reload' : function(e) { this.update(e.type == 'disable' ? -1 : void(0));  }
+	}
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+down numpad_enter'+(this.fm.OS != 'mac' && ' enter')
+	}];
+
+	this.getstate = function(sel) {
+		var sel = this.files(sel),
+			cnt = sel.length;
+		
+		return cnt == 1 
+			? 0 
+			: cnt ? ($.map(sel, function(file) { return file.mime == 'directory' ? null : file}).length == cnt ? 0 : -1) : -1
+	}
+	
+	this.exec = function(hashes) {
+		var fm    = this.fm, 
+			dfrd  = $.Deferred().fail(function(error) { error && fm.error(error); }),
+			files = this.files(hashes),
+			cnt   = files.length,
+			file, url, s, w;
+
+		if (!cnt) {
+			return dfrd.reject();
+		}
+
+		// open folder
+		if (cnt == 1 && (file = files[0]) && file.mime == 'directory') {
+			return file && !file.read
+				? dfrd.reject(['errOpen', file.name, 'errPerm'])
+				: fm.request({
+						data   : {cmd  : 'open', target : file.thash || file.hash},
+						notify : {type : 'open', cnt : 1, hideCnt : true},
+						syncOnFail : true
+					});
+		}
+		
+		files = $.map(files, function(file) { return file.mime != 'directory' ? file : null });
+		
+		// nothing to open or files and folders selected - do nothing
+		if (cnt != files.length) {
+			return dfrd.reject();
+		}
+		
+		// open files
+		cnt = files.length;
+		while (cnt--) {
+			file = files[cnt];
+			
+			if (!file.read) {
+				return dfrd.reject(['errOpen', file.name, 'errPerm']);
+			}
+			
+			if (!(url = fm.url(/*file.thash || */file.hash))) {
+				url = fm.options.url;
+				url = url + (url.indexOf('?') === -1 ? '?' : '&')
+					+ (fm.oldAPI ? 'cmd=open&current='+file.phash : 'cmd=file')
+					+ '&target=' + file.hash;
+			}
+			
+			// set window size for image if set
+			if (file.dim) {
+				s = file.dim.split('x');
+				w = 'width='+(parseInt(s[0])+20) + ',height='+(parseInt(s[1])+20);
+			} else {
+				w = 'width='+parseInt(2*$(window).width()/3)+',height='+parseInt(2*$(window).height()/3);
+			}
+
+			var wnd = window.open('', 'new_window', w + ',top=50,left=50,scrollbars=yes,resizable=yes');
+			if (!wnd) {
+				return dfrd.reject('errPopup');
+			}
+			
+			var form = document.createElement("form");
+			form.action = fm.options.url;
+			form.method = 'POST';
+			form.target = 'new_window';
+			form.style.display = 'none';
+			var params = $.extend({}, fm.options.customData, {
+				cmd: 'file',
+				target: file.hash
+			});
+			$.each(params, function(key, val)
+			{
+				var input = document.createElement("input");
+				input.name = key;
+				input.value = val;
+				form.appendChild(input);
+			});
+			
+			document.body.appendChild(form);
+			form.submit();
+		}
+		return dfrd.resolve(hashes);
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/paste.js
+ */
+
+/**
+ * @class  elFinder command "paste"
+ * Paste filesfrom clipboard into directory.
+ * If files pasted in its parent directory - files duplicates will created
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.paste = function() {
+	
+	this.updateOnSelect  = false;
+	
+	this.handlers = {
+		changeclipboard : function() { this.update(); }
+	}
+
+	this.shortcuts = [{
+		pattern     : 'ctrl+v shift+insert'
+	}];
+	
+	this.getstate = function(dst) {
+		if (this._disabled) {
+			return -1;
+		}
+		if (dst) {
+			if ($.isArray(dst)) {
+				if (dst.length != 1) {
+					return -1;
+				}
+				dst = this.fm.file(dst[0]);
+			}
+		} else {
+			dst = this.fm.cwd();
+		}
+
+		return this.fm.clipboard().length && dst.mime == 'directory' && dst.write ? 0 : -1;
+	}
+	
+	this.exec = function(dst) {
+		var self   = this,
+			fm     = self.fm,
+			dst    = dst ? this.files(dst)[0] : fm.cwd(),
+			files  = fm.clipboard(),
+			cnt    = files.length,
+			cut    = cnt ? files[0].cut : false,
+			error  = cut ? 'errMove' : 'errCopy',
+			fpaste = [],
+			fcopy  = [],
+			dfrd   = $.Deferred()
+				.fail(function(error) {
+					error && fm.error(error);
+				}),
+			copy  = function(files) {
+				return files.length && fm._commands.duplicate
+					? fm.exec('duplicate', files)
+					: $.Deferred().resolve();
+			},
+			paste = function(files) {
+				var dfrd      = $.Deferred(),
+					existed   = [],
+					intersect = function(files, names) {
+						var ret = [], 
+							i   = files.length;
+
+						while (i--) {
+							$.inArray(files[i].name, names) !== -1 && ret.unshift(i);
+						}
+						return ret;
+					},
+					confirm   = function(ndx) {
+						var i    = existed[ndx],
+							file = files[i],
+							last = ndx == existed.length-1;
+
+						if (!file) {
+							return;
+						}
+
+						fm.confirm({
+							title  : fm.i18n(cut ? 'moveFiles' : 'copyFiles'),
+							text   : fm.i18n(['errExists', file.name, 'confirmRepl']), 
+							all    : !last,
+							accept : {
+								label    : 'btnYes',
+								callback : function(all) {
+									!last && !all
+										? confirm(++ndx)
+										: paste(files);
+								}
+							},
+							reject : {
+								label    : 'btnNo',
+								callback : function(all) {
+									var i;
+
+									if (all) {
+										i = existed.length;
+										while (ndx < i--) {
+											files[existed[i]].remove = true
+										}
+									} else {
+										files[existed[ndx]].remove = true;
+									}
+
+									!last && !all
+										? confirm(++ndx)
+										: paste(files);
+								}
+							},
+							cancel : {
+								label    : 'btnCancel',
+								callback : function() {
+									dfrd.resolve();
+								}
+							}
+						})
+					},
+					valid     = function(names) {
+						existed = intersect(files, names);
+						existed.length ? confirm(0) : paste(files);
+					},
+					paste     = function(files) {
+						var files  = $.map(files, function(file) { return !file.remove ? file : null } ),
+							cnt    = files.length,
+							groups = {},
+							args   = [],
+							src;
+
+						if (!cnt) {
+							return dfrd.resolve();
+						}
+
+						src = files[0].phash;
+						files = $.map(files, function(f) { return f.hash});
+						
+						fm.request({
+								data   : {cmd : 'paste', dst : dst.hash, targets : files, cut : cut ? 1 : 0, src : src},
+								notify : {type : cut ? 'move' : 'copy', cnt : cnt}
+							})
+							.always(function() {
+								dfrd.resolve();
+								fm.unlockfiles({files : files});
+							});
+					}
+					;
+
+				if (self._disabled || !files.length) {
+					return dfrd.resolve();
+				}
+				
+					
+				if (fm.oldAPI) {
+					paste(files);
+				} else {
+					
+					if (!fm.option('copyOverwrite')) {
+						paste(files);
+					} else {
+
+						dst.hash == fm.cwd().hash
+							? valid($.map(fm.files(), function(file) { return file.phash == dst.hash ? file.name : null }))
+							: fm.request({
+								data : {cmd : 'ls', target : dst.hash},
+								notify : {type : 'prepare', cnt : 1, hideCnt : true},
+								preventFail : true
+							})
+							.always(function(data) {
+								valid(data.list || [])
+							});
+					}
+				}
+				
+				return dfrd;
+			},
+			parents, fparents;
+
+
+		if (!cnt || !dst || dst.mime != 'directory') {
+			return dfrd.reject();
+		}
+			
+		if (!dst.write)	{
+			return dfrd.reject([error, files[0].name, 'errPerm']);
+		}
+		
+		parents = fm.parents(dst.hash);
+		
+		$.each(files, function(i, file) {
+			if (!file.read) {
+				return !dfrd.reject([error, files[0].name, 'errPerm']);
+			}
+			
+			if (cut && file.locked) {
+				return !dfrd.reject(['errLocked', file.name]);
+			}
+			
+			if ($.inArray(file.hash, parents) !== -1) {
+				return !dfrd.reject(['errCopyInItself', file.name]);
+			}
+			
+			fparents = fm.parents(file.hash);
+			if ($.inArray(dst.hash, fparents) !== -1) {
+				
+				if ($.map(fparents, function(h) { var d = fm.file(h); return d.phash == dst.hash && d.name == file.name ? d : null }).length) {
+					return !dfrd.reject(['errReplByChild', file.name]);
+				}
+			}
+			
+			if (file.phash == dst.hash) {
+				fcopy.push(file.hash);
+			} else {
+				fpaste.push({
+					hash  : file.hash,
+					phash : file.phash,
+					name  : file.name
+				});
+			}
+		});
+
+		if (dfrd.state() == 'rejected') {
+			return dfrd;
+		}
+
+		return $.when(
+			copy(fcopy),
+			paste(fpaste)
+		).always(function() {
+			cut && fm.clipboard([]);
+		});
+	}
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/quicklook.js
+ */
+
+/**
+ * @class  elFinder command "quicklook"
+ * Fast preview for some files types
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.quicklook = function() {
+	var self       = this,
+		fm         = self.fm,
+		/**
+		 * window closed state
+		 *
+		 * @type Number
+		 **/
+		closed     = 0,
+		/**
+		 * window animated state
+		 *
+		 * @type Number
+		 **/
+		animated   = 1,
+		/**
+		 * window opened state
+		 *
+		 * @type Number
+		 **/
+		opened     = 2,
+		/**
+		 * window state
+		 *
+		 * @type Number
+		 **/
+		state      = closed,
+		/**
+		 * next/prev event name (requied to cwd catch it)
+		 *
+		 * @type Number
+		 **/
+		// keydown    = fm.UA.Firefox || fm.UA.Opera ? 'keypress' : 'keydown',
+		/**
+		 * navbar icon class
+		 *
+		 * @type Number
+		 **/
+		navicon    = 'elfinder-quicklook-navbar-icon',
+		/**
+		 * navbar "fullscreen" icon class
+		 *
+		 * @type Number
+		 **/
+		fullscreen  = 'elfinder-quicklook-fullscreen',
+		/**
+		 * Triger keydown/keypress event with left/right arrow key code
+		 *
+		 * @param  Number  left/right arrow key code
+		 * @return void
+		 **/
+		navtrigger = function(code) {
+			$(document).trigger($.Event('keydown', { keyCode: code, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));
+		},
+		/**
+		 * Return css for closed window
+		 *
+		 * @param  jQuery  file node in cwd
+		 * @return void
+		 **/
+		closedCss = function(node) {
+			return {
+				opacity : 0,
+				width   : 20,//node.width(),
+				height  : fm.view == 'list' ? 1 : 20,
+				top     : node.offset().top+'px', 
+				left    : node.offset().left+'px' 
+			}
+		},
+		/**
+		 * Return css for opened window
+		 *
+		 * @return void
+		 **/
+		openedCss = function() {
+			var win = $(window);
+			return {
+				opacity : 1,
+				width  : width,
+				height : height,
+				top    : parseInt((win.height() - height)/2 + win.scrollTop()),
+				left   : parseInt((win.width() - width)/2 + win.scrollLeft())
+			}
+		},
+		
+		support = function(codec) {
+			var media = document.createElement(codec.substr(0, codec.indexOf('/'))),
+				value = false;
+			
+			try {
+				value = media.canPlayType && media.canPlayType(codec);
+			} catch (e) {
+				
+			}
+			
+			return value && value !== '' && value != 'no';
+		},
+		
+		/**
+		 * Opened window width (from config)
+		 *
+		 * @type Number
+		 **/
+		width, 
+		/**
+		 * Opened window height (from config)
+		 *
+		 * @type Number
+		 **/
+		height, 
+		/**
+		 * elFinder node
+		 *
+		 * @type jQuery
+		 **/
+		parent, 
+		/**
+		 * elFinder current directory node
+		 *
+		 * @type jQuery
+		 **/
+		cwd, 
+		title   = $('<div class="elfinder-quicklook-title"/>'),
+		icon    = $('<div/>'),
+		info    = $('<div class="elfinder-quicklook-info"/>'),//.hide(),
+		fsicon  = $('<div class="'+navicon+' '+navicon+'-fullscreen"/>')
+			.mousedown(function(e) {
+				var win     = self.window,
+					full    = win.is('.'+fullscreen),
+					scroll  = 'scroll.'+fm.namespace,
+					$window = $(window);
+					
+				e.stopPropagation();
+				
+				if (full) {
+					win.css(win.data('position')).unbind('mousemove');
+					$window.unbind(scroll).trigger(self.resize).unbind(self.resize);
+					navbar.unbind('mouseenter').unbind('mousemove');
+				} else {
+					win.data('position', {
+						left   : win.css('left'), 
+						top    : win.css('top'), 
+						width  : win.width(), 
+						height : win.height()
+					})
+					.css({
+						width  : '100%',
+						height : '100%'
+					});
+
+					$(window).bind(scroll, function() {
+						win.css({
+							left   : parseInt($(window).scrollLeft())+'px',
+							top    : parseInt($(window).scrollTop()) +'px'
+						})
+					})
+					.bind(self.resize, function(e) {
+						self.preview.trigger('changesize');
+					})
+					.trigger(scroll)
+					.trigger(self.resize);
+					
+					win.bind('mousemove', function(e) {
+						navbar.stop(true, true).show().delay(3000).fadeOut('slow');
+					})
+					.mousemove();
+					
+					navbar.mouseenter(function() {
+						navbar.stop(true, true).show();
+					})
+					.mousemove(function(e) {
+						e.stopPropagation();
+					});
+				}
+				navbar.attr('style', '').draggable(full ? 'destroy' : {});
+				win.toggleClass(fullscreen);
+				$(this).toggleClass(navicon+'-fullscreen-off');
+				$.fn.resizable && parent.add(win).resizable(full ? 'enable' : 'disable').removeClass('ui-state-disabled');
+			}),
+			
+		navbar  = $('<div class="elfinder-quicklook-navbar"/>')
+			.append($('<div class="'+navicon+' '+navicon+'-prev"/>').mousedown(function() { navtrigger(37); }))
+			.append(fsicon)
+			.append($('<div class="'+navicon+' '+navicon+'-next"/>').mousedown(function() { navtrigger(39); }))
+			.append('<div class="elfinder-quicklook-navbar-separator"/>')
+			.append($('<div class="'+navicon+' '+navicon+'-close"/>').mousedown(function() { self.window.trigger('close'); }))
+		;
+
+	this.resize = 'resize.'+fm.namespace;
+	this.info = $('<div class="elfinder-quicklook-info-wrapper"/>')
+		.append(icon)
+		.append(info);
+		
+	this.preview = $('<div class="elfinder-quicklook-preview ui-helper-clearfix"/>')
+		// clean info/icon
+		.bind('change', function(e) {
+			self.info.attr('style', '').hide();
+			icon.removeAttr('class').attr('style', '');
+			info.html('');
+
+		})
+		// update info/icon
+		.bind('update', function(e) {
+			var fm      = self.fm,
+				preview = self.preview,
+				file    = e.file,
+				tpl     = '<div class="elfinder-quicklook-info-data">{value}</div>',
+				tmb;
+
+			if (file) {
+				!file.read && e.stopImmediatePropagation();
+				self.window.data('hash', file.hash);
+				self.preview.unbind('changesize').trigger('change').children().remove();
+				title.html(fm.escape(file.name));
+				
+				info.html(
+						tpl.replace(/\{value\}/, file.name)
+						+ tpl.replace(/\{value\}/, fm.mime2kind(file))
+						+ (file.mime == 'directory' ? '' : tpl.replace(/\{value\}/, fm.formatSize(file.size)))
+						+ tpl.replace(/\{value\}/, fm.i18n('modify')+': '+ fm.formatDate(file))
+					)
+				icon.addClass('elfinder-cwd-icon ui-corner-all '+fm.mime2class(file.mime));
+
+				if (file.tmb) {
+					$('<img/>')
+						.hide()
+						.appendTo(self.preview)
+						.load(function() {
+							icon.css('background', 'url("'+tmb+'") center center no-repeat');
+							$(this).remove();
+						})
+						.attr('src', (tmb = fm.tmb(file.hash)));
+				}
+				self.info.delay(100).fadeIn(10);
+			} else { 
+				e.stopImmediatePropagation();
+			}
+		});
+		
+
+	
+
+	this.window = $('<div class="ui-helper-reset ui-widget elfinder-quicklook" style="position:absolute"/>')
+		.click(function(e) { e.stopPropagation();  })
+		.append(
+			$('<div class="elfinder-quicklook-titlebar"/>')
+				.append(title)
+				.append($('<span class="ui-icon ui-icon-circle-close"/>').mousedown(function(e) {
+					e.stopPropagation();
+					self.window.trigger('close');
+				}))
+		)
+		.append(this.preview.add(navbar))
+		.append(self.info.hide())
+		.draggable({handle : 'div.elfinder-quicklook-titlebar'})
+		.bind('open', function(e) {
+			var win  = self.window, 
+				file = self.value,
+				node;
+
+			if (self.closed() && file && (node = cwd.find('#'+file.hash)).length) {
+				navbar.attr('style', '');
+				state = animated;
+				node.trigger('scrolltoview');
+				win.css(closedCss(node))
+					.show()
+					.animate(openedCss(), 550, function() {
+						state = opened;
+						self.update(1, self.value);
+					});
+			}
+		})
+		.bind('close', function(e) {
+			var win     = self.window,
+				preview = self.preview.trigger('change'),
+				file    = self.value,
+				node    = cwd.find('#'+win.data('hash')),
+				close   = function() {
+					state = closed;
+					win.hide();
+					preview.children().remove();
+					self.update(0, self.value);
+					
+				};
+				
+			if (self.opened()) {
+				state = animated;
+				win.is('.'+fullscreen) && fsicon.mousedown()
+				node.length
+					? win.animate(closedCss(node), 500, close)
+					: close();
+			}
+		});
+
+	/**
+	 * This command cannot be disable by backend
+	 *
+	 * @type Boolean
+	 **/
+	this.alwaysEnabled = true;
+	
+	/**
+	 * Selected file
+	 *
+	 * @type Object
+	 **/
+	this.value = null;
+	
+	this.handlers = {
+		// save selected file
+		select : function() { this.update(void(0), this.fm.selectedFiles()[0]); },
+		error  : function() { self.window.is(':visible') && self.window.data('hash', '').trigger('close'); },
+		'searchshow searchhide' : function() { this.opened() && this.window.trigger('close'); }
+	}
+	
+	this.shortcuts = [{
+		pattern     : 'space'
+	}];
+	
+	this.support = {
+		audio : {
+			ogg : support('audio/ogg; codecs="vorbis"'),
+			mp3 : support('audio/mpeg;'),
+			wav : support('audio/wav; codecs="1"'),
+			m4a : support('audio/x-m4a;') || support('audio/aac;')
+		},
+		video : {
+			ogg  : support('video/ogg; codecs="theora"'),
+			webm : support('video/webm; codecs="vp8, vorbis"'),
+			mp4  : support('video/mp4; codecs="avc1.42E01E"') || support('video/mp4; codecs="avc1.42E01E, mp4a.40.2"') 
+		}
+	}
+	
+	
+	/**
+	 * Return true if quickLoock window is visible and not animated
+	 *
+	 * @return Boolean
+	 **/
+	this.closed = function() {
+		return state == closed;
+	}
+	
+	/**
+	 * Return true if quickLoock window is hidden
+	 *
+	 * @return Boolean
+	 **/
+	this.opened = function() {
+		return state == opened;
+	}
+	
+	/**
+	 * Init command.
+	 * Add default plugins and init other plugins
+	 *
+	 * @return Object
+	 **/
+	this.init = function() {
+		var o       = this.options, 
+			win     = this.window,
+			preview = this.preview,
+			i, p;
+		
+		width  = o.width  > 0 ? parseInt(o.width)  : 450;	
+		height = o.height > 0 ? parseInt(o.height) : 300;
+
+		fm.one('load', function() {
+			parent = fm.getUI();
+			cwd    = fm.getUI('cwd');
+
+			win.appendTo('body').zIndex(100 + parent.zIndex());
+			
+			// close window on escape
+			$(document).keydown(function(e) {
+				e.keyCode == 27 && self.opened() && win.trigger('close')
+			})
+			
+			if ($.fn.resizable) {
+				win.resizable({ 
+					handles   : 'se', 
+					minWidth  : 350, 
+					minHeight : 120, 
+					resize    : function() { 
+						// use another event to avoid recursion in fullscreen mode
+						// may be there is clever solution, but i cant find it :(
+						preview.trigger('changesize'); 
+					}
+				});
+			}
+			
+			self.change(function() {
+				if (self.opened()) {
+					self.value ? preview.trigger($.Event('update', {file : self.value})) : win.trigger('close');
+				}
+			});
+			
+			$.each(fm.commands.quicklook.plugins || [], function(i, plugin) {
+				if (typeof(plugin) == 'function') {
+					new plugin(self)
+				}
+			});
+			
+			preview.bind('update', function() {
+				self.info.show();
+			});
+		});
+		
+	}
+	
+	this.getstate = function() {
+		return this.fm.selected().length == 1 ? state == opened ? 1 : 0 : -1;
+	}
+	
+	this.exec = function() {
+		this.enabled() && this.window.trigger(this.opened() ? 'close' : 'open');
+	}
+
+	this.hideinfo = function() {
+		this.info.stop(true).hide();
+	}
+
+}
+
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/quicklook.plugins.js
+ */
+
+
+elFinder.prototype.commands.quicklook.plugins = [
+	
+	/**
+	 * Images preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var mimes   = ['image/jpeg', 'image/png', 'image/gif'],
+			preview = ql.preview;
+		
+		// what kind of images we can display
+		$.each(navigator.mimeTypes, function(i, o) {
+			var mime = o.type;
+			
+			if (mime.indexOf('image/') === 0 && $.inArray(mime, mimes)) {
+				mimes.push(mime);
+			} 
+		});
+			
+		preview.bind('update', function(e) {
+			var file = e.file,
+				img;
+
+			if ($.inArray(file.mime, mimes) !== -1) {
+				// this is our file - stop event propagation
+				e.stopImmediatePropagation();
+
+				img = $('<img/>')
+					.hide()
+					.appendTo(preview)
+					.load(function() {
+						// timeout - because of strange safari bug - 
+						// sometimes cant get image height 0_o
+						setTimeout(function() {
+							var prop = (img.width()/img.height()).toFixed(2);
+							preview.bind('changesize', function() {
+								var pw = parseInt(preview.width()),
+									ph = parseInt(preview.height()),
+									w, h;
+							
+								if (prop < (pw/ph).toFixed(2)) {
+									h = ph;
+									w = Math.floor(h * prop);
+								} else {
+									w = pw;
+									h = Math.floor(w/prop);
+								}
+								img.width(w).height(h).css('margin-top', h < ph ? Math.floor((ph - h)/2) : 0);
+							
+							})
+							.trigger('changesize');
+							
+							// hide info/icon
+							ql.hideinfo();
+							//show image
+							img.fadeIn(100);
+						}, 1)
+					})
+					.attr('src', ql.fm.url(file.hash));
+			}
+			
+		});
+	},
+	
+	/**
+	 * HTML preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var mimes   = ['text/html', 'application/xhtml+xml'],
+			preview = ql.preview,
+			fm      = ql.fm;
+			
+		preview.bind('update', function(e) {
+			var file = e.file, jqxhr;
+			
+			if ($.inArray(file.mime, mimes) !== -1) {
+				e.stopImmediatePropagation();
+
+				// stop loading on change file if not loaded yet
+				preview.one('change', function() {
+					jqxhr.state() == 'pending' && jqxhr.reject();
+				});
+				
+				jqxhr = fm.request({
+					data           : {cmd : 'get', target  : file.hash, current : file.phash},
+					preventDefault : true
+				})
+				.done(function(data) {
+					ql.hideinfo();
+					doc = $('<iframe class="elfinder-quicklook-preview-html"/>').appendTo(preview)[0].contentWindow.document;
+					doc.open();
+					doc.write(data.content);
+					doc.close();
+				});
+			}
+		})
+	},
+	
+	/**
+	 * Texts preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var fm      = ql.fm,
+			mimes   = fm.res('mimes', 'text'),
+			preview = ql.preview;
+				
+			
+		preview.bind('update', function(e) {
+			var file = e.file,
+				mime = file.mime,
+				jqxhr;
+			
+			if (mime.indexOf('text/') === 0 || $.inArray(mime, mimes) !== -1) {
+				e.stopImmediatePropagation();
+				
+				// stop loading on change file if not loadin yet
+				preview.one('change', function() {
+					jqxhr.state() == 'pending' && jqxhr.reject();
+				});
+				
+				jqxhr = fm.request({
+					data   : {cmd     : 'get', target  : file.hash },
+					preventDefault : true
+				})
+				.done(function(data) {
+					ql.hideinfo();
+					$('<div class="elfinder-quicklook-preview-text-wrapper"><pre class="elfinder-quicklook-preview-text">'+fm.escape(data.content)+'</pre></div>').appendTo(preview);
+				});
+			}
+		});
+	},
+	
+	/**
+	 * PDF preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var fm      = ql.fm,
+			mime    = 'application/pdf',
+			preview = ql.preview,
+			active  = false;
+			
+		if ((fm.UA.Safari && fm.OS == 'mac') || fm.UA.IE) {
+			active = true;
+		} else {
+			$.each(navigator.plugins, function(i, plugins) {
+				$.each(plugins, function(i, plugin) {
+					if (plugin.type == mime) {
+						return !(active = true);
+					}
+				});
+			});
+		}
+
+		active && preview.bind('update', function(e) {
+			var file = e.file, node;
+			
+			if (file.mime == mime) {
+				e.stopImmediatePropagation();
+				preview.one('change', function() {
+					node.unbind('load').remove();
+				});
+				
+				node = $('<iframe class="elfinder-quicklook-preview-pdf"/>')
+					.hide()
+					.appendTo(preview)
+					.load(function() { 
+						ql.hideinfo();
+						node.show(); 
+					})
+					.attr('src', fm.url(file.hash));
+			}
+			
+		})
+		
+			
+	},
+	
+	/**
+	 * Flash preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var fm      = ql.fm,
+			mime    = 'application/x-shockwave-flash',
+			preview = ql.preview,
+			active  = false;
+
+		$.each(navigator.plugins, function(i, plugins) {
+			$.each(plugins, function(i, plugin) {
+				if (plugin.type == mime) {
+					return !(active = true);
+				}
+			});
+		});
+		
+		active && preview.bind('update', function(e) {
+			var file = e.file,
+				node;
+				
+			if (file.mime == mime) {
+				e.stopImmediatePropagation();
+				ql.hideinfo();
+				preview.append((node = $('<embed class="elfinder-quicklook-preview-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="'+fm.url(file.hash)+'" quality="high" type="application/x-shockwave-flash" />')));
+			}
+		});
+	},
+	
+	/**
+	 * HTML5 audio preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var preview  = ql.preview,
+			autoplay = !!ql.options['autoplay'],
+			mimes    = {
+				'audio/mpeg'    : 'mp3',
+				'audio/mpeg3'   : 'mp3',
+				'audio/mp3'     : 'mp3',
+				'audio/x-mpeg3' : 'mp3',
+				'audio/x-mp3'   : 'mp3',
+				'audio/x-wav'   : 'wav',
+				'audio/wav'     : 'wav',
+				'audio/x-m4a'   : 'm4a',
+				'audio/aac'     : 'm4a',
+				'audio/mp4'     : 'm4a',
+				'audio/x-mp4'   : 'm4a',
+				'audio/ogg'     : 'ogg'
+			},
+			node;
+
+		preview.bind('update', function(e) {
+			var file = e.file,
+				type = mimes[file.mime];
+
+			if (ql.support.audio[type]) {
+				e.stopImmediatePropagation();
+				
+				node = $('<audio class="elfinder-quicklook-preview-audio" controls preload="auto" autobuffer><source src="'+ql.fm.url(file.hash)+'" /></audio>')
+					.appendTo(preview);
+				autoplay && node[0].play();
+			}
+		}).bind('change', function() {
+			if (node && node.parent().length) {
+				node[0].pause();
+				node.remove();
+				node= null;
+			}
+		});
+	},
+	
+	/**
+	 * HTML5 video preview plugin
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var preview  = ql.preview,
+			autoplay = !!ql.options['autoplay'],
+			mimes    = {
+				'video/mp4'       : 'mp4',
+				'video/x-m4v'     : 'mp4',
+				'video/ogg'       : 'ogg',
+				'application/ogg' : 'ogg',
+				'video/webm'      : 'webm'
+			},
+			node;
+
+		preview.bind('update', function(e) {
+			var file = e.file,
+				type = mimes[file.mime];
+				
+			if (ql.support.video[type]) {
+				e.stopImmediatePropagation();
+
+				ql.hideinfo();
+				node = $('<video class="elfinder-quicklook-preview-video" controls preload="auto" autobuffer><source src="'+ql.fm.url(file.hash)+'" /></video>').appendTo(preview);
+				autoplay && node[0].play();
+				
+			}
+		}).bind('change', function() {
+			if (node && node.parent().length) {
+				node[0].pause();
+				node.remove();
+				node= null;
+			}
+		});
+	},
+	
+	/**
+	 * Audio/video preview plugin using browser plugins
+	 *
+	 * @param elFinder.commands.quicklook
+	 **/
+	function(ql) {
+		var preview = ql.preview,
+			mimes   = [],
+			node;
+			
+		$.each(navigator.plugins, function(i, plugins) {
+			$.each(plugins, function(i, plugin) {
+				(plugin.type.indexOf('audio/') === 0 || plugin.type.indexOf('video/') === 0) && mimes.push(plugin.type);
+			});
+		});
+		
+		preview.bind('update', function(e) {
+			var file  = e.file,
+				mime  = file.mime,
+				video;
+			
+			if ($.inArray(file.mime, mimes) !== -1) {
+				e.stopImmediatePropagation();
+				(video = mime.indexOf('video/') === 0) && ql.hideinfo();
+				node = $('<embed src="'+ql.fm.url(file.hash)+'" type="'+mime+'" class="elfinder-quicklook-preview-'+(video ? 'video' : 'audio')+'"/>')
+					.appendTo(preview);
+			}
+		}).bind('change', function() {
+			if (node && node.parent().length) {
+				node.remove();
+				node= null;
+			}
+		});
+		
+	}
+	
+]
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/reload.js
+ */
+
+/**
+ * @class  elFinder command "reload"
+ * Sync files and folders
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.reload = function() {
+	
+	this.alwaysEnabled = true;
+	this.updateOnSelect = true;
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+shift+r f5'
+	}];
+	
+	this.getstate = function() {
+		return 0;
+	}
+	
+	this.exec = function() {
+		var fm      = this.fm,
+			dfrd    = fm.sync(),
+			timeout = setTimeout(function() {
+				fm.notify({type : 'reload', cnt : 1, hideCnt : true});
+				dfrd.always(function() { fm.notify({type : 'reload', cnt  : -1}); });
+			}, fm.notifyDelay);
+			
+		return dfrd.always(function() { 
+			clearTimeout(timeout); 
+			fm.trigger('reload');
+		});
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/rename.js
+ */
+
+/**
+ * @class elFinder command "rename". 
+ * Rename selected file.
+ *
+ * @author Dmitry (dio) Levashov, dio@std42.ru
+ **/
+elFinder.prototype.commands.rename = function() {
+	
+	this.shortcuts = [{
+		pattern     : 'f2'+(this.fm.OS == 'mac' ? ' enter' : '')
+	}];
+	
+	this.getstate = function() {
+		var sel = this.fm.selectedFiles();
+
+		return !this._disabled && sel.length == 1 && sel[0].phash && !sel[0].locked  ? 0 : -1;
+	}
+	
+	this.exec = function() {
+		var fm       = this.fm,
+			cwd      = fm.getUI('cwd'),
+			sel      = fm.selected(),
+			cnt      = sel.length,
+			file     = fm.file(sel.shift()),
+			filename = '.elfinder-cwd-filename',
+			dfrd     = $.Deferred()
+				.fail(function(error) {
+					var parent = input.parent(),
+						name   = fm.escape(file.name);
+
+					
+					if (parent.length) {
+						input.remove();
+						parent.html(name);
+					} else {
+						cwd.find('#'+file.hash).find(filename).html(name);
+						setTimeout(function() {
+							cwd.find('#'+file.hash).click();
+						}, 50);
+					}
+					
+					error && fm.error(error);
+				})
+				.always(function() {
+					fm.enable();
+				}),
+			input = $('<input type="text"/>')
+				.keydown(function(e) {
+					e.stopPropagation();
+					e.stopImmediatePropagation();
+					if (e.keyCode == $.ui.keyCode.ESCAPE) {
+						dfrd.reject();
+					} else if (e.keyCode == $.ui.keyCode.ENTER) {
+						input.blur();
+					}
+				})
+				.mousedown(function(e) {
+					e.stopPropagation();
+				})
+				.dblclick(function(e) {
+					e.stopPropagation();
+					e.preventDefault();
+				})
+				.blur(function() {
+					var name   = $.trim(input.val()),
+						parent = input.parent();
+
+					if (parent.length) {
+						if (input[0].setSelectionRange) {
+							input[0].setSelectionRange(0, 0)
+						}
+						if (name == file.name) {
+							return dfrd.reject();
+						}
+						if (!name) {
+							return dfrd.reject('errInvName');
+						}
+						if (fm.fileByName(name, file.phash)) {
+							return dfrd.reject(['errExists', name]);
+						}
+						
+						parent.html(fm.escape(name));
+						fm.lockfiles({files : [file.hash]});
+						fm.request({
+								data   : {cmd : 'rename', target : file.hash, name : name},
+								notify : {type : 'rename', cnt : 1}
+							})
+							.fail(function(error) {
+								dfrd.reject();
+								fm.sync();
+							})
+							.done(function(data) {
+								dfrd.resolve(data);
+							})
+							.always(function() {
+								fm.unlockfiles({files : [file.hash]})
+							});
+						
+					}
+				}),
+			node = cwd.find('#'+file.hash).find(filename).empty().append(input.val(file.name)),
+			name = input.val().replace(/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/ig, '')
+			;
+		
+		if (this.disabled()) {
+			return dfrd.reject();
+		}
+		
+		if (!file || cnt > 1 || !node.length) {
+			return dfrd.reject('errCmdParams', this.title);
+		}
+		
+		if (file.locked) {
+			return dfrd.reject(['errLocked', file.name]);
+		}
+		
+		fm.one('select', function() {
+			input.parent().length && file && $.inArray(file.hash, fm.selected()) === -1 && input.blur();
+		})
+		
+		input.select().focus();
+		
+		input[0].setSelectionRange && input[0].setSelectionRange(0, name.length);
+		
+		return dfrd;
+	}
+
+}
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/resize.js
+ */
+
+/**
+ * @class  elFinder command "resize"
+ * Open dialog to resize image
+ *
+ * @author Dmitry (dio) Levashov
+ * @author Alexey Sukhotin
+ * @author Naoki Sawada
+ * @author Sergio Jovani
+ **/
+elFinder.prototype.commands.resize = function() {
+
+	this.updateOnSelect = false;
+	
+	this.getstate = function() {
+		var sel = this.fm.selectedFiles();
+		return !this._disabled && sel.length == 1 && sel[0].read && sel[0].write && sel[0].mime.indexOf('image/') !== -1 ? 0 : -1;
+	};
+	
+	this.exec = function(hashes) {
+		var fm    = this.fm,
+			files = this.files(hashes),
+			dfrd  = $.Deferred(),
+			
+			open = function(file, id) {
+				var dialog   = $('<div class="elfinder-dialog-resize"/>'),
+					input    = '<input type="text" size="5"/>',
+					row      = '<div class="elfinder-resize-row"/>',
+					label    = '<div class="elfinder-resize-label"/>',
+					control  = $('<div class="elfinder-resize-control"/>'),
+					preview  = $('<div class="elfinder-resize-preview"/>'),
+					spinner  = $('<div class="elfinder-resize-spinner">'+fm.i18n('ntfloadimg')+'</div>'),
+					rhandle  = $('<div class="elfinder-resize-handle"/>'),
+					rhandlec = $('<div class="elfinder-resize-handle"/>'),
+					uiresize = $('<div class="elfinder-resize-uiresize"/>'),
+					uicrop   = $('<div class="elfinder-resize-uicrop"/>'),
+					uibuttonset = '<div class="ui-widget-content ui-corner-all elfinder-buttonset"/>',
+					uibutton    = '<div class="ui-state-default elfinder-button"/>',
+					uiseparator = '<span class="ui-widget-content elfinder-toolbar-button-separator"/>',
+					uirotate    = $('<div class="elfinder-resize-rotate"/>'),
+					uideg270    = $(uibutton).attr('title',fm.i18n('rotate-cw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-l"/>')
+						.click(function(){
+							rdegree = rdegree - 90;
+							rotate.update(rdegree);
+						})),
+					uideg90     = $(uibutton).attr('title',fm.i18n('rotate-ccw')).append($('<span class="elfinder-button-icon elfinder-button-icon-rotate-r"/>')
+						.click(function(){
+							rdegree = rdegree + 90;
+							rotate.update(rdegree);
+						})),
+					uiprop   = $('<span />'),
+					reset    = $('<div class="ui-state-default ui-corner-all elfinder-resize-reset"><span class="ui-icon ui-icon-arrowreturnthick-1-w"/></div>'),
+					uitype   = $('<div class="elfinder-resize-type"/>')
+						.append('<input type="radio" name="type" id="'+id+'-resize" value="resize" checked="checked" /><label for="'+id+'-resize">'+fm.i18n('resize')+'</label>')
+						.append('<input type="radio" name="type" id="'+id+'-crop" value="crop" /><label for="'+id+'-crop">'+fm.i18n('crop')+'</label>')
+						.append('<input type="radio" name="type" id="'+id+'-rotate" value="rotate" /><label for="'+id+'-rotate">'+fm.i18n('rotate')+'</label>'),
+					type     = $('input', uitype).attr('disabled', 'disabled')
+						.change(function() {
+							var val = $('input:checked', uitype).val();
+							
+							resetView();
+							resizable(true);
+							croppable(true);
+							rotateable(true);
+							
+							if (val == 'resize') {
+								uiresize.show();
+								uirotate.hide();
+								uicrop.hide();
+								resizable();
+							}
+							else if (val == 'crop') {
+								uirotate.hide();
+								uiresize.hide();
+								uicrop.show();
+								croppable();
+							} else if (val == 'rotate') {
+								uiresize.hide();
+								uicrop.hide();
+								uirotate.show();
+								rotateable();
+							}
+						}),
+					constr  = $('<input type="checkbox" checked="checked"/>')
+						.change(function() {
+							cratio = !!constr.prop('checked');
+							resize.fixHeight();
+							resizable(true);
+							resizable();
+						}),
+					width   = $(input)
+						.change(function() {
+							var w = parseInt(width.val()),
+								h = parseInt(cratio ? Math.round(w/ratio) : height.val());
+
+							if (w > 0 && h > 0) {
+								resize.updateView(w, h);
+								height.val(h);
+							}
+						}),
+					height  = $(input)
+						.change(function() {
+							var h = parseInt(height.val()),
+								w = parseInt(cratio ? Math.round(h*ratio) : width.val());
+
+							if (w > 0 && h > 0) {
+								resize.updateView(w, h);
+								width.val(w);
+							}
+						}),
+					pointX  = $(input).change(function(){crop.updateView();}),
+					pointY  = $(input).change(function(){crop.updateView();}),
+					offsetX = $(input).change(function(){crop.updateView();}),
+					offsetY = $(input).change(function(){crop.updateView();}),
+					degree = $('<input type="text" size="3" maxlength="3" value="0" />')
+						.change(function() {
+							rotate.update();
+						}),
+					uidegslider = $('<div class="elfinder-resize-rotate-slider"/>')
+						.slider({
+							min: 0,
+							max: 359,
+							value: degree.val(),
+							animate: true,
+							change: function(event, ui) {
+								if (ui.value != uidegslider.slider('value')) {
+									rotate.update(ui.value);
+								}
+							},
+							slide: function(event, ui) {
+								rotate.update(ui.value, false);
+							}
+						}),
+					ratio   = 1,
+					prop    = 1,
+					owidth  = 0,
+					oheight = 0,
+					cratio  = true,
+					pwidth  = 0,
+					pheight = 0,
+					rwidth  = 0,
+					rheight = 0,
+					rdegree = 0,
+					img     = $('<img/>')
+						.load(function() {
+							spinner.remove();
+							
+							owidth  = img.width();
+							oheight = img.height();
+							ratio   = owidth/oheight;
+							resize.updateView(owidth, oheight);
+
+							rhandle.append(img.show()).show();
+							width.val(owidth);
+							height.val(oheight);
+							
+							var r_scale = Math.min(pwidth, pheight) / Math.sqrt(Math.pow(owidth, 2) + Math.pow(oheight, 2));
+							rwidth = owidth * r_scale;
+							rheight = oheight * r_scale;
+							
+							type.button('enable');
+							control.find('input,select').removeAttr('disabled')
+								.filter(':text').keydown(function(e) {
+									var c = e.keyCode, i;
+
+									e.stopPropagation();
+								
+									if ((c >= 37 && c <= 40) 
+									|| c == $.ui.keyCode.BACKSPACE 
+									|| c == $.ui.keyCode.DELETE 
+									|| (c == 65 && (e.ctrlKey||e.metaKey))
+									|| c == 27) {
+										return;
+									}
+								
+									if (c == 9) {
+										i = $(this).parent()[e.shiftKey ? 'prev' : 'next']('.elfinder-resize-row').children(':text');
+
+										if (i.length) {
+											i.focus();
+										} else {
+											$(this).parent().parent().find(':text:' + (e.shiftKey ? 'last' : 'first')).focus();
+										}
+									}
+								
+									if (c == 13) {
+										fm.confirm({
+											title  : $('input:checked', uitype).val(),
+											text   : 'confirmReq',
+											accept : {
+												label    : 'btnApply',
+												callback : function() {  
+													save();
+												}
+											},
+											cancel : {
+												label    : 'btnCancel',
+												callback : function(){}
+											}
+										});
+										return;
+									}
+								
+									if (!((c >= 48 && c <= 57) || (c >= 96 && c <= 105))) {
+										e.preventDefault();
+									}
+								})
+								.filter(':first').focus();
+								
+							resizable();
+							
+							reset.hover(function() { reset.toggleClass('ui-state-hover'); }).click(resetView);
+							
+						})
+						.error(function() {
+							spinner.text('Unable to load image').css('background', 'transparent');
+						}),
+					basec = $('<div/>'),
+					imgc = $('<img/>'),
+					coverc = $('<div/>'),
+					imgr = $('<img/>'),
+					resetView = function() {
+						width.val(owidth);
+						height.val(oheight);
+						resize.updateView(owidth, oheight);
+					},
+					resize = {
+						update : function() {
+							width.val(Math.round(img.width()/prop));
+							height.val(Math.round(img.height()/prop));
+						},
+						
+						updateView : function(w, h) {
+							if (w > pwidth || h > pheight) {
+								if (w / pwidth > h / pheight) {
+									prop = pwidth / w;
+									img.width(pwidth).height(Math.ceil(h*prop));
+								} else {
+									prop = pheight / h;
+									img.height(pheight).width(Math.ceil(w*prop));
+								}
+							} else {
+								img.width(w).height(h);
+							}
+							
+							prop = img.width()/w;
+							uiprop.text('1 : '+(1/prop).toFixed(2));
+							resize.updateHandle();
+						},
+						
+						updateHandle : function() {
+							rhandle.width(img.width()).height(img.height());
+						},
+						fixWidth : function() {
+							var w, h;
+							if (cratio) {
+								h = height.val();
+								h = Math.round(h*ratio);
+								resize.updateView(w, h);
+								width.val(w);
+							}
+						},
+						fixHeight : function() {
+							var w, h;
+							if (cratio) {
+								w = width.val();
+								h = Math.round(w/ratio);
+								resize.updateView(w, h);
+								height.val(h);
+							}
+						}
+					},
+					crop = {
+						update : function() {
+							offsetX.val(Math.round((rhandlec.data('w')||rhandlec.width())/prop));
+							offsetY.val(Math.round((rhandlec.data('h')||rhandlec.height())/prop));
+							pointX.val(Math.round(((rhandlec.data('x')||rhandlec.offset().left)-imgc.offset().left)/prop));
+							pointY.val(Math.round(((rhandlec.data('y')||rhandlec.offset().top)-imgc.offset().top)/prop));
+						},
+						updateView : function() {
+							var x = parseInt(pointX.val()) * prop + imgc.offset().left;
+							var y = parseInt(pointY.val()) * prop + imgc.offset().top;
+							var w = offsetX.val() * prop;
+							var h = offsetY.val() * prop;
+							rhandlec.data({x: x, y: y, w: w, h: h});
+							rhandlec.width(Math.round(w));
+							rhandlec.height(Math.round(h));
+							coverc.width(rhandlec.width());
+							coverc.height(rhandlec.height());
+							rhandlec.offset({left: Math.round(x), top: Math.round(y)});
+						},
+						resize_update : function() {
+							rhandlec.data({w: null, h: null});
+							crop.update();
+							coverc.width(rhandlec.width());
+							coverc.height(rhandlec.height());
+						},
+						drag_update : function() {
+							rhandlec.data({x: null, y: null});
+							crop.update();
+						}
+					},
+					rotate = {
+						mouseStartAngle : 0,
+						imageStartAngle : 0,
+						imageBeingRotated : false,
+							
+						update : function(value, animate) {
+							if (typeof value == 'undefined') {
+								rdegree = value = parseInt(degree.val());
+							}
+							if (typeof animate == 'undefined') {
+								animate = true;
+							}
+							if (! animate || fm.UA.Opera || fm.UA.ltIE8) {
+								imgr.rotate(value);
+							} else {
+								imgr.animate({rotate: value + 'deg'});
+							}
+							value = value % 360;
+							if (value < 0) {
+								value += 360;
+							}
+							degree.val(parseInt(value));
+
+							uidegslider.slider('value', degree.val());
+						},
+						
+						execute : function ( e ) {
+							
+							if ( !rotate.imageBeingRotated ) return;
+							
+							var imageCentre = rotate.getCenter( imgr );
+							var mouseXFromCentre = e.pageX - imageCentre[0];
+							var mouseYFromCentre = e.pageY - imageCentre[1];
+							var mouseAngle = Math.atan2( mouseYFromCentre, mouseXFromCentre );
+							
+							var rotateAngle = mouseAngle - rotate.mouseStartAngle + rotate.imageStartAngle;
+							rotateAngle = Math.round(parseFloat(rotateAngle) * 180 / Math.PI);
+							
+							if ( e.shiftKey ) {
+								rotateAngle = Math.round((rotateAngle + 6)/15) * 15;
+							}
+							
+							imgr.rotate(rotateAngle);
+							
+							rotateAngle = rotateAngle % 360;
+							if (rotateAngle < 0) {
+								rotateAngle += 360;
+							}
+							degree.val(rotateAngle);
+
+							uidegslider.slider('value', degree.val());
+							
+							return false;
+						},
+						
+						start : function ( e ) {
+							
+							rotate.imageBeingRotated = true;
+							
+							var imageCentre = rotate.getCenter( imgr );
+							var mouseStartXFromCentre = e.pageX - imageCentre[0];
+							var mouseStartYFromCentre = e.pageY - imageCentre[1];
+							rotate.mouseStartAngle = Math.atan2( mouseStartYFromCentre, mouseStartXFromCentre );
+							
+							rotate.imageStartAngle = parseFloat(imgr.rotate()) * Math.PI / 180.0;
+							
+							$(document).mousemove( rotate.execute );
+							
+							return false;
+						},
+							
+						stop : function ( e ) {
+							
+							if ( !rotate.imageBeingRotated ) return;
+							
+							$(document).unbind( 'mousemove' , rotate.execute);
+							
+							setTimeout( function() { rotate.imageBeingRotated = false; }, 10 );
+							return false;
+						},
+						
+						getCenter : function ( image ) {
+							
+							var currentRotation = imgr.rotate();
+							imgr.rotate(0);
+							
+							var imageOffset = imgr.offset();
+							var imageCentreX = imageOffset.left + imgr.width() / 2;
+							var imageCentreY = imageOffset.top + imgr.height() / 2;
+							
+							imgr.rotate(currentRotation);
+							
+							return Array( imageCentreX, imageCentreY );
+						}
+					},
+					resizable = function(destroy) {
+						if ($.fn.resizable) {
+							if (destroy) {
+								rhandle.filter(':ui-resizable').resizable('destroy');
+								rhandle.hide();
+							}
+							else {
+								rhandle.show();
+								rhandle.resizable({
+									alsoResize  : img,
+									aspectRatio : cratio,
+									resize      : resize.update,
+									stop        : resize.fixHeight
+								});
+							}
+						}
+					},
+					croppable = function(destroy) {
+						if ($.fn.draggable && $.fn.resizable) {
+							if (destroy) {
+								rhandlec.filter(':ui-resizable').resizable('destroy');
+								rhandlec.filter(':ui-draggable').draggable('destroy');
+								basec.hide();
+							}
+							else {
+								imgc
+									.width(img.width())
+									.height(img.height());
+								
+								coverc
+									.width(img.width())
+									.height(img.height());
+								
+								rhandlec
+									.width(imgc.width())
+									.height(imgc.height())
+									.offset(imgc.offset())
+									.resizable({
+										containment : basec,
+										resize      : crop.resize_update,
+										handles     : 'all'
+									})
+									.draggable({
+										handle      : coverc,
+										containment : imgc,
+										drag        : crop.drag_update
+									});
+								
+								basec.show()
+									.width(img.width())
+									.height(img.height());
+								
+								crop.update();
+							}
+						}
+					},
+					rotateable = function(destroy) {
+						if ($.fn.draggable && $.fn.resizable) {
+							if (destroy) {
+								imgr.hide();
+							}
+							else {
+								imgr.show()
+									.width(rwidth)
+									.height(rheight)
+									.css('margin-top', (pheight-rheight)/2 + 'px')
+									.css('margin-left', (pwidth-rwidth)/2 + 'px');
+
+							}
+						}
+					},
+					save = function() {
+						var w, h, x, y, d;
+						var mode = $('input:checked', uitype).val();
+						
+						//width.add(height).change(); // may be unnecessary
+						
+						if (mode == 'resize') {
+							w = parseInt(width.val()) || 0;
+							h = parseInt(height.val()) || 0;
+						} else if (mode == 'crop') {
+							w = parseInt(offsetX.val()) || 0;
+							h = parseInt(offsetY.val()) || 0;
+							x = parseInt(pointX.val()) || 0;
+							y = parseInt(pointY.val()) || 0;
+						} else if (mode == 'rotate') {
+							w = owidth;
+							h = oheight;
+							d = parseInt(degree.val()) || 0;
+							if (d < 0 || d > 360) {
+								return fm.error('Invalid rotate degree');
+							}
+							if (d == 0 || d == 360) {
+								return fm.error('Image dose not rotated');
+							}
+						}
+						
+						if (mode != 'rotate') {
+
+							if (w <= 0 || h <= 0) {
+								return fm.error('Invalid image size');
+							}
+							
+							if (w == owidth && h == oheight) {
+								return fm.error('Image size not changed');
+							}
+
+						}
+						
+						dialog.elfinderdialog('close');
+						
+						fm.request({
+							data : {
+								cmd    : 'resize',
+								target : file.hash,
+								width  : w,
+								height : h,
+								x      : x,
+								y      : y,
+								degree : d,
+								mode   : mode
+							},
+							notify : {type : 'resize', cnt : 1}
+						})
+						.fail(function(error) {
+							dfrd.reject(error);
+						})
+						.done(function() {
+							dfrd.resolve();
+						});
+						
+					},
+					buttons = {},
+					hline   = 'elfinder-resize-handle-hline',
+					vline   = 'elfinder-resize-handle-vline',
+					rpoint  = 'elfinder-resize-handle-point',
+					src     = fm.url(file.hash)
+					;
+				
+				imgr.mousedown( rotate.start );
+				$(document).mouseup( rotate.stop );
+					
+				uiresize.append($(row).append($(label).text(fm.i18n('width'))).append(width).append(reset))
+					.append($(row).append($(label).text(fm.i18n('height'))).append(height))
+					.append($(row).append($('<label/>').text(fm.i18n('aspectRatio')).prepend(constr)))
+					.append($(row).append(fm.i18n('scale')+' ').append(uiprop));
+				
+				uicrop.append($(row).append($(label).text('X')).append(pointX))
+					.append($(row).append($(label).text('Y')).append(pointY))
+					.append($(row).append($(label).text(fm.i18n('width'))).append(offsetX))
+					.append($(row).append($(label).text(fm.i18n('height'))).append(offsetY));
+				
+				uirotate.append($(row)
+					.append($(label).text(fm.i18n('rotate')))
+					.append($('<div style="float:left; width: 130px;">')
+						.append($('<div style="float:left;">')
+							.append(degree)
+							.append($('<span/>').text(fm.i18n('degree')))
+						)
+						.append($(uibuttonset).append(uideg270).append($(uiseparator)).append(uideg90))
+					)
+					.append(uidegslider)
+				);
+
+				
+				dialog.append(uitype);
+
+				control.append($(row))
+					.append(uiresize)
+					.append(uicrop.hide())
+					.append(uirotate.hide())
+					.find('input,select').attr('disabled', 'disabled');
+				
+				rhandle.append('<div class="'+hline+' '+hline+'-top"/>')
+					.append('<div class="'+hline+' '+hline+'-bottom"/>')
+					.append('<div class="'+vline+' '+vline+'-left"/>')
+					.append('<div class="'+vline+' '+vline+'-right"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-e"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-se"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-s"/>');
+					
+				preview.append(spinner).append(rhandle.hide()).append(img.hide());
+
+				rhandlec.css('position', 'absolute')
+					.append('<div class="'+hline+' '+hline+'-top"/>')
+					.append('<div class="'+hline+' '+hline+'-bottom"/>')
+					.append('<div class="'+vline+' '+vline+'-left"/>')
+					.append('<div class="'+vline+' '+vline+'-right"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-n"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-e"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-s"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-w"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-ne"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-se"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-sw"/>')
+					.append('<div class="'+rpoint+' '+rpoint+'-nw"/>');
+
+				preview.append(basec.css('position', 'absolute').hide().append(imgc).append(rhandlec.append(coverc)));
+				
+				preview.append(imgr.hide());
+				
+				preview.css('overflow', 'hidden');
+				
+				dialog.append(preview).append(control);
+				
+				buttons[fm.i18n('btnApply')] = save;
+				buttons[fm.i18n('btnCancel')] = function() { dialog.elfinderdialog('close'); };
+				
+				fm.dialog(dialog, {
+					title          : file.name,
+					width          : 650,
+					resizable      : false,
+					destroyOnClose : true,
+					buttons        : buttons,
+					open           : function() { preview.zIndex(1+$(this).parent().zIndex()); }
+				}).attr('id', id);
+				
+				// for IE < 9 dialog mising at open second+ time.
+				if (fm.UA.ltIE8) {
+					$('.elfinder-dialog').css('filter', '');
+				}
+				
+				reset.css('left', width.position().left + width.width() + 12);
+				
+				coverc.css({ 'opacity': 0.2, 'background-color': '#fff', 'position': 'absolute'}),
+				rhandlec.css('cursor', 'move');
+				rhandlec.find('.elfinder-resize-handle-point').css({
+					'background-color' : '#fff',
+					'opacity': 0.5,
+					'border-color':'#000'
+				});
+
+				imgr.css('cursor', 'pointer');
+				
+				uitype.buttonset();
+				
+				pwidth  = preview.width()  - (rhandle.outerWidth()  - rhandle.width());
+				pheight = preview.height() - (rhandle.outerHeight() - rhandle.height());
+				
+				img.attr('src', src + (src.indexOf('?') === -1 ? '?' : '&')+'_='+Math.random());
+				imgc.attr('src', img.attr('src'));
+				imgr.attr('src', img.attr('src'));
+				
+			},
+			
+			id, dialog
+			;
+			
+
+		if (!files.length || files[0].mime.indexOf('image/') === -1) {
+			return dfrd.reject();
+		}
+		
+		id = 'resize-'+fm.namespace+'-'+files[0].hash;
+		dialog = fm.getUI().find('#'+id);
+		
+		if (dialog.length) {
+			dialog.elfinderdialog('toTop');
+			return dfrd.resolve();
+		}
+		
+		open(files[0], id);
+			
+		return dfrd;
+	};
+
+};
+
+(function ($) {
+	
+	var findProperty = function (styleObject, styleArgs) {
+		var i = 0 ;
+		for( i in styleArgs) {
+	        if (typeof styleObject[styleArgs[i]] != 'undefined') 
+	        	return styleArgs[i];
+		}
+		styleObject[styleArgs[i]] = '';
+	    return styleArgs[i];
+	};
+	
+	$.cssHooks.rotate = {
+		get: function(elem, computed, extra) {
+			return $(elem).rotate();
+		},
+		set: function(elem, value) {
+			$(elem).rotate(value);
+			return value;
+		}
+	};
+	$.cssHooks.transform = {
+		get: function(elem, computed, extra) {
+			var name = findProperty( elem.style , 
+				['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );
+			return elem.style[name];
+		},
+		set: function(elem, value) {
+			var name = findProperty( elem.style , 
+				['WebkitTransform', 'MozTransform', 'OTransform' , 'msTransform' , 'transform'] );
+			elem.style[name] = value;
+			return value;
+		}
+	};
+	
+	$.fn.rotate = function(val) {
+		if (typeof val == 'undefined') {
+			if (!!window.opera) {
+				var r = this.css('transform').match(/rotate\((.*?)\)/);
+				return  ( r && r[1])?
+					Math.round(parseFloat(r[1]) * 180 / Math.PI) : 0;
+			} else {
+				var r = this.css('transform').match(/rotate\((.*?)\)/);
+				return  ( r && r[1])? parseInt(r[1]) : 0;
+			}
+		}
+		this.css('transform', 
+			this.css('transform').replace(/none|rotate\(.*?\)/, '') + 'rotate(' + parseInt(val) + 'deg)');
+		return this;
+	};
+
+	$.fx.step.rotate  = function(fx) {
+		if ( fx.state == 0 ) {
+			fx.start = $(fx.elem).rotate();
+			fx.now = fx.start;
+		}
+		$(fx.elem).rotate(fx.now);
+	};
+
+	if (typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined") { // IE & IE<9
+		var GetAbsoluteXY = function(element) {
+			var pnode = element;
+			var x = pnode.offsetLeft;
+			var y = pnode.offsetTop;
+			
+			while ( pnode.offsetParent ) {
+				pnode = pnode.offsetParent;
+				if (pnode != document.body && pnode.currentStyle['position'] != 'static') {
+					break;
+				}
+				if (pnode != document.body && pnode != document.documentElement) {
+					x -= pnode.scrollLeft;
+					y -= pnode.scrollTop;
+				}
+				x += pnode.offsetLeft;
+				y += pnode.offsetTop;
+			}
+			
+			return { x: x, y: y };
+		};
+		
+		var StaticToAbsolute = function (element) {
+			if ( element.currentStyle['position'] != 'static') {
+				return ;
+			}
+
+			var xy = GetAbsoluteXY(element);
+			element.style.position = 'absolute' ;
+			element.style.left = xy.x + 'px';
+			element.style.top = xy.y + 'px';
+		};
+
+		var IETransform = function(element,transform){
+
+			var r;
+			var m11 = 1;
+			var m12 = 1;
+			var m21 = 1;
+			var m22 = 1;
+
+			if (typeof element.style['msTransform'] != 'undefined'){
+				return true;
+			}
+
+			StaticToAbsolute(element);
+
+			r = transform.match(/rotate\((.*?)\)/);
+			var rotate =  ( r && r[1])	?	parseInt(r[1])	:	0;
+
+			rotate = rotate % 360;
+			if (rotate < 0) rotate = 360 + rotate;
+
+			var radian= rotate * Math.PI / 180;
+			var cosX =Math.cos(radian);
+			var sinY =Math.sin(radian);
+
+			m11 *= cosX;
+			m12 *= -sinY;
+			m21 *= sinY;
+			m22 *= cosX;
+
+			element.style.filter =  (element.style.filter || '').replace(/progid:DXImageTransform\.Microsoft\.Matrix\([^)]*\)/, "" ) +
+				("progid:DXImageTransform.Microsoft.Matrix(" + 
+					 "M11=" + m11 + 
+					",M12=" + m12 + 
+					",M21=" + m21 + 
+					",M22=" + m22 + 
+					",FilterType='bilinear',sizingMethod='auto expand')") 
+				;
+
+	  		var ow = parseInt(element.style.width || element.width || 0 );
+	  		var oh = parseInt(element.style.height || element.height || 0 );
+
+			var radian = rotate * Math.PI / 180;
+			var absCosX =Math.abs(Math.cos(radian));
+			var absSinY =Math.abs(Math.sin(radian));
+
+			var dx = (ow - (ow * absCosX + oh * absSinY)) / 2;
+			var dy = (oh - (ow * absSinY + oh * absCosX)) / 2;
+
+			element.style.marginLeft = Math.floor(dx) + "px";
+			element.style.marginTop  = Math.floor(dy) + "px";
+
+			return(true);
+		};
+		
+		var transform_set = $.cssHooks.transform.set;
+		$.cssHooks.transform.set = function(elem, value) {
+			transform_set.apply(this, [elem, value] );
+			IETransform(elem,value);
+			return value;
+		};
+	}
+
+})(jQuery);
+
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/rm.js
+ */
+
+/**
+ * @class  elFinder command "rm"
+ * Delete files
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.rm = function() {
+	
+	this.shortcuts = [{
+		pattern     : 'delete ctrl+backspace'
+	}];
+	
+	this.getstate = function(sel) {
+		var fm = this.fm;
+		sel = sel || fm.selected();
+		return !this._disabled && sel.length && $.map(sel, function(h) { var f = fm.file(h); return f && f.phash && !f.locked ? h : null }).length == sel.length
+			? 0 : -1;
+	}
+	
+	this.exec = function(hashes) {
+		var self   = this,
+			fm     = this.fm,
+			dfrd   = $.Deferred()
+				.fail(function(error) {
+					error && fm.error(error);
+				}),
+			files  = this.files(hashes),
+			cnt    = files.length,
+			cwd    = fm.cwd().hash,
+			goroot = false;
+
+		if (!cnt || this._disabled) {
+			return dfrd.reject();
+		}
+		
+		$.each(files, function(i, file) {
+			if (!file.phash) {
+				return !dfrd.reject(['errRm', file.name, 'errPerm']);
+			}
+			if (file.locked) {
+				return !dfrd.reject(['errLocked', file.name]);
+			}
+			if (file.hash == cwd) {
+				goroot = fm.root(file.hash);
+			}
+		});
+
+		if (dfrd.state() == 'pending') {
+			files = this.hashes(hashes);
+			
+			fm.confirm({
+				title  : self.title,
+				text   : 'confirmRm',
+				accept : {
+					label    : 'btnRm',
+					callback : function() {  
+						fm.lockfiles({files : files});
+						fm.request({
+							data   : {cmd  : 'rm', targets : files}, 
+							notify : {type : 'rm', cnt : cnt},
+							preventFail : true
+						})
+						.fail(function(error) {
+							dfrd.reject(error);
+						})
+						.done(function(data) {
+							dfrd.done(data);
+							goroot && fm.exec('open', goroot)
+						}
+						).always(function() {
+							fm.unlockfiles({files : files});
+						});
+					}
+				},
+				cancel : {
+					label    : 'btnCancel',
+					callback : function() { dfrd.reject(); }
+				}
+			});
+		}
+			
+		return dfrd;
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/search.js
+ */
+
+/**
+ * @class  elFinder command "search"
+ * Find files
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.search = function() {
+	this.title          = 'Find files';
+	this.options        = {ui : 'searchbutton'}
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+	
+	/**
+	 * Return command status.
+	 * Search does not support old api.
+	 *
+	 * @return Number
+	 **/
+	this.getstate = function() {
+		return 0;
+	}
+	
+	/**
+	 * Send search request to backend.
+	 *
+	 * @param  String  search string
+	 * @return $.Deferred
+	 **/
+	this.exec = function(q) {
+		var fm = this.fm;
+		
+		if (typeof(q) == 'string' && q) {
+			fm.trigger('searchstart', {query : q});
+			
+			return fm.request({
+				data   : {cmd : 'search', q : q},
+				notify : {type : 'search', cnt : 1, hideCnt : true}
+			});
+		}
+		fm.getUI('toolbar').find('.'+fm.res('class', 'searchbtn')+' :text').focus();
+		return $.Deferred().reject();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/sort.js
+ */
+
+/**
+ * @class  elFinder command "sort"
+ * Change sort files rule
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.sort = function() {
+	/**
+	 * Command options
+	 *
+	 * @type  Object
+	 */
+	this.options = {ui : 'sortbutton'};
+	
+	this.getstate = function() {
+		return 0;
+	}
+	
+	this.exec = function(hashes, sort) {
+		var fm = this.fm,
+			sort = $.extend({
+				type  : fm.sortType,
+				order : fm.sortOrder,
+				stick : fm.sortStickFolders
+			}, sort);
+
+		this.fm.setSort(sort.type, sort.order, sort.stick);
+		return $.Deferred().resolve();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/up.js
+ */
+
+/**
+ * @class  elFinder command "up"
+ * Go into parent directory
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.up = function() {
+	this.alwaysEnabled = true;
+	this.updateOnSelect = false;
+	
+	this.shortcuts = [{
+		pattern     : 'ctrl+up'
+	}];
+	
+	this.getstate = function() {
+		return this.fm.cwd().phash ? 0 : -1;
+	}
+	
+	this.exec = function() {
+		return this.fm.cwd().phash ? this.fm.exec('open', this.fm.cwd().phash) : $.Deferred().reject();
+	}
+
+}
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/upload.js
+ */
+
+/**
+ * @class elFinder command "upload"
+ * Upload files using iframe or XMLHttpRequest & FormData.
+ * Dialog allow to send files using drag and drop
+ *
+ * @type  elFinder.command
+ * @author  Dmitry (dio) Levashov
+ */
+elFinder.prototype.commands.upload = function() {
+	var hover = this.fm.res('class', 'hover');
+	
+	this.disableOnSearch = true;
+	this.updateOnSelect  = false;
+	
+	// Shortcut opens dialog
+	this.shortcuts = [{
+		pattern     : 'ctrl+u'
+	}];
+	
+	/**
+	 * Return command state
+	 *
+	 * @return Number
+	 **/
+	this.getstate = function() {
+		return !this._disabled && this.fm.cwd().write ? 0 : -1;
+	};
+	
+	
+	this.exec = function(data) {
+		var fm = this.fm,
+			upload = function(data) {
+				dialog.elfinderdialog('close');
+				fm.upload(data)
+					.fail(function(error) {
+						dfrd.reject(error);
+					})
+					.done(function(data) {
+						dfrd.resolve(data);
+					});
+			},
+			dfrd, dialog, input, button, dropbox, pastebox;
+		
+		if (this.disabled()) {
+			return $.Deferred().reject();
+		}
+		
+		if (data && (data.input || data.files)) {
+			return fm.upload(data);
+		}
+		
+		dfrd = $.Deferred();
+		
+		
+		input = $('<input type="file" multiple="true"/>')
+			.change(function() {
+				upload({input : input[0]});
+			});
+
+		button = $('<div class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+fm.i18n('selectForUpload')+'</span></div>')
+			.append($('<form/>').append(input))
+			.hover(function() {
+				button.toggleClass(hover)
+			});
+			
+		dialog = $('<div class="elfinder-upload-dialog-wrapper"/>')
+			.append(button);
+		
+		pastebox = $('<div class="ui-corner-all elfinder-upload-dropbox" contenteditable=true></div>')
+			.on('paste drop', function (evt) {
+				var e = evt.originalEvent || evt;
+				var files = [];
+				var file;
+				if (e.clipboardData && e.clipboardData.items && e.clipboardData.items.length){
+					for (var i=0; i < e.clipboardData.items.length; i++) {
+						if (e.clipboardData.items[i].kind == 'file') {
+							file = e.clipboardData.items[i].getAsFile();
+							files.push(file);
+						}
+					}
+					if (files.length) {
+						upload({files : files, type : 'files'});
+						return;
+					}
+				}
+				var my = e.target;
+				setTimeout(function () {
+					if (my.innerHTML) {
+						var src = my.innerHTML.replace(/<br[^>]*>/gi, ' ');
+						var type = src.match(/<[^>]+>/)? 'html' : 'text';
+						my.innerHTML = '';
+						upload({files : [ src ], type : type});
+					}
+				}, 1);
+			})
+			.on('dragenter mouseover', function(){
+				pastebox.addClass(hover);
+			})
+			.on('dragleave mouseout', function(){
+				pastebox.removeClass(hover);
+			});
+		
+		if (fm.dragUpload) {
+			dropbox = $('<div class="ui-corner-all elfinder-upload-dropbox">'+fm.i18n('dropFiles')+'</div>')
+				.prependTo(dialog)
+				.after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')
+				.after(pastebox)
+				.after('<div>'+fm.i18n('dropFilesBrowser')+'</div>')
+				.after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];
+			
+			dropbox.addEventListener('dragenter', function(e) {
+				e.stopPropagation();
+			  	e.preventDefault();
+				$(dropbox).addClass(hover);
+			}, false);
+
+			dropbox.addEventListener('dragleave', function(e) {
+				e.stopPropagation();
+			  	e.preventDefault();
+				$(dropbox).removeClass(hover);
+			}, false);
+
+			dropbox.addEventListener('dragover', function(e) {
+				e.stopPropagation();
+			  	e.preventDefault();
+			  	$(dropbox).addClass(hover);
+			}, false);
+
+			dropbox.addEventListener('drop', function(e) {
+				e.stopPropagation();
+			  	e.preventDefault();
+				var file = false;
+				var type = '';
+				if (e.dataTransfer && e.dataTransfer.items &&  e.dataTransfer.items.length) {
+					file = e.dataTransfer.items;
+					type = 'data';
+				} else if (e.dataTransfer && e.dataTransfer.files &&  e.dataTransfer.files.length) {
+					file = e.dataTransfer.files;
+					type = 'files';
+				} else if (e.dataTransfer.getData('text/html')) {
+					file = [ e.dataTransfer.getData('text/html') ];
+					type = 'html';
+				} else if (e.dataTransfer.getData('text')) {
+					file = [ e.dataTransfer.getData('text') ];
+					type = 'text';
+				}
+				if (file) {
+					upload({files : file, type : type});
+				}
+			}, false);
+			
+		} else {
+			$('<div>'+fm.i18n('dropFilesBrowser')+'</div>')
+				.append(pastebox)
+				.prependTo(dialog)
+				.after('<div class="elfinder-upload-dialog-or">'+fm.i18n('or')+'</div>')[0];
+			
+		}
+		
+		fm.dialog(dialog, {
+			title          : this.title,
+			modal          : true,
+			resizable      : false,
+			destroyOnClose : true
+		});
+		
+		return dfrd;
+	};
+
+};
+
+/*
+ * File: /home/osc/elFinder-build/elFinder/js/commands/view.js
+ */
+
+/**
+ * @class  elFinder command "view"
+ * Change current directory view (icons/list)
+ *
+ * @author Dmitry (dio) Levashov
+ **/
+elFinder.prototype.commands.view = function() {
+	this.value          = this.fm.viewType;
+	this.alwaysEnabled  = true;
+	this.updateOnSelect = false;
+
+	this.options = { ui : 'viewbutton'};
+	
+	this.getstate = function() {
+		return 0;
+	}
+	
+	this.exec = function() {
+		var value = this.fm.storage('view', this.value == 'list' ? 'icons' : 'list');
+		this.fm.viewchange();
+		this.update(void(0), value);
+	}
+
+}
+})(jQuery);

File diff suppressed because it is too large
+ 2 - 2
main/inc/lib/elfinder/js/elfinder.min.js


+ 15 - 8
main/inc/lib/elfinder/js/i18n/elfinder.LANG.js

@@ -75,11 +75,15 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errNoArchive'         : 'File is not archive or has unsupported archive type.',
 			'errCmdNoSupport'      : 'Backend does not support this command.',
 			'errReplByChild'       : 'The folder “$1” can’t be replaced by an item it contains.',
-			'errArcSymlinks'       : 'For security reason denied to unpack archives contains symlinks.',
+			'errArcSymlinks'       : 'For security reason denied to unpack archives contains symlinks or files with not allowed names.', // edited 24.06.2012
 			'errArcMaxSize'        : 'Archive files exceeds maximum allowed size.',
 			'errResize'            : 'Unable to resize "$1".',
 			'errUsupportType'      : 'Unsupported file type.',
-			
+			'errNotUTF8Content'    : 'File "$1" is not in UTF-8 and cannot be edited.',  // added 9.11.2011
+			'errNetMount'          : 'Unable to mount "$1".',     // added 17.04.2012
+			'errNetMountNoDriver'  : 'Unsupported protocol.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Mount failed.',             // added 17.04.2012
+			'errNetMountHostReq'   : 'Host required.', // added 18.04.2012
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Create archive',
 			'cmdback'      : 'Back',
@@ -137,6 +141,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfsearch'   : 'Searching files',
 			'ntfsmth'     : 'Doing something >_<',
 			'ntfloadimg'  : 'Loading image',
+			'ntfnetmount' : 'Mounting network volume', // added 18.04.2012
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : 'unknown',
@@ -181,14 +186,11 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Fri'         : 'Fri', 
 			'Sat'         : 'Sat',
 			/******************************** sort variants ********************************/
-			'sortnameDirsFirst' : 'by name (folders first)', 
-			'sortkindDirsFirst' : 'by kind (folders first)', 
-			'sortsizeDirsFirst' : 'by size (folders first)', 
-			'sortdateDirsFirst' : 'by date (folders first)', 
 			'sortname'          : 'by name', 
 			'sortkind'          : 'by kind', 
 			'sortsize'          : 'by size',
 			'sortdate'          : 'by date',
+			'sortFoldersFirst'  : 'Folders first', // added 22.06.2012
 			
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Confirmation required',
@@ -230,7 +232,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Help',
 			'webfm'           : 'Web file manager',
 			'ver'             : 'Version',
-			'protocol'        : 'protocol version',
+			'protocolver'     : 'protocol version',
 			'homepage'        : 'Project home',
 			'docs'            : 'Documentation',
 			'github'          : 'Fork us on Github',
@@ -264,7 +266,12 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'rotate-cw'       : 'Rotate 90 degrees CW',
 			'rotate-ccw'      : 'Rotate 90 degrees CCW',
 			'degree'          : 'Degree',
-			
+			'netMountDialogTitle' : 'Mount network volume', // added 18.04.2012
+			'protocol'            : 'Protocol', // added 18.04.2012
+			'host'                : 'Host', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'User', // added 18.04.2012
+			'pass'                : 'Password', // added 18.04.2012
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Unknown',
 			'kindFolder'      : 'Folder',

+ 1 - 1
main/inc/lib/elfinder/js/i18n/elfinder.ar.js

@@ -180,7 +180,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'مساعدة',
 			'webfm'           : 'مدير ملفات الويب',
 			'ver'             : 'رقم الإصدار',
-			'protocol'        : 'اصدار البرتوكول',
+			'protocolver'     : 'اصدار البرتوكول',
 			'homepage'        : 'الصفحة الرئيسية',
 			'docs'            : 'التعليمات',
 			'github'          : 'شاركنا بتطوير المشروع على Github',

+ 1 - 1
main/inc/lib/elfinder/js/i18n/elfinder.bg.js

@@ -196,7 +196,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Помощ',
 			'webfm'           : 'Файлов менаджер за web',
 			'ver'             : 'Версия',
-			'protocol'        : 'версия на протокола',
+			'protocolver'        : 'версия на протокола',
 			'homepage'        : 'Начало',
 			'docs'            : 'Документация',
 			'github'          : 'Разклонение в Github',

+ 1 - 1
main/inc/lib/elfinder/js/i18n/elfinder.ca.js

@@ -196,7 +196,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Ajuda',
 			'webfm'           : 'Gestor de fitxers web',
 			'ver'             : 'Versió',
-			'protocol'        : 'versió de protocol',
+			'protocolver'     : 'versió de protocol',
 			'homepage'        : 'Pàgina del projecte',
 			'docs'            : 'Documentació',
 			'github'          : 'Bifurca\'ns a GitHub',

+ 77 - 22
main/inc/lib/elfinder/js/i18n/elfinder.cs.js

@@ -1,19 +1,22 @@
 /**
  * Czech translation
- * @author <gridley.jay@gmail.com>
- * @version 2011-07-27
+ * @author Jay Gridley <gridley.jay@hotmail.com>
+ * @version 2012-03-23
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.cs = {
-		translator : '&lt;gridley.jay@gmail.com&gt;',
-		language   : 'český',
+		translator : 'Jay Gridley &lt;gridley.jay@hotmail.com&gt;',
+		language   : 'čeština',
 		direction  : 'ltr',
+		dateFormat : 'd. m. Y H:i',
+		fancyDateFormat : '$1 H:i',
 		messages   : {
+
 			/********************************** errors **********************************/
 			'error'                : 'Chyba',
 			'errUnknown'           : 'Neznámá chyba.',
 			'errUnknownCmd'        : 'Neznámý příkaz.',
-			'errJqui'              : 'Nedostačující konfigurace jQuery UI. Musí být zahrnuty komponenty Selectable, draggable a droppable.',
+			'errJqui'              : 'Nedostačující konfigurace jQuery UI. Musí být zahrnuty komponenty Selectable, Draggable a Droppable.',
 			'errNode'              : 'elFinder vyžaduje vytvořený DOM Element.',
 			'errURL'               : 'Chybná konfigurace elFinderu! Není nastavena hodnota URL.',
 			'errAccess'            : 'Přístup zamítnut.',
@@ -23,7 +26,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errNotFound'          : 'Backend nenalezen.',
 			'errResponse'          : 'Nesprávná odpověď backendu.',
 			'errConf'              : 'Nepsrávná konfigurace backendu.',
-			'errJSON'              : 'JSON PHP modul není nainstalován.',
+			'errJSON'              : 'PHP modul JSON není nainstalován.',
 			'errNoVolumes'         : 'Není dostupný čitelný oddíl.',
 			'errCmdParams'         : 'Nesprávné parametry příkazu "$1".',
 			'errDataNotJSON'       : 'Data nejsou ve formátu JSON.',
@@ -36,7 +39,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errWrite'             : 'Chyba při zápisu do "$1".',
 			'errPerm'              : 'Přístup odepřen.',
 			'errLocked'            : '"$1" je uzamčený a nemůže být přejmenován, přesunut nebo smazán.',
-			'errExists'            : 'Název souboru "$1" již existuje.',
+			'errExists'            : 'Soubor s názvem "$1" již existuje.',
 			'errInvName'           : 'Nesprávný název souboru.',
 			'errFolderNotFound'    : 'Složka nenalezena.',
 			'errFileNotFound'      : 'Soubor nenalezen.',
@@ -57,7 +60,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errSave'              : '"$1" nelze uložit.',
 			'errCopy'              : '"$1" nelze zkopírovat.',
 			'errMove'              : '"$1" nelze přemístit.',
-			'errCopyInItself'      : '"$1" nelze zkopírovat do sama sebe.',
+			'errCopyInItself'      : '"$1" nelze zkopírovat do sebe sama.',
 			'errRm'                : '"$1" nelze odstranit.',
 			'errExtract'           : 'Nelze extrahovat soubory z "$1".',
 			'errArchive'           : 'Nelze vytvořit archív.',
@@ -67,6 +70,8 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errReplByChild'       : 'Složka "$1" nemůže být nahrazena souborem, který sama obsahuje.',
 			'errArcSymlinks'       : 'Z bezpečnostních důvodů je zakázáno rozbalit archívy obsahující symlinky.',
 			'errArcMaxSize'        : 'Soubory archívu překračují maximální povolenou velikost.',
+			'errResize'            : 'Nepodařilo se změnit velikost obrázku "$1".',
+			'errUsupportType'      : 'Nepodporovaný typ souboru.',
 
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Vytvořit archív',
@@ -94,33 +99,37 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdup'        : 'Přejít do nadřazené složky',
 			'cmdupload'    : 'Nahrát soubor(y)',
 			'cmdview'      : 'Zobrazit',
+			'cmdresize'    : 'Změnit velikost',
+			'cmdsort'      : 'Seřadit',
 
 			/*********************************** buttons ***********************************/
 			'btnClose'  : 'Zavřít',
 			'btnSave'   : 'Uložit',
 			'btnRm'     : 'Odstranit',
+			'btnApply'  : 'Použít',
 			'btnCancel' : 'Zrušit',
 			'btnNo'     : 'Ne',
 			'btnYes'    : 'Ano',
 
 			/******************************** notifications ********************************/
-			'ntfopen'     : 'Otevřít složku',
-			'ntffile'     : 'Otevřít soubor',
-			'ntfreload'   : 'Obnovit obsah složky',
+			'ntfopen'     : 'Otevírání složky',
+			'ntffile'     : 'Otevírání souboru',
+			'ntfreload'   : 'Obnovování obsahu složky',
 			'ntfmkdir'    : 'Vytváření složky',
 			'ntfmkfile'   : 'Vytváření souborů',
-			'ntfrm'       : 'Smazat soubory',
-			'ntfcopy'     : 'Kopírovat soubory',
-			'ntfmove'     : 'Přesunout soubory',
+			'ntfrm'       : 'Mazání souborů',
+			'ntfcopy'     : 'Kopírování souborů',
+			'ntfmove'     : 'Přesunování souborů',
 			'ntfprepare'  : 'Příprava ke kopírování souborů',
-			'ntfrename'   : 'Přejmenovat soubory',
+			'ntfrename'   : 'Přejmenovávání souborů',
 			'ntfupload'   : 'Nahrávání souborů',
 			'ntfdownload' : 'Stahování souborů',
-			'ntfsave'     : 'Uložit soubory',
+			'ntfsave'     : 'Ukládání souborů',
 			'ntfarchive'  : 'Vytváření archívu',
 			'ntfextract'  : 'Rozbalování souborů z archívu',
 			'ntfsearch'   : 'Vyhledávání souborů',
 			'ntfsmth'     : 'Čekejte prosím...',
+			'ntfloadimg'  : 'Načítání obrázků',
 
 			/************************************ dates **********************************/
 			'dateUnknown' : 'neznámý',
@@ -138,17 +147,52 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Oct'         : 'Říj',
 			'Nov'         : 'Lis',
 			'Dec'         : 'Pro',
+			'January'     : 'Leden',
+			'February'    : 'Únor',
+			'March'       : 'Březen',
+			'April'       : 'Duben',
+			'May'         : 'Květen',
+			'June'        : 'Červen',
+			'July'        : 'Červenec',
+			'August'      : 'Srpen',
+			'September'   : 'Září',
+			'October'     : 'Říjen',
+			'November'    : 'Listopad',
+			'December'    : 'Prosinec',
+			'Sunday'      : 'Neděle',
+			'Monday'      : 'Pondělí',
+			'Tuesday'     : 'Úterý',
+			'Wednesday'   : 'Středa',
+			'Thursday'    : 'Čtvrtek',
+			'Friday'      : 'Pátek',
+			'Saturday'    : 'Sobota',
+			'Sun'         : 'Ne',
+			'Mon'         : 'Po',
+			'Tue'         : 'Út',
+			'Wed'         : 'St',
+			'Thu'         : 'Čt',
+			'Fri'         : 'Pá',
+			'Sat'         : 'So',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'dle jména (složky přednostně)',
+			'sortkindDirsFirst' : 'dle typu (složky přednostně)',
+			'sortsizeDirsFirst' : 'dle veliksoti (složky přednostně)',
+			'sortdateDirsFirst' : 'dle data (složky přednostně',
+			'sortname'          : 'dle jména',
+			'sortkind'          : 'dle typu',
+			'sortsize'          : 'dle velikosti',
+			'sortdate'          : 'dle data',
 
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Požadováno potvržení',
-			'confirmRm'       : 'Opravdu chcete odstranit tyto soubory?<br/>Změna nelze vrátit!',
+			'confirmRm'       : 'Opravdu chcete odstranit tyto soubory?<br/>Operace nelze vrátit!',
 			'confirmRepl'     : 'Nahradit staré soubory novými?',
 			'apllyAll'        : 'Všem',
 			'name'            : 'Název',
 			'size'            : 'Velikost',
 			'perms'           : 'Práva',
 			'modify'          : 'Upravený',
-			'kind'            : 'Druh',
+			'kind'            : 'Typ',
 			'read'            : 'čtení',
 			'write'           : 'zápis',
 			'noaccess'        : 'přístup nepovolen',
@@ -174,17 +218,17 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'link'            : 'Odkaz',
 			'searcresult'     : 'Výsledky hledání',
 			'selected'        : 'vybrané položky',
-			'about'           : 'O',
+			'about'           : 'O softwaru',
 			'shortcuts'       : 'Zástupci',
 			'help'            : 'Nápověda',
 			'webfm'           : 'Webový správce souborů',
 			'ver'             : 'Verze',
-			'protocol'        : 'verze protokolu',
+			'protocolver'     : 'verze protokolu',
 			'homepage'        : 'Domovská stránka projektu',
 			'docs'            : 'Dokumentace',
 			'github'          : 'Fork us on Github',
-			'twitter'         : 'Follow us on twitter',
-			'facebook'        : 'Join us on facebook',
+			'twitter'         : 'Follow us on Twitter',
+			'facebook'        : 'Join us on Facebook',
 			'team'            : 'Tým',
 			'chiefdev'        : 'séf vývojářů',
 			'developer'       : 'vývojár',
@@ -202,6 +246,17 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'rmFromPlaces'    : 'Odstranit z míst',
 			'untitled folder' : 'bez názvu',
 			'untitled file.txt' : 'nepojmenovaný soubor.txt',
+			'aspectRatio'     : 'Poměr stran',
+			'scale'           : 'Měřítko',
+			'width'           : 'Šířka',
+			'height'          : 'Výška',
+			'mode'            : 'Mód',
+			'resize'          : 'Změnit vel.',
+			'crop'            : 'Ožezat',
+			'rotate'          : 'Otočit',
+			'rotate-cw'       : 'Otočit o +90 stupňů',
+			'rotate-ccw'      : 'Otočit o -90 stupňů',
+			'degree'          : ' stupňů',
 
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Neznámý',

+ 85 - 30
main/inc/lib/elfinder/js/i18n/elfinder.de.js

@@ -1,13 +1,16 @@
 /**
  * German translation
  * @author JPG & Mace <dev@flying-datacenter.de>
- * @version 2011-07-26
+ * @author tora60 from pragmaMx.org
+ * @version 2013-05-01
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.de = {
-		translator : 'JPG & Mace &lt;dev@flying-datacenter.de&gt;',
+		translator : 'JPG & Mace &lt;dev@flying-datacenter.de&gt;, tora60 from pragmaMx.org',
 		language   : 'Deutsch',
 		direction  : 'ltr',
+		dateFormat : 'd. M. Y h:i', // 13. Mai 2012 05:27
+		fancyDateFormat : '$1 h:i', // will produce smth like: Today 12:25 PM
 		messages   : {
 			
 			/********************************** errors **********************************/
@@ -31,7 +34,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errDataEmpty'         : 'Daten sind leer.',
 			'errCmdReq'            : 'Backend Anfrage benötigt Befehl.',
 			'errOpen'              : 'Kann "$1" nicht öffnen',
-			'errNotFolder'         : 'Objekt ist kein Verzeichnis.',
+			'errNotFolder'         : 'Objekt ist kein Ordner.',
 			'errNotFile'           : 'Objekt ist keine Datei.',
 			'errRead'              : 'Kann "$1" nicht öffnen.',
 			'errWrite'             : 'Kann nicht in "$1" schreiben.',
@@ -39,33 +42,53 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errLocked'            : '"$1" ist gelockt und kann nicht umbenannt, verschoben oder gelöscht werden.',
 			'errExists'            : 'Die Datei "$1" existiert bereits.',
 			'errInvName'           : 'Ungültiger Datei Name.',
-			'errFolderNotFound'    : 'Verzeichnis nicht gefunden.',
+			'errFolderNotFound'    : 'Ordner nicht gefunden.',
 			'errFileNotFound'      : 'Datei nicht gefunden.',
-			'errTrgFolderNotFound' : 'Zielverzeichnis "$1" nicht gefunden.',
+			'errTrgFolderNotFound' : 'Zielordner "$1" nicht gefunden.',
 			'errPopup'             : 'Der Browser hat das Pop-Up-Fenster unterbunden. Um die Datei zu öffnen, Pop-Ups in den Browser Einstellungen aktivieren.',
-			'errMkdir'             : 'Kann Verzeichnis "$1" nicht erstellen.',
+			'errMkdir'             : 'Kann Ordner "$1" nicht erstellen.',
 			'errMkfile'            : 'Kann Datei "$1" nicht erstellen.',
 			'errRename'            : 'Kann "$1" nicht umbenennen.',
 			'errCopyFrom'          : 'Kopieren von Dateien von "$1" nicht erlaubt.',
 			'errCopyTo'            : 'Kopieren von Dateien nach "$1" nicht erlaubt.',
-			'errUploadCommon'      : 'Upload Fehler.',
-			'errUpload'            : 'Kann "$1" nicht hochladen.',
+			'errUpload'            : 'Upload Fehler.',
+			'errUploadFile'        : 'Kann "$1" nicht hochladen.',
 			'errUploadNoFiles'     : 'Keine Dateien zum Hochladen gefunden.',
-			'errMaxSize'           : 'Daten überschreiten die Maximalgröße.',
-			'errFileMaxSize'       : 'Die Datei überschreitet die Maximalgröße',
+			'errUploadTotalSize'   : 'Daten überschreiten die Maximalgröße.',
+			'errUploadFileSize'    : 'Die Datei überschreitet die Maximalgröße',
 			'errUploadMime'        : 'Dateityp nicht zulässig.',
-			'errUploadTransfer'    : '"$1" Transfer Fehler.', 
+			'errUploadTransfer'    : '"$1" Transfer Fehler.',
+			'errNotReplace'        : 'Das Objekt "$1" existiert bereits an dieser Stelle und kann nicht durch ein Objekt eines anderen Typs ersetzt werden.',
+			'errReplace'           : 'Kann "$1" nicht ersetzen.',
 			'errSave'              : 'Kann "$1" nicht speichern.',
 			'errCopy'              : 'Kann "$1" nicht kopieren.',
 			'errMove'              : 'Kann "$1" nicht verschieben.',
 			'errCopyInItself'      : '"$1" kann sich nicht in sich selbst kopieren.',
 			'errRm'                : 'Kann "$1" nicht enfernen.',
+			'errRmSrc'             : 'Kann Quelldatei(en) nicht entfernen.',
 			'errExtract'           : 'Kann "$1" nicht entpacken .',
 			'errArchive'           : 'Archiv konnte nicht erstellt werden.',
 			'errArcType'           : 'Archivtyp nicht untersützt.',
 			'errNoArchive'         : 'Bei der Datei handelt es nicht um ein Archiv oder der Archivtyp nicht unterstütz.',
 			'errCmdNoSupport'      : 'Das Backend unterstütz diesen Befehl nicht.',
-			
+			'errReplByChild'       : 'Der Ordner “$1” kann nicht durch etwas ersetzt werden, das ihn selbst enthält.',
+			'errArcSymlinks'       : 'Aus Sicherheitsgründen ist es verboten, ein Archiv mit symbolischen Links zu extrahieren.',
+			'errArcMaxSize'        : 'Die Archiv Dateien übersteigen die maximal erlaubte Größe.',
+			'errResize'            : 'Größe von "$1" kann nicht geändert werden.',
+			'errUsupportType'      : 'Nicht unterstützter Dateityp.',
+			'errNotUTF8Content'    : 'Die Datei "$1" ist nicht im UTF-8 Format und kann nicht editiert werden.',
+			'errNetMount'          : 'Verbindung mit "$1" nicht möglich.',
+			'errNetMountNoDriver'  : 'Nicht unterstütztes Protokoll.',
+			'errNetMountFailed'    : 'Verbindung fehlgeschlagen.',
+			'errNetMountHostReq'   : 'Host benötigz.',
+			'errSessionExpires'    : 'Ihre Sitzung ist aufgrund von Inaktivität abgelaufen',
+			'errCreatingTempDir'   : 'Erstellung des temporären Ordners nicht möglich: "$1"',
+			'errFtpDownloadFile'   : 'Download der Datei über FTP nicht möglich: "$1"',
+			'errFtpUploadFile'     : 'Upload der Datei zu FTP nicht möglich: "$1"',
+			'errFtpMkdir'          : 'Erstellung des Remote-Ordners auf FTP nicht möglich: "$1"',
+			'errArchiveExec'       : 'Fehler bei der Archivierung der Dateien: "$1"',
+			'errExtractExec'       : 'Fehler beim Extrahieren der Dateien: "$1"',
+
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Archiv erstellen',
 			'cmdback'      : 'Zurück',
@@ -78,9 +101,9 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdforward'   : 'Vorwärts',
 			'cmdgetfile'   : 'Datei auswählen',
 			'cmdhelp'      : 'über diese Software',
-			'cmdhome'      : 'Startverzeichnis',
+			'cmdhome'      : 'Startordner',
 			'cmdinfo'      : 'Informationen',
-			'cmdmkdir'     : 'Neues Verzeichnis',
+			'cmdmkdir'     : 'Neuer Ordner',
 			'cmdmkfile'    : 'Neue Textdatei',
 			'cmdopen'      : 'öffnen',
 			'cmdpaste'     : 'Einfügen',
@@ -89,36 +112,43 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdrename'    : 'Umbenennen',
 			'cmdrm'        : 'Löschen',
 			'cmdsearch'    : 'Suchen',
-			'cmdup'        : 'Ins übergeordnete Verzeichnis wechseln',
+			'cmdup'        : 'In übergeordneten Ordner wechseln',
 			'cmdupload'    : 'Datei hochladen',
 			'cmdview'      : 'Ansehen',
+			'cmdresize'    : 'Größe ändern & drehen',
+			'cmdsort'      : 'Sortieren',
+			'cmdnetmount'  : 'Verbinde mit Netzwerkspeicher',
 			
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : 'Schließen',
 			'btnSave'   : 'Speichern',
 			'btnRm'     : 'Entfernen',
+			'btnApply'  : 'Anwenden',
 			'btnCancel' : 'Abbrechen',
 			'btnNo'     : 'Nein',
 			'btnYes'    : 'Ja',
-			
+			'btnMount'  : 'Verbinden',
 			/******************************** notifications ********************************/
-			'ntfopen'     : 'öffne Verzeichnis',
+			'ntfopen'     : 'öffne Ordner',
 			'ntffile'     : 'öffne Datei',
-			'ntfreload'   : 'Verzeichnisinhalt neu',
-			'ntfmkdir'    : 'Erstelle Verzeichnis',
+			'ntfreload'   : 'Ordnerinhalt neu',
+			'ntfmkdir'    : 'Erstelle Ordner',
 			'ntfmkfile'   : 'Erstelle Dateien',
 			'ntfrm'       : 'Lösche Dateien',
 			'ntfcopy'     : 'Kopiere Dateien files',
 			'ntfmove'     : 'Verschiebe Dateien',
 			'ntfprepare'  : 'Kopiervorgang initialisieren',
 			'ntfrename'   : 'Benenne Dateien um',
-			'ntfupload'   : 'Uploading files',
-			'ntfdownload' : 'Downloading files',
+			'ntfupload'   : 'Dateien hochladen',
+			'ntfdownload' : 'Dateien herunterladen',
 			'ntfsave'     : 'Speichere Datei',
 			'ntfarchive'  : 'Erstelle Archiv',
 			'ntfextract'  : 'Entpacke Dateien',
 			'ntfsearch'   : 'Suche',
-			'ntfsmth'     : 'Bin beschäftigt >_<',
+			'ntfresize'   : 'Bildgrößen ändern',
+			'ntfsmth'     : 'Bin beschäftigt',
+			'ntfloadimg'  : 'Bild laden',
+			'ntfnetmount' : 'Mit Netzwerkspeicher verbinden',
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : 'unbekannt',
@@ -137,6 +167,13 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Nov'         : 'Nov',
 			'Dec'         : 'Dez',
 
+			/******************************** sort variants ********************************/
+			'sortname'         : 'nach Name',
+			'sortkind'         : 'nach Typ',
+			'sortsize'         : 'nach Größe',
+			'sortdate'         : 'nach Datum',
+			'sortFoldersFirst' : 'Ordner zuerst',
+
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Bestätigung Benötigt',
 			'confirmRm'       : 'Sollen die Dateien gelöscht werden?<br/>Dies kann nicht rückgängig gemacht werden!',
@@ -159,25 +196,25 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'viewlist'        : 'Spaltenansicht',
 			'viewicons'       : 'Symbolansicht',
 			'places'          : 'Orte',
-			'calc'            : 'Berechne', 
+			'calc'            : 'Berechne',
 			'path'            : 'Pfad',
 			'aliasfor'        : 'Verknüpfund zu',
 			'locked'          : 'Gesperrt',
 			'dim'             : 'Bildgröße',
 			'files'           : 'Dateien',
-			'folders'         : 'Verzeichnise',
+			'folders'         : 'Ordner',
 			'items'           : 'Objekte',
 			'yes'             : 'ja',
 			'no'              : 'nein',
 			'link'            : 'Link',
-			'searcresult'     : 'Suchergebnisse',  
+			'searcresult'     : 'Suchergebnisse',
 			'selected'        : 'Objekte ausgewählt',
 			'about'           : 'über',
 			'shortcuts'       : 'Tastenkombinationen',
 			'help'            : 'Hilfe',
 			'webfm'           : 'Web Datei Manager',
 			'ver'             : 'Version',
-			'protocol'        : 'Protokol Version',
+			'protocolver'     : 'Protokol Version',
 			'homepage'        : 'Projekt Website',
 			'docs'            : 'Dokumentation',
 			'github'          : 'Forke uns auf Github',
@@ -190,17 +227,35 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'maintainer'      : 'Maintainer',
 			'translator'      : 'Übersetzer',
 			'icons'           : 'Icons',
-			'dontforget'      : 'und vergess dein Handtuch nicht',
-			'shortcutsof'     : 'Shortcuts disabled',
+			'dontforget'      : 'und vergiss dein Handtuch nicht',
+			'shortcutsof'     : 'Tastenkombinationen deaktiviert',
 			'dropFiles'       : 'Dateien hier ablegen',
+			'dropFilesBrowser': 'Verschieben oder Einfügen von Dateien aus dem Browser',
 			'or'              : 'oder',
 			'selectForUpload' : 'Dateien zum Upload auswählen',
 			'moveFiles'       : 'Dateien verschieben',
 			'copyFiles'       : 'Dateien kopieren',
-						
+			'rmFromPlaces'    : 'Lösche von Orte',
+			'aspectRatio'     : 'Seitenverhältnis',
+			'scale'           : 'Maßstab',
+			'width'           : 'Breite',
+			'height'          : 'Höhe',
+			'resize'          : 'Größe ändern',
+			'crop'            : 'Zuschneiden',
+			'rotate'          : 'Drehen',
+			'rotate-cw'       : 'Drehe 90° im Uhrzeigersinn',
+			'rotate-ccw'      : 'Drehe 90° gegen den Uhrzeigersinn',
+			'degree'          : '°',
+			'netMountDialogTitle' : 'verbinde Netzwerk Speicher',
+			'protocol'            : 'Protokoll',
+			'host'                : 'Host',
+			'port'                : 'Port',
+			'user'                : 'Benutzer',
+			'pass'                : 'Passwort',
+
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Unbekannt',
-			'kindFolder'      : 'Verzeichnis',
+			'kindFolder'      : 'Ordner',
 			'kindAlias'       : 'Verknüpfung',
 			'kindAliasBroken' : 'Defekte Verknüpfung',
 			// applications

+ 355 - 0
main/inc/lib/elfinder/js/i18n/elfinder.el.js

@@ -0,0 +1,355 @@
+/**
+ * elFinder translation template
+ * use this file to create new translation
+ * submit new translation via https://github.com/Studio-42/elFinder/issues
+ * or make a pull request
+ */
+ 
+/**
+ * Greek translation
+ * @author yawd <info@yawd.eu>
+ * @version 2012-09-12
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.el = {
+		translator : 'yawd &lt;ingo@yawd.eu&gt;',
+		language   : 'Ελληνικά',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : 'Πρόβλημα',
+			'errUnknown'           : 'Άγνωστο πρόβλημα.',
+			'errUnknownCmd'        : 'Άγνωστη εντολή.',
+			'errJqui'              : 'Μη έγκυρη ρύθμιση του jQuery UI. Τα components "selectable", "draggable" και "droppable" πρέπει να περιληφούν.',
+			'errNode'              : 'το elFinder χρειάζεται να έχει δημιουργηθεί το DOM Element.',
+			'errURL'               : 'Μη έγκυρες ρυθμίσεις για το elFinder! η επιλογή URL δεν έχει οριστεί.',
+			'errAccess'            : 'Απαγορεύεται η πρόσβαση.',
+			'errConnect'           : 'Δεν ήταν δυνατή η σύνδεση με το backend.',
+			'errAbort'             : 'Η σύνδεση εγκαταλείφθηκε.',
+			'errTimeout'           : 'Η σύνδεση έληξε.',
+			'errNotFound'          : 'Δε βρέθηκε το backend.',
+			'errResponse'          : 'Μή έγκυρη απάντηση από το backend.',
+			'errConf'              : 'Μη έγκυρες ρυθμίσεις για το backend.',
+			'errJSON'              : 'Το PHP JSON module δεν είναι εγκατεστημένο.',
+			'errNoVolumes'         : 'Δεν βρέθηκαν αναγνώσιμα volumes.',
+			'errCmdParams'         : 'Μη εέγκυρες παράμετροι για την εντολή "$1".',
+			'errDataNotJSON'       : 'Τα δεδομένα δεν είναι JSON.',
+			'errDataEmpty'         : 'Τα δεδομένα είναι άδεια.',
+			'errCmdReq'            : 'Το Backend request χρειάζεται όνομα εντολής.',
+			'errOpen'              : 'Δεν ήταν δυνατό να ανοίξει το "$1".',
+			'errNotFolder'         : 'Το αντικείμενο δεν είναι φάκελος.',
+			'errNotFile'           : 'Το αντικείμενο δεν είναι αρχείο.',
+			'errRead'              : 'Δεν ήταν δυνατόν να διαβαστεί το "$1".',
+			'errWrite'             : 'Δεν ήταν δυνατή η εγγραφή στο "$1".',
+			'errPerm'              : 'Απαγορεύεται η πρόσβαση.',
+			'errLocked'            : '"$1" είναι κλειδωμένο και δεν μπορεί να μετονομαστεί, μετακινηθεί ή διαγραφεί.',
+			'errExists'            : 'Το αρχείο με όνομα "$1" υπάρχει ήδη.',
+			'errInvName'           : 'Μη έγκυρο όνομα αρχείου.',
+			'errFolderNotFound'    : 'Ο φάκελος δε βρέθηκε.',
+			'errFileNotFound'      : 'Το αρχείο δε βρέθηκε.',
+			'errTrgFolderNotFound' : 'Ο φάκελος "$1" δε βρεέθηκε.',
+			'errPopup'             : 'Το πρόγραμμα πλήγησης αμπόδισε το άνοιγμα αναδυόμενου παραθύρου. Για ανοίξετε το αρχείο ενεργοποιήστε το στις επιλογές του περιηγητή.',
+			'errMkdir'             : 'Η δυμιουργία του φακέλου "$1" δεν ήταν δυνατή.',
+			'errMkfile'            : 'Η δημιουργία του αρχείου "$1" δεν ήταν δυνατή.',
+			'errRename'            : 'Η μετονομασία του αρχείου "$1" δεν ήταν δυνατή.',
+			'errCopyFrom'          : 'Δεν επιτρέπεται η αντιγραφή αρχείων από το volume "$1".',
+			'errCopyTo'            : 'Δεν επιτρέπεται η αντιγραφή αρχείων στο volume "$1".',
+			'errUploadCommon'      : 'Πρόβλημα κατά το upload.',
+			'errUpload'            : 'Το αρχείο "$1" δεν μπόρεσε να γίνει upload.',
+			'errUploadNoFiles'     : 'Δεν βρέθηκαν αρχεία για upload.',
+			'errMaxSize'           : 'Τα δεδομένα υπερβαίνουν το επιτρεπόμενο μέγιστο μέγεθος δεδομένων.',
+			'errFileMaxSize'       : 'Το αρχείο υπερβαίνει το επιτρεπόμενο μέγιστο μέγεθος.',
+			'errUploadMime'        : 'Ο τύπος αρχείου δεν επιτρέπεται.',
+			'errUploadTransfer'    : 'Πρόβλημα μεταφοράς για το "$1".', 
+			'errSave'              : 'Το "$1" δεν ήταν δυνατόν να αποθηκευτεί.',
+			'errCopy'              : 'Δεν ήταν δυνατή η αντιγραφή του "$1".',
+			'errMove'              : 'Δεν ήταν δυνατή η μετακίνηση του "$1".',
+			'errCopyInItself'      : 'Δεν είναι δυνατή η αντιγραφή του "$1" στον εαυτό του.',
+			'errRm'                : 'Δεν ήταν δυνατή η αφαίρεση του "$1".',
+			'errExtract'           : 'Δεν ήταν δυνατή η ανάγνωση των αρχείων από "$1".',
+			'errArchive'           : 'Δεν ήταν δυνατή η δημιουργία του αρχείου.',
+			'errArcType'           : 'Ο τύπος αρχείου δεν υποστηρίζεται.',
+			'errNoArchive'         : 'Το αρχείο δεν είναι έγκυρο ή δεν υποστηρίζεται ο τύπος του.',
+			'errCmdNoSupport'      : 'Το backend δεν υποστηρίζει αυτή την εντολή.',
+			'errReplByChild'       : 'Ο φάκελος “$1” δεν μπορεί να αντικατασταθεί από οποιοδήποτε αρχείο περιέχεται σε αυτόν.',
+			'errArcSymlinks'       : 'Για λόγους ασφαλείας δεν είναι δυνατόν να διαβαστούν αρχεία που περιέχουν symlinks orη αρχεία με μη επιτρεπτά ονόματα.', // edited 24.06.2012
+			'errArcMaxSize'        : 'Το μέγεθος του αρχείου υπερβαίνει το μέγιστο επιτρεπτό όριο.',
+			'errResize'            : 'Δεν ήταν δυνατή η αλλαγή μεγέθους του "$1".',
+			'errUsupportType'      : 'Ο τύπος αρχείου δεν υποστηρίζεται.',
+			'errNotUTF8Content'    : 'Το αρχείο "$1" δεν είναι UTF-8 και δεν μπορεί να επεξεργασθεί.',  // added 9.11.2011
+			'errNetMount'          : 'Δεν ήταν δυνατή η φόρτωση του "$1".',     // added 17.04.2012
+			'errNetMountNoDriver'  : 'Μη υποστηριζόμενο πρωτόκολο.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Η φόρτωση απέτυχε.',             // added 17.04.2012
+			'errNetMountHostReq'   : 'Απαιτείται host εξυπηρετητής.', // added 18.04.2012
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Δημιουργία archive αρχείου',
+			'cmdback'      : 'Πίσω',
+			'cmdcopy'      : 'Αντιγραφή',
+			'cmdcut'       : 'Αφαίρεση',
+			'cmddownload'  : 'Μεταφόρτωση',
+			'cmdduplicate' : 'Αντίγραφο',
+			'cmdedit'      : 'Επεξεργασία αρχείου',
+			'cmdextract'   : 'Εξαγωγή αρχείων από archive',
+			'cmdforward'   : 'Προώθηση',
+			'cmdgetfile'   : 'Επιλέξτε αρχεία',
+			'cmdhelp'      : 'Σχετικά με αυτό το λογισμικό',
+			'cmdhome'      : 'Home',
+			'cmdinfo'      : 'Πληροφορίες',
+			'cmdmkdir'     : 'Νέος φάκελος',
+			'cmdmkfile'    : 'Νέο αρχείο κειμένου',
+			'cmdopen'      : 'Άνοιγμα',
+			'cmdpaste'     : 'Επικόλληση',
+			'cmdquicklook' : 'Προεπισκόπηση',
+			'cmdreload'    : 'Ανανέωση',
+			'cmdrename'    : 'Μετονομασία',
+			'cmdrm'        : 'Διαγραφή',
+			'cmdsearch'    : 'Έυρεση αρχείων',
+			'cmdup'        : 'Μετάβαση στο γονικό φάκελο',
+			'cmdupload'    : 'Ανέβασμα αρχείων',
+			'cmdview'      : 'Προβολή',
+			'cmdresize'    : 'Αλλαγή μεγέθους εικόνας',
+			'cmdsort'      : 'Ταξινόμηση',
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Κλείσιμο',
+			'btnSave'   : 'Αποθήκευση',
+			'btnRm'     : 'Αφαίρεση',
+			'btnApply'  : 'Εφαρμογή',
+			'btnCancel' : 'Ακύρωση',
+			'btnNo'     : 'Όχι',
+			'btnYes'    : 'Ναι',
+			
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Άνοιγμα φακέλου',
+			'ntffile'     : 'Άνοιγμα αρχείου',
+			'ntfreload'   : 'Ανανέωση περιεχομένων φακέλου',
+			'ntfmkdir'    : 'Δημιουργία φακέλου',
+			'ntfmkfile'   : 'Δημιουργία αρχείων',
+			'ntfrm'       : 'Διαγραφή αρχείων',
+			'ntfcopy'     : 'Αντιγραφή αρχείων',
+			'ntfmove'     : 'Μετακίνηση αρχείων',
+			'ntfprepare'  : 'Προετοιμασία αντιγραφής αρχείων',
+			'ntfrename'   : 'Μετονομασία αρχείων',
+			'ntfupload'   : 'Ανέβασμα αρχείων',
+			'ntfdownload' : 'Μεταφόρτωση αρχείων',
+			'ntfsave'     : 'Αποθήκευση αρχείων',
+			'ntfarchive'  : 'Δημιουργία αρχείου',
+			'ntfextract'  : 'Εξαγωγή αρχείων από το archive',
+			'ntfsearch'   : 'Αναζήτηση αρχείων',
+			'ntfsmth'     : 'Σύστημα απασχολημένο>_<',
+			'ntfloadimg'  : 'Φόρτωση εικόνας',
+			'ntfnetmount' : 'Φόρτωση δικτυακού δίσκου', // added 18.04.2012
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : 'άγνωστο',
+			'Today'       : 'Σήμερα',
+			'Yesterday'   : 'Εχθές',
+			'Jan'         : 'Ιαν',
+			'Feb'         : 'Φεβ',
+			'Mar'         : 'Μαρ',
+			'Apr'         : 'Απρ',
+			'May'         : 'Μαϊ',
+			'Jun'         : 'Ιουν',
+			'Jul'         : 'Ιουλ',
+			'Aug'         : 'Αυγ',
+			'Sep'         : 'Σεπ',
+			'Oct'         : 'Οκτ',
+			'Nov'         : 'Νοεμ',
+			'Dec'         : 'Δεκ',
+			'January'     : 'Ιανουάριος',
+			'February'    : 'Φεβρουάριος',
+			'March'       : 'Μάρτιος',
+			'April'       : 'Απρίλιος',
+			'May'         : 'Μάϊος',
+			'June'        : 'Ιούνιος',
+			'July'        : 'Ιούλιος',
+			'August'      : 'Αύγουστος',
+			'September'   : 'Σεπτέμβριος',
+			'October'     : 'Οκτώβριος',
+			'November'    : 'Νοέμβριος',
+			'December'    : 'Δεκέμβριος',
+			'Sunday'      : 'Κυριακή', 
+			'Monday'      : 'Δευτέρα', 
+			'Tuesday'     : 'Τρίτη', 
+			'Wednesday'   : 'Τετάρτη', 
+			'Thursday'    : 'Πέμπτη', 
+			'Friday'      : 'Παρασκευή', 
+			'Saturday'    : 'Σάββατο',
+			'Sun'         : 'Κυρ', 
+			'Mon'         : 'Δευ', 
+			'Tue'         : 'Τρ', 
+			'Wed'         : 'Τετ', 
+			'Thu'         : 'Πεμ', 
+			'Fri'         : 'Παρ', 
+			'Sat'         : 'Σαβ',
+			/******************************** sort variants ********************************/
+			'sortname'          : 'κατά όνομα', 
+			'sortkind'          : 'κατά είδος', 
+			'sortsize'          : 'κατά μέγεθος',
+			'sortdate'          : 'κατά ημερομηνία',
+			'sortFoldersFirst'  : 'Πρώτα οι φάκελοι', // added 22.06.2012
+			
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Απαιτείται επιβεβαίωση',
+			'confirmRm'       : 'Είστε σίγουροι πως θέλετε να διαγράψετε τα αρχεία?<br/>Οι αλλαγές θα είναι μόνιμες!',
+			'confirmRepl'     : 'Αντικατάσταση του παλιού αρχείου με το νέο?',
+			'apllyAll'        : 'Εφαρμογή σε όλλα',
+			'name'            : 'Όνομα',
+			'size'            : 'Μέγεθος',
+			'perms'           : 'Δικαιώματα',
+			'modify'          : 'Τροποποιήθηκε',
+			'kind'            : 'Είδος',
+			'read'            : 'ανάγνωση',
+			'write'           : 'εγγραφή',
+			'noaccess'        : 'δεν υπάρχει πρόσβαση',
+			'and'             : 'και',
+			'unknown'         : 'άγνωστο',
+			'selectall'       : 'Επιλογή όλων',
+			'selectfiles'     : 'Επιλογή αρχείων',
+			'selectffile'     : 'Επιλογή πρώτου αρχείου',
+			'selectlfile'     : 'Επιλογή τελευταίου αρχείου',
+			'viewlist'        : 'Προβολή λίστας',
+			'viewicons'       : 'Προβολή εικονιδίων',
+			'places'          : 'Τοποθεσίες',
+			'calc'            : 'Υπολογισμός', 
+			'path'            : 'Διαδρομή',
+			'aliasfor'        : 'Ψευδώνυμο για',
+			'locked'          : 'Κλειδωμένο',
+			'dim'             : 'Διαστάσεις',
+			'files'           : 'Αρχεία',
+			'folders'         : 'Φάκελοι',
+			'items'           : 'Ατικείμενα',
+			'yes'             : 'ναι',
+			'no'              : 'όχι',
+			'link'            : 'Σλυνδεσμος',
+			'searcresult'     : 'Αποτελέσματα αναζήτησης',  
+			'selected'        : 'επιλεγμένα αντικείμενα',
+			'about'           : 'Σχετικά',
+			'shortcuts'       : 'Συντομέυσεις',
+			'help'            : 'Βοήθεια',
+			'webfm'           : 'εργαλέιο διαχείρισης αρχείων από το web',
+			'ver'             : 'ΈΚδοση',
+			'protocolver'     : 'έκδοση πρωτοκόλλου',
+			'homepage'        : 'Σελίδα του project',
+			'docs'            : 'Τεκμηρίωση (documentation)',
+			'github'          : 'Κάντε μας fork στο Github',
+			'twitter'         : 'Ακολουθήστε μας στο twitter',
+			'facebook'        : 'Βρείτε μας στο facebook',
+			'team'            : 'Ομάδα',
+			'chiefdev'        : 'κύριος προγραμματιστής',
+			'developer'       : 'προγραμματισής',
+			'contributor'     : 'συνισφορά',
+			'maintainer'      : 'συντηρητής',
+			'translator'      : 'μεταφραστής',
+			'icons'           : 'Εικονίδια',
+			'dontforget'      : 'και μην ξεχάσεις την πετσέτα σου!',
+			'shortcutsof'     : 'Οι συντομεύσεις είναι απενεργοποιημένες',
+			'dropFiles'       : 'Κάντε drop τα αρχεία εδώ',
+			'or'              : 'ή',
+			'selectForUpload' : 'Επιλογή αρχείων για ανέβασμα',
+			'moveFiles'       : 'Μετακίνηση αρχείων',
+			'copyFiles'       : 'Αντιγραφή αρχείων',
+			'rmFromPlaces'    : 'Αντιγραφή από τοποθεσίες',
+			'untitled folder' : 'untitled folder',
+			'untitled file.txt' : 'untitled file.txt',
+			'aspectRatio'     : 'Αναλογία διαστάσεων',
+			'scale'           : 'Κλίμακα',
+			'width'           : 'Πλάτος',
+			'height'          : 'Ύψος',
+			'mode'            : 'Κατάσταση',
+			'resize'          : 'Αλλαγή μεγέθους',
+			'crop'            : 'Crop',
+			'rotate'          : 'Περιστροφή',
+			'rotate-cw'       : 'Περιστροφή κατά 90 βαθμούς CW',
+			'rotate-ccw'      : 'Περιστροφή κατά 90 βαθμούς CCW',
+			'degree'          : 'Βαθμός',
+			'netMountDialogTitle' : 'Φορτώστε δικτυακό δίσκο', // added 18.04.2012
+			'protocol'            : 'Πρωτόκολλο', // added 18.04.2012
+			'host'                : 'Host', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'Χρήστης', // added 18.04.2012
+			'pass'                : 'Κωδικός', // added 18.04.2012
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Άγνωστο',
+			'kindFolder'      : 'Φάκελος',
+			'kindAlias'       : 'Ψευδώνυμο (alias)',
+			'kindAliasBroken' : 'Μη έγκυρο ψευδώνυμο',
+			// applications
+			'kindApp'         : 'Εφαρμοφή',
+			'kindPostscript'  : 'Έγγραφο Postscript',
+			'kindMsOffice'    : 'Έγγραφο Microsoft Office',
+			'kindMsWord'      : 'Έγγραφο Microsoft Word',
+			'kindMsExcel'     : 'Έγγραφο Microsoft Excel',
+			'kindMsPP'        : 'Παρουσίαση Microsoft Powerpoint',
+			'kindOO'          : 'Έγγραφο Open Office',
+			'kindAppFlash'    : 'Εφαρμογή Flash',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Αρχείο Bittorrent',
+			'kind7z'          : 'Αρχείο 7z',
+			'kindTAR'         : 'Αρχείο TAR',
+			'kindGZIP'        : 'Αρχείο GZIP',
+			'kindBZIP'        : 'Αρχείο BZIP',
+			'kindZIP'         : 'Αρχείο ZIP',
+			'kindRAR'         : 'Αρχείο RAR',
+			'kindJAR'         : 'Αρχείο Java JAR',
+			'kindTTF'         : 'Γραμματοσειρά True Type',
+			'kindOTF'         : 'Γραμματοσειρά Open Type',
+			'kindRPM'         : 'Πακέτο RPM',
+			// texts
+			'kindText'        : 'Έγγραφο κειμένου',
+			'kindTextPlain'   : 'Απλό κείμενο',
+			'kindPHP'         : 'Κώδικας PHP',
+			'kindCSS'         : 'Cascading style sheet',
+			'kindHTML'        : 'Έγγραφο HTML',
+			'kindJS'          : 'Κώδικας Javascript',
+			'kindRTF'         : 'Rich Text Format',
+			'kindC'           : 'Κώδικας C',
+			'kindCHeader'     : 'Κώδικας κεφαλίδας C',
+			'kindCPP'         : 'Κώδικας C++',
+			'kindCPPHeader'   : 'Κώδικας κεφαλίδας C++',
+			'kindShell'       : 'Unix shell script',
+			'kindPython'      : 'Κώδικας Python',
+			'kindJava'        : 'Κώδικας Java',
+			'kindRuby'        : 'Κώδικας Ruby',
+			'kindPerl'        : 'Perl script',
+			'kindSQL'         : 'Κώδικας SQL',
+			'kindXML'         : 'Έγγραφο XML',
+			'kindAWK'         : 'Κώδικας AWK',
+			'kindCSV'         : 'Τιμές χωρισμένες με κόμμα',
+			'kindDOCBOOK'     : 'Έγγραφο Docbook XML',
+			// images
+			'kindImage'       : 'Εικόνα',
+			'kindBMP'         : 'Εικόνα BMP',
+			'kindJPEG'        : 'Εικόνα JPEG',
+			'kindGIF'         : 'Εικόνα GIF',
+			'kindPNG'         : 'Εικόνα PNG',
+			'kindTIFF'        : 'Εικόνα TIFF',
+			'kindTGA'         : 'Εικόνα TGA',
+			'kindPSD'         : 'Εικόνα Adobe Photoshop',
+			'kindXBITMAP'     : 'Εικόνα X bitmap',
+			'kindPXM'         : 'Εικόνα Pixelmator',
+			// media
+			'kindAudio'       : 'Αρχεία ήχου',
+			'kindAudioMPEG'   : 'Ήχος MPEG',
+			'kindAudioMPEG4'  : 'Εικόνα MPEG-4',
+			'kindAudioMIDI'   : 'Εικόνα MIDI',
+			'kindAudioOGG'    : 'Εικόνα Ogg Vorbis',
+			'kindAudioWAV'    : 'Εικόνα WAV',
+			'AudioPlaylist'   : 'MP3 playlist',
+			'kindVideo'       : 'Αρχεία media',
+			'kindVideoDV'     : 'Ταινία DV',
+			'kindVideoMPEG'   : 'Ταινία MPEG',
+			'kindVideoMPEG4'  : 'Ταινία MPEG-4',
+			'kindVideoAVI'    : 'Ταινία AVI',
+			'kindVideoMOV'    : 'Ταινία Quick Time',
+			'kindVideoWM'     : 'Ταινία Windows Media',
+			'kindVideoFlash'  : 'Ταινία flash',
+			'kindVideoMKV'    : 'Ταινία matroska',
+			'kindVideoOGG'    : 'Ταινία ogg'
+		}
+	}
+}
+

+ 33 - 17
main/inc/lib/elfinder/js/i18n/elfinder.es.js

@@ -1,7 +1,8 @@
 /**
  * Spanish translation
  * @author Julián Torres <julian.torres@pabernosmatao.com>
- * @version 2011-08-25
+ * @author Julio Montoya <gugli100@gmail.com> - Fixing typos
+ * @version 2013-05-08
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.es = {
@@ -27,7 +28,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errJSON'              : 'El módulo PHP JSON no está instalado.',
 			'errNoVolumes'         : 'No hay disponibles volúmenes legibles.',
 			'errCmdParams'         : 'Parámetros no válidos para el comando "$1".',
-			'errDataNotJSON'       : 'los datos no estñan en formato JSON.',
+			'errDataNotJSON'       : 'los datos no estan en formato JSON.',
 			'errDataEmpty'         : 'No hay datos.',
 			'errCmdReq'            : 'La petición del backend necesita un nombre de comando.',
 			'errOpen'              : 'No se puede abrir "$1".',
@@ -48,19 +49,19 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errRename'            : 'No se puede renombrar "$1".',
 			'errCopyFrom'          : 'No se permite copiar archivos desde el volumen "$1".',
 			'errCopyTo'            : 'No se permite copiar archivos al volumen "$1".',
-			'errUploadCommon'      : 'Error en el envñio.',
+			'errUploadCommon'      : 'Error en el envio.',
 			'errUpload'            : 'No se puede subir "$1".',
 			'errUploadNoFiles'     : 'No hay archivos para subir.',
 			'errMaxSize'           : 'El tamaño de los datos excede el máximo permitido.',
 			'errFileMaxSize'       : 'El tamaño del archivo excede el máximo permitido.',
-			'errUploadMime'        : 'Tipo de archivo no permitidp.',
+			'errUploadMime'        : 'Tipo de archivo no permitido.',
 			'errUploadTransfer'    : 'Error al transferir "$1".', 
-			'errSave'              : 'No se puede guadar "$1".',
+			'errSave'              : 'No se puede guardar "$1".',
 			'errCopy'              : 'No se puede copiar "$1".',
 			'errMove'              : 'No se puede mover "$1".',
-			'errCopyInItself'      : 'No se puede copiar "$1" into itself.',
+			'errCopyInItself'      : 'No se puede copiar "$1" en si mismo.',
 			'errRm'                : 'No se puede borrar "$1".',
-			'errExtract'           : 'No se puede extraer archivos from "$1".',
+			'errExtract'           : 'No se puede extraer archivos desde "$1".',
 			'errArchive'           : 'No se puede crear el archivo.',
 			'errArcType'           : 'Tipo de archivo no soportado.',
 			'errNoArchive'         : 'El archivo no es de tipo archivo o es de un tipo no soportado.',
@@ -68,6 +69,21 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errReplByChild'       : 'La carpeta “$1” no puede ser reemplazada por un elemento contenido en ella.',
 			'errArcSymlinks'       : 'Por razones de seguridad no se pueden descomprimir archivos que contengan symlinks.',
 			'errArcMaxSize'        : 'El tamaño del archivo excede el máximo permitido.',
+
+			'errSessionExpires'    : 'La sesión ha expirado por inactividad',
+			'errCreatingTempDir'   : 'No se ha podido crear al directorio temporal: "$1"',
+			'errFtpDownloadFile'   : 'No se ha podido descargar el archivo desde FTP: "$1"',
+			'errFtpUploadFile'     : 'No se ha podido cargar el archivo a FTP: "$1"',
+			'errFtpMkdir'          : 'No se ha podido crear el directorio remoto en FTP: "$1"',
+			'errArchiveExec'       : 'Se ha producido un error durante la archivación: "$1"',
+			'errExtractExec'       : 'Se ha producido un error durante la extracción de archivos: "$1"',
+			'cmdsort'              : 'Clasificar',
+			'sortkind'             : 'por tipo',
+			'sortname'             : 'por nombre',
+			'sortsize'             : 'por tamaño',
+			'sortdate'             : 'por fecha',
+			'sortFoldersFirst'     : 'Las carpetas en primer lugar',
+			'errUploadFile'        : 'No se ha podido cargar "$1".',
 			
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Crear archivo',
@@ -83,7 +99,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdhelp'      : 'Acerca de este software',
 			'cmdhome'      : 'Inicio',
 			'cmdinfo'      : 'Obtener información',
-			'cmdmkdir'     : 'Nueva arpeta',
+			'cmdmkdir'     : 'Nueva carpeta',
 			'cmdmkfile'    : 'Nuevo archivo de texto',
 			'cmdopen'      : 'Abrir',
 			'cmdpaste'     : 'Pegar',
@@ -110,7 +126,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfreload'   : 'Actualizar contenido de la carpeta',
 			'ntfmkdir'    : 'Creando directorio',
 			'ntfmkfile'   : 'Creando archivos',
-			'ntfrm'       : 'Eliminndo archivos',
+			'ntfrm'       : 'Eliminando archivos',
 			'ntfcopy'     : 'Copiar archivos',
 			'ntfmove'     : 'Mover archivos',
 			'ntfprepare'  : 'Preparar copia de archivos',
@@ -121,8 +137,8 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfarchive'  : 'Creando archivo',
 			'ntfextract'  : 'Extrayendo elementos del archivo',
 			'ntfsearch'   : 'Buscando archivos',
-			'ntfsmth'     : 'Haciendo algo >_<',
-      'ntfloadimg'  : 'Cargando imagen',
+			'ntfsmth'     : 'Haciendo algo',
+			'ntfloadimg'  : 'Cargando imagen',
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : 'desconocida',
@@ -144,7 +160,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Se necesita confirmación',
 			'confirmRm'       : '¿Está seguro de querer eliminar archivos?<br/>Esto no tiene vuelta atrás!',
-			'confirmRepl'     : '¿Reemplazar el antigüo archivo con el nuevo?',
+			'confirmRepl'     : '¿Reemplazar el antiguo archivo con el nuevo?',
 			'apllyAll'        : 'Aplicar a todo',
 			'name'            : 'Nombre',
 			'size'            : 'Tamaño',
@@ -181,12 +197,12 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Ayuda',
 			'webfm'           : 'Administrador de archivos web',
 			'ver'             : 'Version',
-			'protocol'        : 'versión del protocolo',
-			'homepage'        : 'Project home',
+			'protocolver'     : 'versión del protocolo',
+			'homepage'        : 'Inicio',
 			'docs'            : 'Documentación',
 			'github'          : 'Fork us on Github',
 			'twitter'         : 'Síguenos en Twitter',
-			'facebook'        : 'Únete a nostros en Facebook',
+			'facebook'        : 'Únete a nosotros en Facebook',
 			'team'            : 'Equipo',
 			'chiefdev'        : 'desarrollador jefe',
 			'developer'       : 'desarrollador',
@@ -201,7 +217,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'selectForUpload' : 'Seleccione archivos para subir',
 			'moveFiles'       : 'Mover archivos',
 			'copyFiles'       : 'Copiar archivos',
-			'rmFromPlaces'    : 'Eliminar en sus ubicaciónes',
+			'rmFromPlaces'    : 'Eliminar en sus ubicaciones',
 			'untitled folder' : 'carpeta sin título',
 			'untitled archivo.txt' : 'archivo.txt sin título',
       'mode'            : 'Modo',
@@ -242,7 +258,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'kindHTML'        : 'Documento HTML',
 			'kindJS'          : 'Código Javascript',
 			'kindRTF'         : 'Documento RTF',
-			'kindC'           : 'C source',
+			'kindC'           : 'Código C source',
 			'kindCHeader'     : 'Código C header',
 			'kindCPP'         : 'Código C++',
 			'kindCPPHeader'   : 'Código C++ header',

+ 339 - 0
main/inc/lib/elfinder/js/i18n/elfinder.fa.js

@@ -0,0 +1,339 @@
+/**
+ * Persian-Farsi Translation
+ * @author Keyhan Mohammadpour <keyhan_universityworks@yahoo.com>
+ * @version 2012-04-07
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.fa = {
+		translator : 'Keyhan Mohammadpour &lt;keyhan_universityworks@yahoo.com&gt;',
+		language   : 'فارسی',
+		direction  : 'rtl',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+
+			/********************************** errors **********************************/
+			'error'                : 'خطا',
+			'errUnknown'           : 'خطای ناشناخته .',
+			'errUnknownCmd'        : 'دستور ناشناخته .',
+			'errJqui'              : 'تنظیمات کتابخانه JQuery UI شما به درستی تنظیم نشده است . این کتابخانه بایستی شامل Resizable ، Draggable و Droppable باشد .',
+			'errNode'              : 'شی elfinder به درستی ایجاد نشده است .',
+			'errURL'               : 'تنظیمات elfinder شما به درستی انجام نشده است . تنظیم Url را به درستی انجام دهید .',
+			'errAccess'            : 'محدودیت سطح دسترسی',
+			'errAbort'             : 'ارتباط قطع شده است .',
+			'errTimeout'           : 'مهلت زمانی Connection شما به انتها رسیده ایت .',
+			'errNotFound'          : 'تنظیم Backend یافت نشد .',
+			'errResponse'          : 'پاسخ دریافتی از Backend صحیح نمی باشد .',
+			'errConf'              : 'تنطیمات Backend به درستی انجام نشده است .',
+			'errJSON'              : 'ماژول PHP JSON نصب نگردیده است .',
+			'errNoVolumes'         : 'درایوهای قابل خواندن یافت نشدند .',
+			'errCmdParams'         : 'پارامترهای دستور "$1" به صورت صحیح داده نشده است .',
+			'errDataNotJSON'       : 'داده ها در قالب JSON نمی باشند .',
+			'errDataEmpty'         : 'داده ها تهی می باشند .',
+			'errCmdReq'            : 'درخواست از سمت Backend نیازمند نام دستور می باشد .',
+			'errOpen'              : 'قادر به باز نمودن "$1" نمی باشد .',
+			'errNotFolder'         : 'شی به صورت پوشه نمی باشد .',
+			'errNotFile'           : 'شی به صورت فایل نمی باشد .',
+			'errRead'              : 'قادر به خواندن "$1" نمی باشد .',
+			'errWrite'             : 'قادر به نوشتن در درون "$1" نمی باشد .',
+			'errPerm'              : 'شما مجاز به انجام این عمل نمی باشید .',
+			'errLocked'            : '"$1"قفل گردیده است و شما قادر به تغییر نام ، حذف و یا جابجایی آن نمی باشید .',
+			'errExists'            : 'فایلی با نام "$1" هم اکنون وجود دارد .',
+			'errInvName'           : 'نام انتخابی شما صحیح نمی باشد .',
+			'errFolderNotFound'    : 'پوشه مورد نظر شما یافت نشد .',
+			'errFileNotFound'      : 'فایل مورد نظر شما یافت نشد .',
+			'errTrgFolderNotFound' : 'پوشه مقصد با نام "$1" یافت نشد .',
+			'errPopup'             : 'مرورگر شما ار باز شدن پنجره popup جلوگیری می نماید ، اطفا تنطیم مربوطه را در مرورگر خود فعال نمایید .',
+			'errMkdir'             : 'قادر به ایجاد نمودن پوشه ای با نام "$1" نمی باشد .',
+			'errMkfile'            : 'قادر به ابجاد نمودن فایلی با نبم "$1" نمی باشد .',
+			'errRename'            : 'قادر به تغییر نام فایل "$1" نمی باشد .',
+			'errCopyFrom'          : 'کپی نمودن از درایو با نام "$1" امکان پذیر نمی باشد .',
+			'errCopyTo'            : 'کپی نمودن به درایو با نام "$1" امکان پذیر نمی باشد .',
+			'errUploadCommon'      : 'خطای بارگذاری ',
+			'errUpload'            : 'قادر به بارگذاری "$1" نمی باشد .',
+			'errUploadNoFiles'     : 'هیچ فایلی برای بارگذاری یافت نشد .',
+			'errMaxSize'           : 'حجم داده ها بیشتر از حد مجاز تعیین شده است .',
+			'errFileMaxSize'       : 'حجم فایل بیشتر از حد مجاز تعیین شده است .',
+			'errUploadMime'        : 'نوع فایل انتخابی شما مجاز نمی باشد .',
+			'errUploadTransfer'    : 'در تبادل "$1" خطایی رخ داده است .',
+			'errSave'              : 'قادر به دخیره کردن "$1" نمی باشد .',
+			'errCopy'              : 'قادر به کپی نمودن "$1" نمی باشد .',
+			'errMove'              : 'قادر به جابجایی "$1" نمی باشد .',
+			'errCopyInItself'      : 'قادر به کپی نمودن "$1" در درون خودش نمی باشد .',
+			'errRm'                : 'قادر به حذف نمودن "$1" نمی باشد .',
+			'errExtract'           : 'قادر به استخراج فایل فشرده "$1" نمی باشد .',
+			'errArchive'           : 'قادر به ایجاد آرشیو نمی باشد .',
+			'errArcType'           : 'نوع ناشناخته برای آرشیو .',
+			'errNoArchive'         : 'قادر به آرشیو نمودن فایل نمی باشد و یا نوع فایل در نوع های آرشیو تعیین نشده است .',
+			'errCmdNoSupport'      : 'Backend قادر به پشتیبانی از این دستور نمی باشد .',
+			'errReplByChild'       : 'پوشه با نام "$1"قادر به تغییر با محتویات درونی خود نمی باشد .',
+			'errArcSymlinks'       : 'به دلایل مسائل امنیتی قادر به استخراج آرشیو های دارای symlinks نمی باشد .',
+			'errArcMaxSize'        : 'فایل های آرشیو شده به حداکثر اندازه تعیین شده رسیده اند .',
+			'errResize'            : 'قادر به تغییر اندازه "$1" نمی باشد .',
+			'errUsupportType'      : 'نوع فایل شما قابل پشتیبانی نمی باشد .',
+
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'ساختن آرشیو',
+			'cmdback'      : 'قبلی',
+			'cmdcopy'      : 'کپی',
+			'cmdcut'       : 'جابجایی',
+			'cmddownload'  : 'بارگیری',
+			'cmdduplicate' : 'تکثیر نمودن',
+			'cmdedit'      : 'ویرایش فایل',
+			'cmdextract'   : 'از حالت فشرده خارج نمودن',
+			'cmdforward'   : 'بعدی',
+			'cmdgetfile'   : 'انتخاب فایل ها',
+			'cmdhelp'      : 'درباره این فایل',
+			'cmdhome'      : 'صفحه اصلی',
+			'cmdinfo'      : 'دریافت اطلاعات',
+			'cmdmkdir'     : 'پوشه جدید',
+			'cmdmkfile'    : 'فایل متنی جدید',
+			'cmdopen'      : 'باز نمودن',
+			'cmdpaste'     : 'چسباندن',
+			'cmdquicklook' : 'پیش نمایش',
+			'cmdreload'    : 'بارگذاری مجدد',
+			'cmdrename'    : 'تغییر نام',
+			'cmdrm'        : 'حذف',
+			'cmdsearch'    : 'جستجو',
+			'cmdup'        : 'رفتن به پوشه والد',
+			'cmdupload'    : 'بارگذاری فایل ها',
+			'cmdview'      : 'نمایش',
+			'cmdresize'    : 'تغییر اندازه فایل',
+			'cmdsort'      : 'مرتب سازی',
+
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'بستن',
+			'btnSave'   : 'ذخیره',
+			'btnRm'     : 'حذف',
+			'btnApply'  : 'اعمال',
+			'btnCancel' : 'انصراف',
+			'btnNo'     : 'خیر',
+			'btnYes'    : 'بلی',
+
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'باز نمودن پوشه',
+			'ntffile'     : 'باز نمدن فایل',
+			'ntfreload'   : 'بازخوانی مجدد محتویات پوشه',
+			'ntfmkdir'    : 'ساختن پوشه',
+			'ntfmkfile'   : 'ساختن فایل',
+			'ntfrm'       : 'حذف فایل',
+			'ntfcopy'     : 'کپی فایل',
+			'ntfmove'     : 'انتقال فایل',
+			'ntfprepare'  : 'آماده شدن برای کپی نمودن فایل ها',
+			'ntfrename'   : 'تغییر نام فایل',
+			'ntfupload'   : 'بارگذاری فایل',
+			'ntfdownload' : 'بارگیری فایل',
+			'ntfsave'     : 'ذخیره نمودن فایل ها',
+			'ntfarchive'  : 'در حال ساختن آرشیو',
+			'ntfextract'  : 'استخراج فایل ها از آرشیو',
+			'ntfsearch'   : 'در حال جستجو فایل ها',
+			'ntfsmth'     : 'درحال انجام عملیات ....',
+			'ntfloadimg'  : 'در حال لود نمودن تصویر',
+
+			/************************************ dates **********************************/
+			'dateUnknown' : 'ناشناخته',
+			'Today'       : 'امروز',
+			'Yesterday'   : 'دیروز',
+			'Jan'         : 'بهمن',
+			'Feb'         : 'اسفند',
+			'Mar'         : 'فروردین',
+			'Apr'         : 'اردیبهشت',
+			'May'         : 'خرداد',
+			'Jun'         : 'تیر',
+			'Jul'         : 'مرداد',
+			'Aug'         : 'شهریور',
+			'Sep'         : 'مهر',
+			'Oct'         : 'آبان',
+			'Nov'         : 'آذر',
+			'Dec'         : 'دی',
+			'January'     : 'بهمن',
+			'February'    : 'اسفند',
+			'March'       : 'فروردین',
+			'April'       : 'اردیبهشت',
+			'May'         : 'خرداد',
+			'June'        : 'تیر',
+			'July'        : 'مرداد',
+			'August'      : 'شهریور',
+			'September'   : 'مهر',
+			'October'     : 'آبان',
+			'November'    : 'آذر',
+			'December'    : 'دی',
+			'Sunday'      : 'یک شنبه',
+			'Monday'      : 'دوشنبه',
+			'Tuesday'     : 'سه شنبه',
+			'Wednesday'   : 'چهار شنبه',
+			'Thursday'    : 'پنج شنبه',
+			'Friday'      : 'جمعه',
+			'Saturday'    : 'شنبه',
+			'Sun'         : 'یک شنبه',
+			'Mon'         : 'دو شنبه',
+			'Tue'         : 'سه شنبه',
+			'Wed'         : 'چهار شنبه',
+			'Thu'         : 'پنج شنبه',
+			'Fri'         : 'جمعه',
+			'Sat'         : 'شنبه',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'بر اساس نام (پوشه ها در ابتدا قرار می گیرند ) .',
+			'sortkindDirsFirst' : 'بر اساس نوع (پوشه ها در ابتدا قرار می گیرند ) .',
+			'sortsizeDirsFirst' : 'بر اساس اندازه (پوشه ها در ابتدا قرار می گیرند ) .',
+			'sortdateDirsFirst' : 'بر اساس تاریخ (پوشه ها در ابتدا قرار می گیرند ) .',
+			'sortname'          : 'بر اساس نام',
+			'sortkind'          : 'بر اساس نوع',
+			'sortsize'          : 'بر اساس اندازه',
+			'sortdate'          : 'بر اساس تاریخ',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : 'تاییدیه نهایی نیاز است .',
+			'confirmRm'       : 'آیا مطمثن به انجام عملیات حذف می باشید ؟ آیتم های حدف شده قابل بازیابی نمی باشند  !',
+			'confirmRepl'     : 'آیا فایل قدیم با فایل جدید جایگزین شود ؟',
+			'apllyAll'        : 'اعمال تغییرات به همه',
+			'name'            : 'نام',
+			'size'            : 'اندازه',
+			'perms'           : 'مجوزها',
+			'modify'          : 'تغییر داده شده',
+			'kind'            : 'نوع',
+			'read'            : 'خواندن',
+			'write'           : 'نوشتن',
+			'noaccess'        : 'دسترسی وجود ندارد',
+			'and'             : 'و',
+			'unknown'         : 'ناشناخته',
+			'selectall'       : 'انتخاب همه فایل ها',
+			'selectfiles'     : 'انتخاب یکی یا همه فایل ها',
+			'selectffile'     : 'انتخاب اولین فایل',
+			'selectlfile'     : 'انتخاب آخرین فایل',
+			'viewlist'        : 'نمایش به صورت لیست',
+			'viewicons'       : 'نمایش با آیکون ها',
+			'places'          : 'محل ها',
+			'calc'            : 'محاسبه',
+			'path'            : 'مسیر',
+			'aliasfor'        : 'نام مستعار برای',
+			'locked'          : 'قفل شده',
+			'dim'             : 'ابعاد',
+			'files'           : 'فایل ها',
+			'folders'         : 'پوشه ها',
+			'items'           : 'آیتم ها',
+			'yes'             : 'بلی',
+			'no'              : 'خیر',
+			'link'            : 'پیوند',
+			'searcresult'     : 'جستجو در نتایج',
+			'selected'        : 'آیتم های انتخاب شده',
+			'about'           : 'درباره',
+			'shortcuts'       : 'میانبرها',
+			'help'            : 'راهنما',
+			'webfm'           : 'مدیر وب فایل',
+			'ver'             : 'نسخه',
+			'protocol'        : 'نسخه پروتکل',
+			'homepage'        : 'صفحه اصلی پروژه',
+			'docs'            : 'مستندات',
+			'github'          : 'دنبال کردن ما بر روی Github',
+			'twitter'         : 'دنبال کردن ما در Twitter',
+			'facebook'        : 'به ما در facebook بپیوندید',
+			'team'            : 'گروه',
+			'chiefdev'        : 'سازنده اصلی برنامه',
+			'developer'       : 'سازنده',
+			'contributor'     : 'همکار',
+			'maintainer'      : 'پشتیبان',
+			'translator'      : 'مترجم',
+			'icons'           : 'آیکون ها',
+			'dontforget'      : 'فراموش نشود',
+			'shortcutsof'     : 'میانبرها غیرفعال شده اند .',
+			'dropFiles'       : 'فایل های خود را در این محل رها نمایید .',
+			'or'              : 'یا',
+			'selectForUpload' : 'انتخاب فایل ها برای بارگذاری',
+			'moveFiles'       : 'انتقال فایل ها',
+			'copyFiles'       : 'کپی فایل ها',
+			'rmFromPlaces'    : 'حدف',
+			'untitled folder' : 'پوشه بدون نام',
+			'untitled file.txt' : 'فایل متنی بدون نام',
+			'aspectRatio'     : 'نسبت تصویر',
+			'scale'           : 'مقیاس',
+			'width'           : 'طول',
+			'height'          : 'ارتفاع',
+			'mode'            : 'مد',
+			'resize'          : 'تغییر اندازه',
+			'crop'            : 'بریدن',
+			'rotate'          : 'چرخاندن',
+			'rotate-cw'       : 'چرخاندن 90 درجه در جهت عقربه های ساعت',
+			'rotate-ccw'      : 'چرخاندن 90 درجه در جهت خلاف عقربه های ساعت',
+			'degree'          : 'درجه',
+
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Unknown',
+			'kindFolder'      : 'Folder',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : 'Broken alias',
+			// applications
+			'kindApp'         : 'Application',
+			'kindPostscript'  : 'Postscript document',
+			'kindMsOffice'    : 'Microsoft Office document',
+			'kindMsWord'      : 'Microsoft Word document',
+			'kindMsExcel'     : 'Microsoft Excel document',
+			'kindMsPP'        : 'Microsoft Powerpoint presentation',
+			'kindOO'          : 'Open Office document',
+			'kindAppFlash'    : 'Flash application',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent file',
+			'kind7z'          : '7z archive',
+			'kindTAR'         : 'TAR archive',
+			'kindGZIP'        : 'GZIP archive',
+			'kindBZIP'        : 'BZIP archive',
+			'kindZIP'         : 'ZIP archive',
+			'kindRAR'         : 'RAR archive',
+			'kindJAR'         : 'Java JAR file',
+			'kindTTF'         : 'True Type font',
+			'kindOTF'         : 'Open Type font',
+			'kindRPM'         : 'RPM package',
+			// texts
+			'kindText'        : 'Text document',
+			'kindTextPlain'   : 'Plain text',
+			'kindPHP'         : 'PHP source',
+			'kindCSS'         : 'Cascading style sheet',
+			'kindHTML'        : 'HTML document',
+			'kindJS'          : 'Javascript source',
+			'kindRTF'         : 'Rich Text Format',
+			'kindC'           : 'C source',
+			'kindCHeader'     : 'C header source',
+			'kindCPP'         : 'C++ source',
+			'kindCPPHeader'   : 'C++ header source',
+			'kindShell'       : 'Unix shell script',
+			'kindPython'      : 'Python source',
+			'kindJava'        : 'Java source',
+			'kindRuby'        : 'Ruby source',
+			'kindPerl'        : 'Perl script',
+			'kindSQL'         : 'SQL source',
+			'kindXML'         : 'XML document',
+			'kindAWK'         : 'AWK source',
+			'kindCSV'         : 'Comma separated values',
+			'kindDOCBOOK'     : 'Docbook XML document',
+			// images
+			'kindImage'       : 'Image',
+			'kindBMP'         : 'BMP image',
+			'kindJPEG'        : 'JPEG image',
+			'kindGIF'         : 'GIF Image',
+			'kindPNG'         : 'PNG Image',
+			'kindTIFF'        : 'TIFF image',
+			'kindTGA'         : 'TGA image',
+			'kindPSD'         : 'Adobe Photoshop image',
+			'kindXBITMAP'     : 'X bitmap image',
+			'kindPXM'         : 'Pixelmator image',
+			// media
+			'kindAudio'       : 'Audio media',
+			'kindAudioMPEG'   : 'MPEG audio',
+			'kindAudioMPEG4'  : 'MPEG-4 audio',
+			'kindAudioMIDI'   : 'MIDI audio',
+			'kindAudioOGG'    : 'Ogg Vorbis audio',
+			'kindAudioWAV'    : 'WAV audio',
+			'AudioPlaylist'   : 'MP3 playlist',
+			'kindVideo'       : 'Video media',
+			'kindVideoDV'     : 'DV movie',
+			'kindVideoMPEG'   : 'MPEG movie',
+			'kindVideoMPEG4'  : 'MPEG-4 movie',
+			'kindVideoAVI'    : 'AVI movie',
+			'kindVideoMOV'    : 'Quick Time movie',
+			'kindVideoWM'     : 'Windows Media movie',
+			'kindVideoFlash'  : 'Flash movie',
+			'kindVideoMKV'    : 'Matroska movie',
+			'kindVideoOGG'    : 'Ogg movie'
+		}
+	}
+}

+ 70 - 30
main/inc/lib/elfinder/js/i18n/elfinder.fr.js

@@ -1,13 +1,15 @@
 /**
  * French translation
- * @author Régis Guyomarch <regisg@gmail.com>
- * @version 2011-07-11
+ * @author Régis Guyomarch <regisg@gmail.com>, Benoit Delachaux <benorde33@gmail.com>
+ * @version 2012-08-11
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.fr = {
-		translator : 'Régis Guyomarch &lt;regisg@gmail.com&gt;',
+		translator : 'Régis Guyomarch &lt;regisg@gmail.com&gt;Benoit Delachaux &lt;benorde33@gmail.com&gt;',
 		language   : 'française',
 		direction  : 'ltr',
+		dateFormat : 'd M, Y H:i',
+		fancyDateFormat : '$1 H:i',
 		messages   : {
 			
 			/********************************** errors **********************************/
@@ -36,7 +38,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errRead'              : 'Impossible de lire "$1".',
 			'errWrite'             : 'Impossible d\'écrire dans "$1".',
 			'errPerm'              : 'Permission refusée.',
-			'errLocked'            : '"$1" est verrouillé et ne peut être déplace ou supprimé.',
+			'errLocked'            : '"$1" est verrouillé et ne peut être déplacé ou supprimé.',
 			'errExists'            : 'Un fichier nommé "$1" existe déjà.',
 			'errInvName'           : 'Nom de fichier incorrect.',
 			'errFolderNotFound'    : 'Dossier non trouvé.',
@@ -47,20 +49,23 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errMkfile'            : 'impossible de créer le fichier "$1".',
 			'errRename'            : 'Impossible de renommer "$1".',
 			'errCopyFrom'          : 'Interdiction de copier des fichiers depuis le volume "$1".',
-			'errCopyTo'            : 'Interdiction copier des fichiers vers le volume "$1".',
-			'errUploadCommon'      : 'Erreur lors de l\'envoi du fichier.',
-			'errUpload'            : 'Impossible d\'envoyer "$1".',
-			'errUploadNoFiles'     : 'Aucun fichier a envoyer.',
-			'errMaxSize'           : 'Les données dépassent la taille maximale allouée.',
-			'errFileMaxSize'       : 'Le fichier dépasse la taille maximale allouée.',
+			'errCopyTo'            : 'Interdiction de copier des fichiers vers le volume "$1".',
+			'errUpload'            : 'Erreur lors de l\'envoi du fichier.',
+			'errUploadFile'        : 'Impossible d\'envoyer "$1".',
+			'errUploadNoFiles'     : 'Aucun fichier à envoyer.',
+			'errUploadTotalSize'   : 'Les données dépassent la taille maximale allouée.',
+			'errUploadFileSize'    : 'Le fichier dépasse la taille maximale allouée.',
 			'errUploadMime'        : 'Type de fichier non autorisé.',
 			'errUploadTransfer'    : '"$1" erreur transfert.', 
+			'errNotReplace'        : 'L\'objet "$1" existe déjà à cet endroit et ne peut être remplacé par un objet d\'un type différent.', // new
+			'errReplace'           : 'Impossible de remplacer "$1".', // added 11.08.1013
 			'errSave'              : 'Impossible de sauvegarder "$1".',
 			'errCopy'              : 'Impossible de copier "$1".',
 			'errMove'              : 'Impossible de déplacer "$1".',
 			'errCopyInItself'      : 'Impossible de copier "$1" sur lui-même.',
 			'errRm'                : 'Impossible de supprimer "$1".',
 			'errExtract'           : 'Impossible d\'extraire les fichier de "$1".',
+			'errExtract'           : 'Imbossible d\'extraire les fichiers à partir de "$1".', // added 11.08.2012
 			'errArchive'           : 'Impossible de créer l\'archive.',
 			'errArcType'           : 'Type d\'archive non supporté.',
 			'errNoArchive'         : 'Le fichier n\'est pas une archive, ou c\'est un type d\'archive non supporté.',
@@ -68,6 +73,24 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errReplByChild'       : 'Le dossier “$1” ne peut pas être remplacé par un élément qu\'il contient.',
 			'errArcSymlinks'       : 'Par mesure de sécurité, il est défendu d\'extraire une archive contenant des liens symboliques.',
 			'errArcMaxSize'        : 'Les fichiers de l\'archive excèdent la taille maximale autorisée.',
+			'errResize'            : 'Impossible de redimensionner "$1".',
+			'errResizeDegree'      : 'Degré de rotation invalide.',  // added 11.8.2013
+			'errResizeRotate'      : 'L\'image ne peut pas être tournée.',  // added 11.8.2013
+			'errResizeSize'        : 'Dimension de l\'image non-valide.',  // added 11.8.2013
+			'errResizeNoChange'    : 'L\'image n\'est pas redimensionnable.',  // added 11.8.2013
+			'errUsupportType'      : 'Type de fichier non supporté.',
+			'errNotUTF8Content'    : 'Le fichier "$1" n\'est pas en UTF-8, il ne peut être édité.',  // added 9.11.2011
+			'errNetMount'          : 'Impossible de monter "$1".', // added 17.04.2012
+			'errNetMountNoDriver'  : 'Protocol non supporté.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Echec du montage.',         // added 17.04.2012
+			'errNetMountHostReq'   : 'Hôte requis.', // added 18.04.2012			
+			'errSessionExpires'    : 'Votre session a expiré en raison de son inactivité',
+			'errCreatingTempDir'   : 'Impossible de créer le répertoire temporaire : "$1"',
+			'errFtpDownloadFile'   : 'Impossible de télécharger le file depuis l\'accès FTP : "$1"',
+			'errFtpUploadFile'     : 'Impossible d\'envoyer le fichier vers l\'accès FTP : "$1"',
+			'errFtpMkdir'          : 'Impossible de créer un répertoire distant sur l\'accès FTP :"$1"',
+			'errArchiveExec'       : 'Erreur lors de l\'archivage des fichiers : "$1"',
+			'errExtractExec'       : 'Erreur lors de l\'extraction des fichiers : "$1"',
 			
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Créer une archive',
@@ -80,7 +103,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdextract'   : 'Extraire les fichiers de l\'archive',
 			'cmdforward'   : 'Suivant',
 			'cmdgetfile'   : 'Sélectionner les fichiers',
-			'cmdhelp'      : 'À propose de ce logiciel',
+			'cmdhelp'      : 'À propos de ce logiciel',
 			'cmdhome'      : 'Accueil',
 			'cmdinfo'      : 'Informations',
 			'cmdmkdir'     : 'Nouveau dossier',
@@ -95,16 +118,19 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdup'        : 'Remonter au dossier parent',
 			'cmdupload'    : 'Envoyer les fichiers',
 			'cmdview'      : 'Vue',
-			'cmdresize'    : 'Redimmensionner l\'image',
+			'cmdresize'    : 'Redimensionner l\'image',
 			'cmdsort'      : 'Trier',
+			'cmdnetmount'  : 'Monter un volume réseau',
 			
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : 'Fermer',
 			'btnSave'   : 'Sauvegarder',
 			'btnRm'     : 'Supprimer',
 			'btnCancel' : 'Annuler',
+			'btnApply'  : 'Appliquer', // added 11.08.2013
 			'btnNo'     : 'Non',
 			'btnYes'    : 'Oui',
+			'btnMount'  : 'Monter',  // added 18.04.2012
 			
 			/******************************** notifications ********************************/
 			'ntfopen'     : 'Ouvrir le dossier',
@@ -123,7 +149,10 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfarchive'  : 'Création de l\'archive',
 			'ntfextract'  : 'Extraction des fichiers de l\'archive',
 			'ntfsearch'   : 'Recherche des fichiers',
-			'ntfsmth'     : 'Fait quelque chose >_<',
+			'ntfsmth'     : 'Fait quelque chose',
+			'ntfloadimg'  : 'Chargement de l\' image',
+			'ntfnetmount' : 'Monte le volume réseau', // added 18.04.2012			
+			'ntfdim'      : 'Calcule la dimension de l\'image', // added 11.08.2013
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : 'Inconnue',
@@ -143,15 +172,12 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Dec'         : 'Déc',
 
 			/******************************** sort variants ********************************/
-			'sortnameDirsFirst' : 'par nom (dossiers en premier)', 
-			'sortkindDirsFirst' : 'par type (dossiers en premier)', 
-			'sortsizeDirsFirst' : 'par taille (dossiers en premier)', 
-			'sortdateDirsFirst' : 'par date (dossiers en premier)', 
 			'sortname'          : 'par nom', 
 			'sortkind'          : 'par type', 
 			'sortsize'          : 'par taille',
 			'sortdate'          : 'par date',
-
+			'sortFoldersFirst'  : 'Dossiers en premier',
+			
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Confirmation requise',
 			'confirmRm'       : 'Êtes-vous certain de vouloir supprimer les fichiers?<br/>Cela ne peut être annulé!',
@@ -192,7 +218,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Aide',
 			'webfm'           : 'Gestionnaire de fichier Web',
 			'ver'             : 'Version',
-			'protocol'        : 'Version du protocole',
+			'protocolver'     : 'Version du protocole',
 			'homepage'        : 'Page du projet',
 			'docs'            : 'Documentation',
 			'github'          : 'Forker-nous sur Github',
@@ -213,25 +239,39 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'moveFiles'       : 'Déplacer les fichiers',
 			'copyFiles'       : 'Copier les fichiers',
 			'rmFromPlaces'    : 'Remove from places',
-			'untitled folder' : 'dossier sans nom',
-			'untitled file.txt' : 'sans nom file.txt',
+			'aspectRatio'     : 'Aspect ratio',
+			'scale'           : 'Mise à l\'échelle',
+			'width'           : 'Largeur',
+			'height'          : 'Hauteur',
+			'resize'          : 'Redimensionner',
+			'crop'            : 'Recadrer',
+			'rotate'          : 'Rotation',
+			'rotate-cw'       : 'Rotation de 90 degrés horaire',
+			'rotate-ccw'      : 'Rotation de 90 degrés antihoraire',
+			'degree'          : '°',
+			'netMountDialogTitle' : 'Monter un volume réseau', // added 18.04.2012
+			'protocol'            : 'Protocole', // added 18.04.2012
+			'host'                : 'Hôte', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'Utilisateur', // added 18.04.2012
+			'pass'                : 'Mot de passe', // added 18.04.2012
 			
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Inconnu',
 			'kindFolder'      : 'Dossier',
-			'kindAlias'       : 'Raccourcis',
-			'kindAliasBroken' : 'Raccourcis cassé',
+			'kindAlias'       : 'Raccourci',
+			'kindAliasBroken' : 'Raccourci cassé',
 			// applications
 			'kindApp'         : 'Application',
 			'kindPostscript'  : 'Document Postscript',
 			'kindMsOffice'    : 'Document Microsoft Office',
 			'kindMsWord'      : 'Document Microsoft Word',
 			'kindMsExcel'     : 'Document Microsoft Excel',
-			'kindMsPP'        : 'Présentation Microsoft Powerpoint',
-			'kindOO'          : 'Document Open Office',
-			'kindAppFlash'    : 'Application flash',
+			'kindMsPP'        : 'Présentation Microsoft PowerPoint',
+			'kindOO'          : 'Document OpenOffice',
+			'kindAppFlash'    : 'Application Flash',
 			'kindPDF'         : 'Portable Document Format (PDF)',
-			'kindTorrent'     : 'Fichier Bittorrent',
+			'kindTorrent'     : 'Fichier BitTorrent',
 			'kind7z'          : 'Archive 7z',
 			'kindTAR'         : 'Archive TAR',
 			'kindGZIP'        : 'Archive GZIP',
@@ -246,10 +286,10 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'kindText'        : 'Document Text',
 			'kindTextPlain'   : 'Texte non formaté',
 			'kindPHP'         : 'Source PHP',
-			'kindCSS'         : 'Cascading style sheet',
+			'kindCSS'         : 'Feuille de style en cascade',
 			'kindHTML'        : 'Document HTML',
-			'kindJS'          : 'Source Javascript',
-			'kindRTF'         : 'Rich Text Format',
+			'kindJS'          : 'Source JavaScript',
+			'kindRTF'         : 'Format de texte enrichi (Rich Text Format)',
 			'kindC'           : 'Source C',
 			'kindCHeader'     : 'Source header C',
 			'kindCPP'         : 'Source C++',

+ 1 - 1
main/inc/lib/elfinder/js/i18n/elfinder.hu.js

@@ -177,7 +177,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Súgó',
 			'webfm'           : 'Web file manager',
 			'ver'             : 'Verzió',
-			'protocol'        : 'protokol verzió',
+			'protocolver'     : 'protokol verzió',
 			'homepage'        : 'Projekt honlap',
 			'docs'            : 'Dokumentáció',
 			'github'          : 'Hozz létre egy új verziót a Github-on',

+ 340 - 0
main/inc/lib/elfinder/js/i18n/elfinder.it.js

@@ -0,0 +1,340 @@
+/**
+ * Italian translation
+ * @author Alberto Tocci <alberto.tocci@gmail.com>
+ * @version 2012-05-09
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.it = {
+		translator : 'Alberto Tocci (alberto.tocci@gmail.com)',
+		language   : 'Italiano',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+
+			/********************************** errors **********************************/
+			'error'                : 'Errore',
+			'errUnknown'           : 'Errore sconosciuto.',
+			'errUnknownCmd'        : 'Comando sconosciuto.',
+			'errJqui'              : 'Configurazione JQuery UI non valida. Devono essere inclusi i plugin Selectable, Draggable e Droppable.',
+			'errNode'              : 'elFinder necessita dell\'elemento DOM per essere inizializzato.',
+			'errURL'               : 'Configurazione non valida.Il parametro URL non è settato.',
+			'errAccess'            : 'Accesso non consentito.',
+			'errConnect'           : 'Impossibile collegarsi al backend.',
+			'errAbort'             : 'Connessione terminata.',
+			'errTimeout'           : 'Timeout di connessione.',
+			'errNotFound'          : 'Backend non trovato.',
+			'errResponse'          : 'Risposta non valida dal backend.',
+			'errConf'              : 'Configurazione backend non valida.',
+			'errJSON'              : 'Modulo PHP JSON non installato.',
+			'errNoVolumes'         : 'Non è stato possibile leggere i volumi.',
+			'errCmdParams'         : 'Parametri non validi per il comando "$1".',
+			'errDataNotJSON'       : 'I dati non sono nel formato JSON.',
+			'errDataEmpty'         : 'Stringa vuota.',
+			'errCmdReq'            : 'Backend request requires command name.',
+			'errOpen'              : 'Impossibile aprire "$1".',
+			'errNotFolder'         : 'L\'oggetto non è una cartella..',
+			'errNotFile'           : 'L\'oggetto non è un file.',
+			'errRead'              : 'Impossibile leggere "$1".',
+			'errWrite'             : 'Non è possibile scrivere in "$1".',
+			'errPerm'              : 'Permesso negato.',
+			'errLocked'            : '"$1" è bloccato e non può essere rinominato, spostato o eliminato.',
+			'errExists'            : 'Il file "$1" è già esistente.',
+			'errInvName'           : 'Nome file non valido.',
+			'errFolderNotFound'    : 'Cartella non trovata.',
+			'errFileNotFound'      : 'File non trovato.',
+			'errTrgFolderNotFound' : 'La cartella di destinazione"$1" non è stata trovata.',
+			'errPopup'             : 'Il tuo Browser non consente di aprire finestre di pop-up. Per aprire il file abilita questa opzione nelle impostazioni del tuo Browser.',
+			'errMkdir'             : 'Impossibile creare la cartella "$1".',
+			'errMkfile'            : 'Impossibile creare il file "$1".',
+			'errRename'            : 'Impossibile rinominare "$1".',
+			'errCopyFrom'          : 'Non è possibile copiare file da "$1".',
+			'errCopyTo'            : 'Non è possibile copiare file in "$1".',
+			'errUploadCommon'      : 'Errore di Caricamento.',
+			'errUpload'            : 'Impossibile Caricare "$1".',
+			'errUploadNoFiles'     : 'Non sono stati specificati file da caricare.',
+			'errMaxSize'           : 'La dimensione totale dei file supera il limite massimo consentito.',
+			'errFileMaxSize'       : 'Le dimensioni del file superano il massimo consentito.',
+			'errUploadMime'        : 'FileType non consentito.',
+			'errUploadTransfer'    : 'Trasferimento errato del file "$1".', 
+			'errSave'              : 'Impossibile salvare "$1".',
+			'errCopy'              : 'Impossibile copiare "$1".',
+			'errMove'              : 'Impossibile spostare "$1".',
+			'errCopyInItself'      : 'Sorgente e destinazione risultato essere uguali.',
+			'errRm'                : 'Impossibile rimuovere "$1".',
+			'errExtract'           : 'Impossibile estrarre file da "$1".',
+			'errArchive'           : 'Impossibile creare archivio.',
+			'errArcType'           : 'Tipo di archivio non supportato.',
+			'errNoArchive'         : 'Il file non è un archivio o contiene file non supportati.',
+			'errCmdNoSupport'      : 'Il Backend non supporta questo comando.',
+			'errReplByChild'       : 'La cartella $1 non può essere sostituita da un oggetto in essa contenuto.',
+			'errArcSymlinks'       : 'Per questioni di sicurezza non è possibile estrarre archivi che contengono collegamenti..',
+			'errArcMaxSize'        : 'La dimensione dell\'archivio supera le massime dimensioni consentite.',
+			'errResize'            : 'Impossibile ridimensionare "$1".',
+			'errUsupportType'      : 'FileType non supportato.',
+
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Crea Archivio',
+			'cmdback'      : 'Indietro',
+			'cmdcopy'      : 'Copia',
+			'cmdcut'       : 'Taglia',
+			'cmddownload'  : 'Download',
+			'cmdduplicate' : 'Duplica',
+			'cmdedit'      : 'Modifica File',
+			'cmdextract'   : 'Estrai Archivio',
+			'cmdforward'   : 'Avanti',
+			'cmdgetfile'   : 'Seleziona File',
+			'cmdhelp'      : 'About',
+			'cmdhome'      : 'Home',
+			'cmdinfo'      : 'Informazioni',
+			'cmdmkdir'     : 'Nuova cartella',
+			'cmdmkfile'    : 'Nuovo file di testo',
+			'cmdopen'      : 'Apri',
+			'cmdpaste'     : 'Incolla',
+			'cmdquicklook' : 'Anteprima',
+			'cmdreload'    : 'Ricarica',
+			'cmdrename'    : 'Rinomina',
+			'cmdrm'        : 'Cancella',
+			'cmdsearch'    : 'Ricerca file',
+			'cmdup'        : 'Vai alla directory padre',
+			'cmdupload'    : 'Carica File',
+			'cmdview'      : 'Visualizza',
+			'cmdresize'    : 'Ridimensiona Immagine',
+			'cmdsort'      : 'Ordina',
+
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Chiudi',
+			'btnSave'   : 'Salva',
+			'btnRm'     : 'Rimuovi',
+			'btnApply'  : 'Applica',
+			'btnCancel' : 'Cancella',
+			'btnNo'     : 'No',
+			'btnYes'    : 'Si',
+
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Apri cartella',
+			'ntffile'     : 'Apri file',
+			'ntfreload'   : 'Ricarica il contenuto della cartella',
+			'ntfmkdir'    : 'Creazione delle directory in corso',
+			'ntfmkfile'   : 'Creazione dei files in corso',
+			'ntfrm'       : 'Cancellazione files in corso',
+			'ntfcopy'     : 'Copia file in corso',
+			'ntfmove'     : 'Spostamento file in corso',
+			'ntfprepare'  : 'Inizializzando la copia dei file.',
+			'ntfrename'   : 'Sto rinominando i file',
+			'ntfupload'   : 'Caricamento file in corso',
+			'ntfdownload' : 'Downloading file in corso',
+			'ntfsave'     : 'Salvataggio file in corso',
+			'ntfarchive'  : 'Creazione archivio in corso',
+			'ntfextract'  : 'Estrazione file dall\'archivio in corso',
+			'ntfsearch'   : 'Ricerca files in corso',
+			'ntfsmth'     : 'Operazione in corso. Attendere...',
+			'ntfloadimg'  : 'Caricamento immagine in corso',
+
+			/************************************ dates **********************************/
+			'dateUnknown' : 'sconosciuto',
+			'Today'       : 'Oggi',
+			'Yesterday'   : 'Ieri',
+			'Jan'         : 'Gen',
+			'Feb'         : 'Feb',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Apr',
+			'May'         : 'Mag',
+			'Jun'         : 'Giu',
+			'Jul'         : 'Lug',
+			'Aug'         : 'Ago',
+			'Sep'         : 'Set',
+			'Oct'         : 'Ott',
+			'Nov'         : 'Nov',
+			'Dec'         : 'Dic',
+			'January'     : 'Gennaio',
+			'February'    : 'Febbraio',
+			'March'       : 'Marzo',
+			'April'       : 'Aprile',
+			'May'         : 'Maggio',
+			'June'        : 'Giugno',
+			'July'        : 'Luglio',
+			'August'      : 'Agosto',
+			'September'   : 'Settembre',
+			'October'     : 'Ottobre',
+			'November'    : 'Novembre',
+			'December'    : 'Dicembre',
+			'Sunday'      : 'Domenica', 
+			'Monday'      : 'Lunedì', 
+			'Tuesday'     : 'Martedì', 
+			'Wednesday'   : 'Mercoledì', 
+			'Thursday'    : 'Giovedì', 
+			'Friday'      : 'Venerdì', 
+			'Saturday'    : 'Sabato',
+			'Sun'         : 'Dom', 
+			'Mon'         : 'Lun', 
+			'Tue'         : 'Mar', 
+			'Wed'         : 'Mer', 
+			'Thu'         : 'Gio', 
+			'Fri'         : 'Ven', 
+			'Sat'         : 'Sab',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'per nome (cartelle in testa)', 
+			'sortkindDirsFirst' : 'per tipo (cartelle in testa)', 
+			'sortsizeDirsFirst' : 'per dimensione (cartelle in testa)', 
+			'sortdateDirsFirst' : 'per data (cartelle in testa)', 
+			'sortname'          : 'per nome', 
+			'sortkind'          : 'per tipo', 
+			'sortsize'          : 'per dimensione',
+			'sortdate'          : 'per data',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Conferma richiesta',
+			'confirmRm'       : 'Sei sicuro di voler rimuovere i file?<br />L\'operazione non è reversibile!',
+			'confirmRepl'     : 'Sostituire i file ?',
+			'apllyAll'        : 'Applica a tutti',
+			'name'            : 'Nome',
+			'size'            : 'Dimensione',
+			'perms'           : 'Permessi',
+			'modify'          : 'Modificato il',
+			'kind'            : 'Tipo',
+			'read'            : 'lettura',
+			'write'           : 'scrittura',
+			'noaccess'        : 'nessun accesso',
+			'and'             : 'e',
+			'unknown'         : 'sconosciuto',
+			'selectall'       : 'Seleziona tutti i file',
+			'selectfiles'     : 'Seleziona file',
+			'selectffile'     : 'Seleziona il primo file',
+			'selectlfile'     : 'Seleziona l\'ultimo file',
+			'viewlist'        : 'Visualizza Elenco',
+			'viewicons'       : 'Visualizza Icone',
+			'places'          : 'Places',
+			'calc'            : 'Calcola', 
+			'path'            : 'Percorso',
+			'aliasfor'        : 'Alias per',
+			'locked'          : 'Bloccato',
+			'dim'             : 'Dimensioni',
+			'files'           : 'File',
+			'folders'         : 'Cartelle',
+			'items'           : 'Oggetti',
+			'yes'             : 'si',
+			'no'              : 'no',
+			'link'            : 'Collegamento',
+			'searcresult'     : 'Risultati ricerca',  
+			'selected'        : 'oggetti selezionati',
+			'about'           : 'About',
+			'shortcuts'       : 'Scorciatoie',
+			'help'            : 'Help',
+			'webfm'           : 'Web file manager',
+			'ver'             : 'Versione',
+			'protocol'        : 'versione protocollo',
+			'homepage'        : 'Home del progetto',
+			'docs'            : 'Documentazione',
+			'github'          : 'Seguici su Github',
+			'twitter'         : 'Seguici su Twitter',
+			'facebook'        : 'Seguici su Facebook',
+			'team'            : 'Team',
+			'chiefdev'        : 'sviluppatore capo',
+			'developer'       : 'sviluppatore',
+			'contributor'     : 'collaboratore',
+			'maintainer'      : 'maintainer',
+			'translator'      : 'traduttore',
+			'icons'           : 'Icone',
+			'dontforget'      : 'e non dimenticate di portare l\'asciugamano',
+			'shortcutsof'     : 'Scorciatoie disabilitate',
+			'dropFiles'       : 'Trascina i file qui',
+			'or'              : 'o',
+			'selectForUpload' : 'Seleziona file da caricare',
+			'moveFiles'       : 'Sposta file',
+			'copyFiles'       : 'Copia file',
+			'rmFromPlaces'    : 'Rimuovi da places',
+			'untitled folder' : 'cartella senza titolo',
+			'untitled file.txt' : 'file senza titolo.txt',
+			'aspectRatio'     : 'Proporzioni',
+			'scale'           : 'Scala',
+			'width'           : 'Larghezza',
+			'height'          : 'Altezza',
+			'mode'            : 'Modalità',
+			'resize'          : 'Ridimensione',
+			'crop'            : 'Ritaglia',
+			'rotate'          : 'Ruota',
+			'rotate-cw'       : 'Ruota di 90° in senso orario',
+			'rotate-ccw'      : 'Ruota di 90° in senso antiorario',
+			'degree'          : 'Gradi',
+
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Sconosciuto',
+			'kindFolder'      : 'Cartella',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : 'Alias guasto',
+			// applications
+			'kindApp'         : 'Applicazione',
+			'kindPostscript'  : 'Documento Postscript',
+			'kindMsOffice'    : 'Documento Microsoft Office',
+			'kindMsWord'      : 'Documento Microsoft Word',
+			'kindMsExcel'     : 'Documento Microsoft Excel',
+			'kindMsPP'        : 'Presentazione Microsoft Powerpoint',
+			'kindOO'          : 'Documento Open Office',
+			'kindAppFlash'    : 'Applicazione Flash',
+			'kindPDF'         : 'Documento PDF',
+			'kindTorrent'     : 'File Bittorrent',
+			'kind7z'          : 'Archivio 7z',
+			'kindTAR'         : 'Archivio TAR',
+			'kindGZIP'        : 'Archivio GZIP',
+			'kindBZIP'        : 'Archivio BZIP',
+			'kindZIP'         : 'Archivio ZIP',
+			'kindRAR'         : 'Archivio RAR',
+			'kindJAR'         : 'File Java JAR',
+			'kindTTF'         : 'Font True Type',
+			'kindOTF'         : 'Font Open Type',
+			'kindRPM'         : 'Pacchetto RPM',
+			// texts
+			'kindText'        : 'Documento di testo',
+			'kindTextPlain'   : 'Testo Semplice',
+			'kindPHP'         : 'File PHP',
+			'kindCSS'         : 'File CSS (Cascading Style Sheet)',
+			'kindHTML'        : 'Documento HTML',
+			'kindJS'          : 'File Javascript',
+			'kindRTF'         : 'File RTF (Rich Text Format)',
+			'kindC'           : 'File C',
+			'kindCHeader'     : 'File C (header)',
+			'kindCPP'         : 'File C++',
+			'kindCPPHeader'   : 'File C++ (header)',
+			'kindShell'       : 'Script Unix shell',
+			'kindPython'      : 'File Python',
+			'kindJava'        : 'File Java',
+			'kindRuby'        : 'File Ruby',
+			'kindPerl'        : 'File Perl',
+			'kindSQL'         : 'File SQL',
+			'kindXML'         : 'File XML',
+			'kindAWK'         : 'File AWK',
+			'kindCSV'         : 'File CSV (Comma separated values)',
+			'kindDOCBOOK'     : 'File Docbook XML',
+			// images
+			'kindImage'       : 'Immagine',
+			'kindBMP'         : 'Immagine BMP',
+			'kindJPEG'        : 'Immagine JPEG',
+			'kindGIF'         : 'Immagine GIF',
+			'kindPNG'         : 'Immagine PNG',
+			'kindTIFF'        : 'Immagine TIFF',
+			'kindTGA'         : 'Immagine TGA',
+			'kindPSD'         : 'Immagine Adobe Photoshop',
+			'kindXBITMAP'     : 'Immagine X bitmap',
+			'kindPXM'         : 'Immagine Pixelmator',
+			// media
+			'kindAudio'       : 'File Audio',
+			'kindAudioMPEG'   : 'Audio MPEG',
+			'kindAudioMPEG4'  : 'Audio MPEG-4',
+			'kindAudioMIDI'   : 'Audio MIDI',
+			'kindAudioOGG'    : 'Audio Ogg Vorbis',
+			'kindAudioWAV'    : 'Audio WAV',
+			'AudioPlaylist'   : 'Playlist MP3',
+			'kindVideo'       : 'File Video',
+			'kindVideoDV'     : 'Filmato DV',
+			'kindVideoMPEG'   : 'Filmato MPEG',
+			'kindVideoMPEG4'  : 'Filmato MPEG-4',
+			'kindVideoAVI'    : 'Filmato AVI',
+			'kindVideoMOV'    : 'Filmato Quick Time',
+			'kindVideoWM'     : 'Filmato Windows Media',
+			'kindVideoFlash'  : 'Filmato Flash',
+			'kindVideoMKV'    : 'Filmato Matroska',
+			'kindVideoOGG'    : 'Filmato Ogg'
+		}
+	}
+}

+ 58 - 32
main/inc/lib/elfinder/js/i18n/elfinder.jp.js

@@ -1,13 +1,16 @@
 /**
  * Japanese translation
  * @author Tomoaki Yoshida <info@yoshida-studio.jp>
- * @version 2012-02-25
+ * @author Naoki Sawada <hypweb@gmail.com>
+ * @version 2013-07-03
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.jp = {
-		translator : 'Tomoaki Yoshida &lt;info@yoshida-studio.jp&gt;',
+		translator : 'Tomoaki Yoshida &lt;info@yoshida-studio.jp&gt;, Naoki Sawada &lt;hypweb@gmail.com&gt;',
 		language   : 'Japanese',
 		direction  : 'ltr',
+		dateFormat : 'Y/m/d h:i A', // 2012/04/11 05:27 PM
+		fancyDateFormat : '$1 h:i A', // will produce smth like: 今日 12:25 PM
 		messages   : {
 			
 			/********************************** errors **********************************/
@@ -68,12 +71,27 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errArcType'           : 'サポート外のアーカイブ形式です',
 			'errNoArchive'         : 'アーカイブでないかサポートされていないアーカイブ形式です',
 			'errCmdNoSupport'      : 'サポートされていないコマンドです',
-			'errReplByChild'       : 'ルダ "$1" に含まれてるアイテムを置き換えることはできません',
-			'errArcSymlinks'       : 'シンボリックリンクを含むアーカイブはセキュリティ上、解凍できません',
+			'errReplByChild'       : 'フォルダ "$1" に含まれてるアイテムを置き換えることはできません',
+			'errArcSymlinks'       : 'シンボリックリンクまたは許容されないファイル名を含むアーカイブはセキュリティ上、解凍できません', // edited 25.06.2012
 			'errArcMaxSize'        : 'アーカイブが許容されたサイズを超えています',
 			'errResize'            : '"$1"をリサイズできません',
+			'errResizeDegree'      : 'イメージの回転角度が不正です',  // added 7.3.2013
+			'errResizeRotate'      : 'イメージの回転ができません',  // added 7.3.2013
+			'errResizeSize'        : '指定されたイメージサイズが不正です',  // added 7.3.2013
+			'errResizeNoChange'    : 'イメージサイズなどの変更がありません',  // added 7.3.2013
 			'errUsupportType'      : 'このファイルタイプはサポートされません',
 			'errNotUTF8Content'    : 'ファイル "$1" には UTF-8 以外の文字が含まれているので編集できません',  // added 9.11.2011
+			'errNetMount'          : '"$1"をマウントできません', // added 17.04.2012
+			'errNetMountNoDriver'  : 'サポートされていないプロトコルです',     // added 17.04.2012
+			'errNetMountFailed'    : 'マウントに失敗しました',         // added 17.04.2012
+			'errNetMountHostReq'   : 'ホスト名は必須です', // added 18.04.2012
+			'errSessionExpires'    : 'アクションがなかったため、セッションが期限切れになりました',
+			'errCreatingTempDir'   : '一時ディレクトリを作成できません:"$1"',
+			'errFtpDownloadFile'   : 'FTP からファイルをダウンロードできません:"$1"',
+			'errFtpUploadFile'     : 'FTP へファイルをアップロードできません:"$1"',
+			'errFtpMkdir'          : 'FTP にリモートディレクトリを作成できません:"$1"',
+			'errArchiveExec'       : 'ファイルのアーカイブ中にエラーが発生しました:"$1"',
+			'errExtractExec'       : 'ファイルの抽出中にエラーが発生しました:"$1"',
 			
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'アーカイブ作成',
@@ -103,6 +121,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdview'      : 'ビュー',
 			'cmdresize'    : 'リサイズと回転',
 			'cmdsort'      : 'ソート',
+			'cmdnetmount'  : 'ネットワークボリュームをマウント', // added 18.04.2012
 			
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : '閉じる',
@@ -112,27 +131,30 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'btnCancel' : 'キャンセル',
 			'btnNo'     : 'いいえ',
 			'btnYes'    : 'はい',
-			
+			'btnMount'  : 'マウント',  // added 18.04.2012
 			/******************************** notifications ********************************/
-			'ntfopen'     : 'フォルダーを開',
-			'ntffile'     : 'ファイルを開',
-			'ntfreload'   : 'フォルダーを再読込',
-			'ntfmkdir'    : 'ディレクトリーを作成',
-			'ntfmkfile'   : 'ファイルを作成',
-			'ntfrm'       : 'ファイルを削除',
-			'ntfcopy'     : 'ファイルをコピー',
-			'ntfmove'     : 'ファイルを移動',
-			'ntfprepare'  : 'ファイルコピーを準備',
-			'ntfrename'   : 'ファイル名を変更',
-			'ntfupload'   : 'ファイルをアップロード',
-			'ntfdownload' : 'ファイルをダウンロード',
-			'ntfsave'     : 'ファイルを保存',
-			'ntfarchive'  : 'アーカイブ作成',
-			'ntfextract'  : 'アーカイブを解凍',
-			'ntfsearch'   : 'ファイル検索',
+			'ntfopen'     : 'フォルダーを開いています',
+			'ntffile'     : 'ファイルを開いています',
+			'ntfreload'   : 'フォルダーを再読込しています',
+			'ntfmkdir'    : 'ディレクトリーを作成しています',
+			'ntfmkfile'   : 'ファイルを作成しています',
+			'ntfrm'       : 'ファイルを削除しています',
+			'ntfcopy'     : 'ファイルをコピーしています',
+			'ntfmove'     : 'ファイルを移動しています',
+			'ntfprepare'  : 'ファイルコピーを準備しています',
+			'ntfrename'   : 'ファイル名を変更しています',
+			'ntfupload'   : 'ファイルをアップロードしています',
+			'ntfdownload' : 'ファイルをダウンロードしています',
+			'ntfsave'     : 'ファイルを保存しています',
+			'ntfarchive'  : 'アーカイブ作成しています',
+			'ntfextract'  : 'アーカイブを解凍しています',
+			'ntfsearch'   : 'ファイル検索',
 			'ntfresize'   : 'リサイズしています',
-			'ntfsmth'     : '何かしています >_<',
-			'ntfloadimg'  : 'Loading image',
+			'ntfsmth'     : '処理をしています',
+      		'ntfloadimg'  : 'イメージを読み込んでいます',
+      		'ntfnetmount' : 'ネットワークボリュームをマウントしています', // added 18.04.2012
+			'ntfdim'      : '画像サイズを取得しています', // added 20.05.2013
+			'ntfreaddir'  : 'ホルダ情報を読み取っています', // added 01.07.2013
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : '不明',
@@ -152,19 +174,16 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Dec'         : '12月',
 
 			/******************************** sort variants ********************************/
-			'sortnameDirsFirst' : '名前順 (フォルダ優先)', 
-			'sortkindDirsFirst' : '種類順 (フォルダ優先)', 
-			'sortsizeDirsFirst' : 'サイズ順 (フォルダ優先)', 
-			'sortdateDirsFirst' : '日付順 (フォルダ優先)', 
 			'sortname'          : '名前順', 
 			'sortkind'          : '種類順', 
 			'sortsize'          : 'サイズ順',
 			'sortdate'          : '日付順',
+			'sortFoldersFirst'  : 'フォルダ優先', // added 21.06.2012
 
 			/********************************** messages **********************************/
-			'confirmReq'      : '確認必須です',
-			'confirmRm'       : '本当にファイルを削除しますか?<br/>この操作は取り消せません!',
-			'confirmRepl'     : '古いファイルを新しいファイルで上書きしますか?',
+			'confirmReq'      : '処理を実行しますか?',
+			'confirmRm'       : '本当にファイルを削除しますか?<br/>この操作は取り消せません',
+			'confirmRepl'     : '古いファイルを新しいファイルで上書きしますか',
 			'apllyAll'        : '全てに適用します',
 			'name'            : '名前',
 			'size'            : 'サイズ',
@@ -201,7 +220,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'ヘルプ',
 			'webfm'           : 'ウェブファイルマネージャー',
 			'ver'             : 'バージョン',
-			'protocol'        : 'プロトコルバージョン',
+			'protocolver'     : 'プロトコルバージョン',
 			'homepage'        : 'プロジェクトホーム',
 			'docs'            : 'ドキュメンテーション',
 			'github'          : 'Github でフォーク',
@@ -217,6 +236,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'dontforget'      : 'タオル忘れちゃだめよー。',
 			'shortcutsof'     : 'ショートカットは利用できません',
 			'dropFiles'       : 'ここにファイルをドロップ',
+			'dropFilesBrowser': 'ブラウザからファイルをドロップまたは貼り付け', // added 30.05.2012
 			'or'              : 'または',
 			'selectForUpload' : 'アップロードするファイルを選択',
 			'moveFiles'       : 'ファイルを移動',
@@ -232,7 +252,13 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'rotate-cw'       : '90度左回転',
 			'rotate-ccw'      : '90度右回転',
 			'degree'          : '度',
-			
+			'netMountDialogTitle' : 'ネットワークボリュームのマウント', // added 18.04.2012
+			'protocol'            : 'プロトコル', // added 18.04.2012
+			'host'                : 'ホスト名', // added 18.04.2012
+			'port'                : 'ポート', // added 18.04.2012
+			'user'                : 'ユーザー名', // added 18.04.2012
+			'pass'                : 'パスワード', // added 18.04.2012
+
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : '不明',
 			'kindFolder'      : 'フォルダー',

+ 340 - 0
main/inc/lib/elfinder/js/i18n/elfinder.ko.js

@@ -0,0 +1,340 @@
+/**
+ * Korean translation
+ * @author Hwang Ahreum 황아름 <luckmagic@naver.com>
+ * @version 2012-06-27
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.ko = {
+		translator : 'Hwang Ahreum; &lt;luckmagic@naver.com&gt;',
+		language   : 'Korea-한국어',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+
+			/********************************** errors **********************************/
+			'error'                : '에러',
+			'errUnknown'           : '알 수 없는 에러',
+			'errUnknownCmd'        : '알 수 없는 명령어',
+			'errJqui'              : 'jQuery UI 환경설정이 올바르지 않습니다. 선택,드래그앤드롭 컴포넌트가 포함되어야합니다',
+			'errNode'              : 'elFinder를 생성하기 위해서는 DOM Element를 요구합니다',
+			'errURL'               : 'elFinder 환경설정이 올바르지 않습니다! URL 옵션이 설정되지 않았습니다',
+			'errAccess'            : '액세스 할 수 없습니다',
+			'errConnect'           : 'Backend에 연결할 수 없습니다',
+			'errAbort'             : '연결 실패',
+			'errTimeout'           : '연결시간 초과',
+			'errNotFound'          : 'Backend를 찾을 수 없습니다',
+			'errResponse'          : 'Backend가 응답하지 않습니다',
+			'errConf'              : 'Backend 환경설정이 올바르지 않습니다',
+			'errJSON'              : 'PHP JSON 모듈이 설치되지 않았습니다',
+			'errNoVolumes'         : '읽기 가능한 볼률이 없습니다',
+			'errCmdParams'         : ' "$1" 명령어는 잘못된 인수입니다',
+			'errDataNotJSON'       : '데이터는 JSON이 아닙니다',
+			'errDataEmpty'         : '빈 데이터 입니다',
+			'errCmdReq'            : 'Backend는 필요한 명령어 이름을 요청합니다',
+			'errOpen'              : ' "$1" 열 수 없습니다',
+			'errNotFolder'         : '폴더가 아닙니다',
+			'errNotFile'           : '파일이 아닙니다',
+			'errRead'              : ' "$1" 읽을 수 없습니다',
+			'errWrite'             : ' "$1" 쓸 수 없습니다',
+			'errPerm'              : '권한이 없습니다',
+			'errLocked'            : ' "$1" 잠겨 있습니다, 이동,삭제가 불가능합니다',
+			'errExists'            : ' "$1" 존재합니다',
+			'errInvName'           : '이름에 올바르지 않은 문자가 포함되었습니다',
+			'errFolderNotFound'    : '폴더를 찾을 수 없습니다',
+			'errFileNotFound'      : '파일을 찾을 수 없습니다',
+			'errTrgFolderNotFound' : ' "$1" 폴더를 찾을 수 없습니다',
+			'errPopup'             : '브라우저에서 팝업을 차단하였습니다.팝업을 허용하려면 브라우저 옵션을 변경하세요',
+			'errMkdir'             : ' "$1" 폴더를 생성할 수 없습니다',
+			'errMkfile'            : ' "$1" 파일을 생성할 수 없습니다',
+			'errRename'            : ' "$1" 이름을 변경할 수 없습니다',
+			'errCopyFrom'          : '볼률 "$1" 로부터 파일을 복사할 수 없습니다',
+			'errCopyTo'            : '볼률 "$1" 에 파일을 복사할 수 없습니다',
+			'errUploadCommon'      : '업로드 에러',
+			'errUpload'            : ' "$1" 업로드할 수 없습니다',
+			'errUploadNoFiles'     : '업로드할 파일이 없습니다',
+			'errMaxSize'           : '데이터가 허용된 최대크기를 초과하였습니다',
+			'errFileMaxSize'       : '파일이 허용된 최대크기를 초과하였습니다',
+			'errUploadMime'        : '잘못된 파일형식입니다',
+			'errUploadTransfer'    : ' "$1" 전송 에러', 
+			'errSave'              : ' "$1" 저장할 수 없습니다',
+			'errCopy'              : ' "$1" 복사할 수 없습니다',
+			'errMove'              : ' "$1" 이동할 수 없습니다',
+			'errCopyInItself'      : ' "$1" 이곳에 복사 할 수 없습니다',
+			'errRm'                : ' "$1" 이름을 변경할 수 없습니다',
+			'errExtract'           : ' "$1" 에 압축을 풀 수 없습니다',
+			'errArchive'           : '압축파일을 생성할 수 없습니다',
+			'errArcType'           : '지원하지 않는 압축파일 형식입니다',
+			'errNoArchive'         : '압축파일이 아니거나 지원하지 않는 압축파일 형식입니다',
+			'errCmdNoSupport'      : '이 명령어는 Backend를 지원하지 않습니다',
+			'errReplByChild'       : ' "$1" 폴더에 덮어쓸수 없습니다',
+			'errArcSymlinks'       : '보안을 위해 시스템 호출을 포함한 압축파일인지를 분석합니다',
+			'errArcMaxSize'        : '압축파일이 허용된 최대크기를 초과하였습니다',
+			'errResize'            : ' "$1" 크기 변경을 할 수 없습니다',
+			'errUsupportType'      : '지원하지 않는 파일 형식',
+
+			/******************************* commands names ********************************/
+			'cmdarchive'   : '압축파일생성',
+			'cmdback'      : '뒤로',
+			'cmdcopy'      : '복사',
+			'cmdcut'       : '자르기',
+			'cmddownload'  : '다운로드',
+			'cmdduplicate' : '사본',
+			'cmdedit'      : '편집',
+			'cmdextract'   : '압축풀기',
+			'cmdforward'   : '앞으로',
+			'cmdgetfile'   : '선택',
+			'cmdhelp'      : '이 소프트웨어는',
+			'cmdhome'      : '홈',
+			'cmdinfo'      : '파일정보',
+			'cmdmkdir'     : '새 폴더',
+			'cmdmkfile'    : '새 텍스트파일',
+			'cmdopen'      : '열기',
+			'cmdpaste'     : '붙여넣기',
+			'cmdquicklook' : '미리보기',
+			'cmdreload'    : '새로고침',
+			'cmdrename'    : '이름바꾸기',
+			'cmdrm'        : '삭제',
+			'cmdsearch'    : '파일찾기',
+			'cmdup'        : '상위폴더',
+			'cmdupload'    : '업로드',
+			'cmdview'      : '보기',
+			'cmdresize'    : '이미지 사이즈변경',
+			'cmdsort'      : '정렬',
+
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : '닫기',
+			'btnSave'   : '저장',
+			'btnRm'     : '삭제',
+			'btnApply'  : '적용',
+			'btnCancel' : '취소',
+			'btnNo'     : '아니오',
+			'btnYes'    : '예',
+
+			/******************************** notifications ********************************/
+			'ntfopen'     : '폴더 열기',
+			'ntffile'     : '파일 열기',
+			'ntfreload'   : '새로고침',
+			'ntfmkdir'    : '폴더 생성',
+			'ntfmkfile'   : '파일 생성',
+			'ntfrm'       : '삭제',
+			'ntfcopy'     : '복사',
+			'ntfmove'     : '이동',
+			'ntfprepare'  : '복사 준비',
+			'ntfrename'   : '이름바꾸기',
+			'ntfupload'   : '업로드',
+			'ntfdownload' : '다운로드',
+			'ntfsave'     : '저장하기',
+			'ntfarchive'  : '압축파일만들기',
+			'ntfextract'  : '압축풀기',
+			'ntfsearch'   : '검색',
+			'ntfsmth'     : '작업중 >_<',
+			'ntfloadimg'  : '이미지 불러오기',
+
+			/************************************ dates **********************************/
+			'dateUnknown' : '알수없음',
+			'Today'       : '오늘',
+			'Yesterday'   : '내일',
+			'Jan'         : '1월',
+			'Feb'         : '2월',
+			'Mar'         : '3월',
+			'Apr'         : '4월',
+			'May'         : '5월',
+			'Jun'         : '6월',
+			'Jul'         : '7월',
+			'Aug'         : '8월',
+			'Sep'         : '9월',
+			'Oct'         : '10월',
+			'Nov'         : '11월',
+			'Dec'         : '12월',
+			'January'     : '1월',
+			'February'    : '2월',
+			'March'       : '3월',
+			'April'       : '4월',
+			'May'         : '5월',
+			'June'        : '6월',
+			'July'        : '7월',
+			'August'      : '8월',
+			'September'   : '9월',
+			'October'     : '10월',
+			'November'    : '11월',
+			'December'    : '12월',
+			'Sunday'      : '일요일', 
+			'Monday'      : '월요일', 
+			'Tuesday'     : '화요일', 
+			'Wednesday'   : '수요일', 
+			'Thursday'    : '목요일', 
+			'Friday'      : '금요일', 
+			'Saturday'    : '토요일',
+			'Sun'         : '일', 
+			'Mon'         : '월', 
+			'Tue'         : '화', 
+			'Wed'         : '수', 
+			'Thu'         : '목', 
+			'Fri'         : '금', 
+			'Sat'         : '토',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : '이름 (폴더 먼저)', 
+			'sortkindDirsFirst' : '종류 (폴더 먼저)', 
+			'sortsizeDirsFirst' : '크기 (폴더 먼저)', 
+			'sortdateDirsFirst' : '날짜 (폴더 먼저)', 
+			'sortname'          : '이름', 
+			'sortkind'          : '종류', 
+			'sortsize'          : '크기',
+			'sortdate'          : '날짜',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : '확인',
+			'confirmRm'       : '이 파일을 정말 삭제 하겠습니까?<br/>실행 후 되돌릴 수 없습니다!',
+			'confirmRepl'     : '파일을 덮어쓰겠습니까?',
+			'apllyAll'        : '모두 적용',
+			'name'            : '이름',
+			'size'            : '크기',
+			'perms'           : '권한',
+			'modify'          : '수정된 시간',
+			'kind'            : '종류',
+			'read'            : '읽기',
+			'write'           : '쓰기',
+			'noaccess'        : '액세스 불가',
+			'and'             : '와',
+			'unknown'         : '알 수 없음',
+			'selectall'       : '모든 파일 선택',
+			'selectfiles'     : '파일 선택',
+			'selectffile'     : '첫번째 파일 선택',
+			'selectlfile'     : '마지막 파일 선택',
+			'viewlist'        : '리스트 보기',
+			'viewicons'       : '아이콘 보기',
+			'places'          : '위치',
+			'calc'            : '계산', 
+			'path'            : '경로',
+			'aliasfor'        : '별명',
+			'locked'          : '잠금',
+			'dim'             : '크기',
+			'files'           : '파일',
+			'folders'         : '폴더',
+			'items'           : '아이템',
+			'yes'             : '예',
+			'no'              : '아니오',
+			'link'            : '링크',
+			'searcresult'     : '검색 결과',  
+			'selected'        : '아이템 선택',
+			'about'           : 'About',
+			'shortcuts'       : '단축아이콘',
+			'help'            : '도움말',
+			'webfm'           : '웹 파일매니저',
+			'ver'             : '버전',
+			'protocol'        : '프로토콜 버전',
+			'homepage'        : '홈페이지',
+			'docs'            : '문서',
+			'github'          : 'Fork us on Github',
+			'twitter'         : '트위터따라가기',
+			'facebook'        : '페이스북 가입하기',
+			'team'            : '팀',
+			'chiefdev'        : '개발팀장',
+			'developer'       : '개발자',
+			'contributor'     : '공헌자',
+			'maintainer'      : '관리자',
+			'translator'      : '번역',
+			'icons'           : '아이콘',
+			'dontforget'      : 'and don\'t forget to take your towel',
+			'shortcutsof'     : '단축아이콘 사용불가',
+			'dropFiles'       : '여기로 이동하기',
+			'or'              : '또는',
+			'selectForUpload' : '업로드 파일 선택',
+			'moveFiles'       : '파일 이동',
+			'copyFiles'       : '파일 복사',
+			'rmFromPlaces'    : '현재 폴더에서 삭제하기',
+			'untitled folder' : '새 폴더',
+			'untitled file.txt' : '새 텍스트.txt',
+			'aspectRatio'     : '화면비율',
+			'scale'           : '크기',
+			'width'           : '가로',
+			'height'          : '세로',
+			'mode'            : '모드',
+			'resize'          : '사이즈 변경',
+			'crop'            : '자르기',
+			'rotate'          : '회전',
+			'rotate-cw'       : '반시계방향 90도 회전',
+			'rotate-ccw'      : '시계방향 90도 회전',
+			'degree'          : '각도',
+
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : '알수없음',
+			'kindFolder'      : '폴더',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : '손상된 Alias',
+			// applications
+			'kindApp'         : '응용프로그램',
+			'kindPostscript'  : 'Postscript 문서',
+			'kindMsOffice'    : 'Microsoft Office 문서',
+			'kindMsWord'      : 'Microsoft Word 문서',
+			'kindMsExcel'     : 'Microsoft Excel 문서',
+			'kindMsPP'        : 'Microsoft Powerpoint',
+			'kindOO'          : 'Office 문서 열기',
+			'kindAppFlash'    : '플래쉬',
+			'kindPDF'         : 'PDF(PDF)',
+			'kindTorrent'     : 'Bittorrent 파일',
+			'kind7z'          : '7z 압축파일',
+			'kindTAR'         : 'TAR 압축파일',
+			'kindGZIP'        : 'GZIP 압축파일',
+			'kindBZIP'        : 'BZIP 압축파일',
+			'kindZIP'         : 'ZIP 압축파일',
+			'kindRAR'         : 'RAR 압축파일',
+			'kindJAR'         : 'Java JAR 파일',
+			'kindTTF'         : '트루타입 글꼴',
+			'kindOTF'         : '오픈타입 글꼴',
+			'kindRPM'         : 'RPM 패키지',
+			// texts
+			'kindText'        : 'Text 문서',
+			'kindTextPlain'   : '보통 텍스트',
+			'kindPHP'         : 'PHP 소스',
+			'kindCSS'         : 'CSS 문서',
+			'kindHTML'        : 'HTML 문서',
+			'kindJS'          : '자바스크립트 소스',
+			'kindRTF'         : 'RTF 형식',
+			'kindC'           : 'C 소스',
+			'kindCHeader'     : 'C 헤더소스',
+			'kindCPP'         : 'C++ 소스',
+			'kindCPPHeader'   : 'C++ 헤더소스',
+			'kindShell'       : 'Unix shell 스크립트',
+			'kindPython'      : 'Python 소스',
+			'kindJava'        : 'Java 소스',
+			'kindRuby'        : 'Ruby 소스',
+			'kindPerl'        : 'Perl 스크립트',
+			'kindSQL'         : 'SQL 소스',
+			'kindXML'         : 'XML 문서',
+			'kindAWK'         : 'AWK 소스',
+			'kindCSV'         : 'CSV 형식',
+			'kindDOCBOOK'     : 'XML 닥북 문서',
+			// images
+			'kindImage'       : '이미지',
+			'kindBMP'         : 'BMP 이미지',
+			'kindJPEG'        : 'JPEG 이미지',
+			'kindGIF'         : 'GIF 이미지',
+			'kindPNG'         : 'PNG 이미지',
+			'kindTIFF'        : 'TIFF 이미지',
+			'kindTGA'         : 'TGA 이미지',
+			'kindPSD'         : 'Adobe Photoshop 이미지',
+			'kindXBITMAP'     : 'X bitmap 이미지',
+			'kindPXM'         : 'Pixelmator 이미지',
+			// media
+			'kindAudio'       : '오디오 미디어',
+			'kindAudioMPEG'   : 'MPEG 오디오',
+			'kindAudioMPEG4'  : 'MPEG-4 오디오',
+			'kindAudioMIDI'   : 'MIDI 오디오',
+			'kindAudioOGG'    : 'Ogg Vorbis 오디오',
+			'kindAudioWAV'    : 'WAV 오디오',
+			'AudioPlaylist'   : 'MP3 플레이 리스트',
+			'kindVideo'       : 'Video 미디어',
+			'kindVideoDV'     : 'DV 동영상',
+			'kindVideoMPEG'   : 'MPEG 동영상',
+			'kindVideoMPEG4'  : 'MPEG-4 동영상',
+			'kindVideoAVI'    : 'AVI 동영상',
+			'kindVideoMOV'    : '퀵타임 동영상',
+			'kindVideoWM'     : '윈도우 미디어 플레이어 동영상',
+			'kindVideoFlash'  : '플래쉬 동영상',
+			'kindVideoMKV'    : 'Matroska 동영상',
+			'kindVideoOGG'    : 'Ogg 동영상'
+		}
+	}
+}

+ 33 - 14
main/inc/lib/elfinder/js/i18n/elfinder.nl.js

@@ -68,10 +68,23 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errNoArchive'         : 'Bestand is geen archief of geen ondersteund archief type.',
 			'errCmdNoSupport'      : 'Backend ondersteund dit commando niet.',
 			'errReplByChild'       : 'De map "$1" kan niet vervangen worden door een item uit die map.',
-			'errArcSymlinks'       : 'Om veiligheidsredenen kan een bestand met symlinks niet worden uitgepakt .',
+			'errArcSymlinks'       : 'Om veiligheidsredenen kan een bestand met symlinks of bestanden met niet toegestane namen niet worden uitgepakt .',
 			'errArcMaxSize'        : 'Archief overschrijdt de maximale bestandsgrootte.',
 			'errResize'            : 'Kan het formaat van "$1" niet wijzigen.',
-    			'errUsupportType'      : 'Bestandstype wordt niet ondersteund.',
+			'errUsupportType'      : 'Bestandstype wordt niet ondersteund.',
+			'errNotUTF8Content'    : 'Bestand "$1" is niet in UTF-8 and kan niet aangepast worden.', 
+			'errNetMount'          : 'Kan "$1" niet mounten.',   
+			'errNetMountNoDriver'  : 'Niet ondersteund protocol.',   
+			'errNetMountFailed'    : 'Mount mislukt.',    
+			'errNetMountHostReq'   : 'Host is verplicht.',
+			'errSessionExpires'    : 'Uw sessie is verlopen vanwege inactiviteit.',
+			'errCreatingTempDir'   : 'Kan de tijdelijke map niet aanmaken: "$1" ',
+			'errFtpDownloadFile'   : 'Kan het bestand niet downloaden vanaf FTP: "$1"',
+			'errFtpUploadFile'     : 'Kan het bestand niet uploaden naar FTP: "$1"',
+			'errFtpMkdir'          : 'Kan het externe map niet aanmaken op de FTP-server: "$1"',
+			'errArchiveExec'       : 'Er is een fout opgetreden bij het archivering van de bestanden: "$1" ',
+			'errExtractExec'       : 'Er is een fout opgetreden bij het uitpakken van de bestanden: "$1" ',
+			'errUploadFile'        : 'Kan "$1" niet uploaden',
 			
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Maak archief',
@@ -101,6 +114,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdview'      : 'Bekijk',
 			'cmdresize'    : 'Formaat wijzigen',
 			'cmdsort'      : 'Sorteren',
+			'cmdnetmount'  : 'Mount netwerk volume',
 			
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : 'Sluit',
@@ -110,26 +124,28 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'btnCancel' : 'Annuleren',
 			'btnNo'     : 'Nee',
 			'btnYes'    : 'Ja',
+			'btnMount'  : 'Mount',
 			
 			/******************************** notifications ********************************/
 			'ntfopen'     : 'Bezig met openen van map',
 			'ntffile'     : 'Bezig met openen bestand',
-			'ntfreload'   : 'Bezig met inhoud map vernieuwen',
+			'ntfreload'   : 'Herladen map inhoud',
 			'ntfmkdir'    : 'Bezig met map maken',
 			'ntfmkfile'   : 'Bezig met Bestanden maken',
-			'ntfrm'       : 'Bezig met verwijderen bestanden',
+			'ntfrm'       : 'Verwijderen bestanden',
 			'ntfcopy'     : 'Kopieer bestanden',
 			'ntfmove'     : 'Verplaats bestanden',
-			'ntfprepare'  : 'Voorbereiden om bestanden te kopiëren',
+			'ntfprepare'  : 'Voorbereiden kopiëren',
 			'ntfrename'   : 'Hernoem bestanden',
-			'ntfupload'   : 'Bezig met uploaden bestanden',
-			'ntfdownload' : 'Bezig met downloaden bestanden',
+			'ntfupload'   : 'Bestanden uploaden actief',
+			'ntfdownload' : 'Bestanden downloaden actief',
 			'ntfsave'     : 'Bestanden opslaan',
 			'ntfarchive'  : 'Archief aan het maken',
-			'ntfextract'  : 'Bestanden uit het archief aan het uitpakken',
+			'ntfextract'  : 'Bestanden uitpakken actief',
 			'ntfsearch'   : 'Zoeken naar bestanden',
-			'ntfsmth'     : 'Iets aan het doen >_<',
+			'ntfsmth'     : 'Iets aan het doen',
 			'ntfloadimg'  : 'Laden van plaatje',
+			'ntfnetmount' : 'Verhogen netwerk volume',
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : 'onbekend',
@@ -175,14 +191,11 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Sat'         : 'Za',
 			
 			/******************************** sort variants ********************************/
-			'sortnameDirsFirst' : 'op naam (mappen eerst)', 
-			'sortkindDirsFirst' : 'op type (mappen eerst)', 
-			'sortsizeDirsFirst' : 'op grootte (mappen eerst)', 
-			'sortdateDirsFirst' : 'op datum (mappen eerst)', 
 			'sortname'          : 'op naam', 
 			'sortkind'          : 'op type', 
 			'sortsize'          : 'op grootte',
 			'sortdate'          : 'op datum',
+			'sortFoldersFirst'  : 'Mappen eerst',
 
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Bevestiging nodig',
@@ -224,7 +237,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Help',
 			'webfm'           : 'Web bestandsmanager',
 			'ver'             : 'Versie',
-			'protocol'        : 'protocol versie',
+			'protocolver'     : 'protocol versie',
 			'homepage'        : 'Project home',
 			'docs'            : 'Documentatie',
 			'github'          : 'Fork ons op Github',
@@ -258,6 +271,12 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'rotate-cw'	  : 'Draai 90 graden rechtsom',
 			'rotate-ccw'	  : 'Draai 90 graden linksom',
 			'degree'	  : '°',
+			'netMountDialogTitle' : 'Mount network volume',
+			'protocol'        : 'Protocol', 
+			'host'            : 'Host', 
+			'port'            : 'Poort',
+			'user'            : 'Gebruikersnaams', 
+			'pass'            : 'Wachtwoord', 
 			
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Onbekend',

+ 1 - 1
main/inc/lib/elfinder/js/i18n/elfinder.no.js

@@ -177,7 +177,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Hjelp',
 			'webfm'           : 'Web-filbehandler',
 			'ver'             : 'Versjon',
-			'protocol'        : 'protokol versjon',
+			'protocolver'     : 'protokol versjon',
 			'homepage'        : 'Project home',
 			'docs'            : 'dokumentasjon',
 			'github'          : 'Fork us on Github',

+ 37 - 3
main/inc/lib/elfinder/js/i18n/elfinder.pl.js

@@ -1,13 +1,16 @@
 /**
  * Polish translation
  * @author Marcin Mikołajczyk <marcin@pjwstk.edu.pl>
- * @version 2012-01-28
+ * @author Wojciech Jabłoński <www.jablonski@gmail.com>
+ * @version 2013-01-28
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.pl = {
-		translator : 'Marcin Mikołajczyk &lt;marcin@pjwstk.edu.pl&gt;',
+		translator : 'Marcin Mikołajczyk &lt;marcin@pjwstk.edu.pl&gt;, Wojciech Jabłoński &lt;www.jablonski@gmail.com&gt;',
 		language   : 'Polski',
 		direction  : 'ltr',
+		dateFormat : 'd M Y H:i',
+		fancyDateFormat : '$1 H:i',
 		messages   : {
 
 			/********************************** errors **********************************/
@@ -145,6 +148,32 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Oct'         : 'paź',
 			'Nov'         : 'lis',
 			'Dec'         : 'gru',
+			'January'     : 'Styczeń',
+			'February'    : 'Luty',
+			'March'       : 'Marzec',
+			'April'       : 'Kwiecień',
+			'May'         : 'Maj',
+			'June'        : 'Czerwiec',
+			'July'        : 'Lipiec',
+			'August'      : 'Sierpień',
+			'September'   : 'Wrzesień',
+			'October'     : 'Październik',
+			'November'    : 'Listopad',
+			'December'    : 'Grudzień',
+			'Sunday'      : 'niedziela',
+			'Monday'      : 'poniedziałek',
+			'Tuesday'     : 'wtorek',
+			'Wednesday'   : 'środa',
+			'Thursday'    : 'czwartek',
+			'Friday'      : 'piątek',
+			'Saturday'    : 'sobota',
+			'Sun'         : 'nie',
+			'Mon'         : 'pon',
+			'Tue'         : 'wto',
+			'Wed'         : 'śro',
+			'Thu'         : 'czw',
+			'Fri'         : 'pią',
+			'Sat'         : 'sob',
 
 			/******************************** sort variants ********************************/
 			'sortnameDirsFirst' : 'po nazwie (foldery pierwsze)', 
@@ -226,6 +255,11 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'mode'            : 'Tryb',
 			'resize'          : 'Zmień rozmiar',
 			'crop'            : 'Przytnij',
+			'rotate'          : 'Obróć',
+			'rotate-cw'       : 'Obróć 90° w lewo',
+			'rotate-ccw'      : 'Obróć 90° w prawo',
+			'degree'          : '°',
+
 
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Nieznany',
@@ -306,4 +340,4 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'kindVideoOGG'    : 'Plik wideo Ogg'
 		}
 	}
-}
+}

+ 58 - 7
main/inc/lib/elfinder/js/i18n/elfinder.pt_BR.js

@@ -1,13 +1,15 @@
 /**
  * Brazilian Portuguese translation
  * @author Leandro Carvalho <contato@leandrowebdev.net>
- * @version 2011-07-09
+ * @version 2013-01-22
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.pt_BR = {
 		translator : 'Leandro Carvalho &lt;contato@leandrowebdev.net&gt;',
 		language   : 'Português',
 		direction  : 'ltr',
+		dateFormat : 'd M Y H:i', // Mar 13, 2012 05:27 PM
+		fancyDateFormat : '$1 H:i', // will produce smth like: Today 12:25 PM
 		messages   : {
 
 			/********************************** errors **********************************/
@@ -65,6 +67,25 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errArcType'           : 'Tipo de arquivo não suportado.',
 			'errNoArchive'         : 'Arquivo inválido ou é um tipo sem suporte.',
 			'errCmdNoSupport'      : 'Backend não suporta este comando.',
+			'errNotUTF8Content'    : 'Arquivo "$1" não está em UTF-8 e não pode ser editado.',  // added 9.11.2011
+			'errNetMount'          : 'Habilitar montagem "$1".', // added 17.04.2012
+			'errNetMountNoDriver'  : 'Protocolo não suportado.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Monagem falhou.',         // added 17.04.2012
+			'errNetMountHostReq'   : 'Servidor requerido.', // added 18.04.2012
+			'errSessionExpires'    : 'Sua sessão expirou por inatividade',
+			'errCreatingTempDir'   : 'Não foi possível criar um diretório temporário: "$1"',
+			'errFtpDownloadFile'   : 'Não foi possível fazer o download do arquivo do FTP: "$1"',
+			'errFtpUploadFile'     : 'Não foi possível fazer o upload do arquivo para o FTP: "$1"',
+			'errFtpMkdir'          : 'Não foi possível criar um diretório remoto no FTP: "$1"',
+			'errArchiveExec'       : 'Erro no arquivamento: "$1"',
+			'errExtractExec'       : 'Erro na extração dos arquivos: "$1"',
+			'cmdsort'              : 'Ordenar',
+			'sortkind'             : 'por tipo',
+			'sortname'             : 'por nome',
+			'sortsize'             : 'por tamanho',
+			'sortdate'             : 'por data',
+			'sortFoldersFirst'     : 'Pastas primeiro',
+			'errUploadFile'        : 'Não foi possível fazer o upload "$1".',
 
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Criar arquivo',
@@ -92,6 +113,9 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdup'        : 'Ir para o diretório pai',
 			'cmdupload'    : 'Fazer upload de arquivo',
 			'cmdview'      : 'Vizualizar',
+			'cmdresize'    : 'Redimencionar & Rodar',
+			'cmdsort'      : 'Ordenar',
+			'cmdnetmount'  : 'Montar unidade de rede', // added 18.04.2012
 
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : 'Fechar',
@@ -100,6 +124,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'btnCancel' : 'Cancelar',
 			'btnNo'     : 'Não',
 			'btnYes'    : 'Sim',
+			'btnMount'  : 'Montar',  // added 18.04.2012
 
 			/******************************** notifications ********************************/
 			'ntfopen'     : 'Abrir Pasta',
@@ -110,15 +135,17 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfrm'       : 'Deletar arquivos',
 			'ntfcopy'     : 'Copiar arquivos',
 			'ntfmove'     : 'Mover arquivos',
-			'ntfprepare'  : 'Preparar para copiar os arquivos',
+			'ntfprepare'  : 'Preparando para copiar',
 			'ntfrename'   : 'Renomear arquivos',
-			'ntfupload'   : 'Fazendo o upload dos arquivos',
+			'ntfupload'   : 'Subindo arquivos',
 			'ntfdownload' : 'Baixando os arquivos',
 			'ntfsave'     : 'Slvando os arquivos',
 			'ntfarchive'  : 'Criando os arquivos',
-			'ntfextract'  : 'Extraindo arquivos dos ficheiros',
+			'ntfextract'  : 'Extraindo arquivos',
 			'ntfsearch'   : 'Procurando arquivos',
-			'ntfsmth'     : 'Fazendo alguma coisa >_<',
+			'ntfsmth'     : 'Fazendo alguma coisa',
+			'ntfnetmount' : 'Montando unidade de rede', // added 18.04.2012
+
 
 			/************************************ dates **********************************/
 			'dateUnknown' : 'Desconhecido',
@@ -137,6 +164,13 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Nov'         : 'Nov',
 			'Dec'         : 'Dez',
 
+			/******************************** sort variants ********************************/
+			'sortname'          : 'por nome', 
+			'sortkind'          : 'por tipo', 
+			'sortsize'          : 'por tam.',
+			'sortdate'          : 'por data',
+			'sortFoldersFirst'  : 'Pastas primeiro',
+			
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Confirmação requerida',
 			'confirmRm'       : 'Você tem certeza que quer remover os arquivos?<br />Isto não pode ser desfeito!',
@@ -144,7 +178,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'apllyAll'        : 'Aplicar a todos',
 			'name'            : 'Nome',
 			'size'            : 'Tamanho',
-			'perms'           : 'Permições',
+			'perms'           : 'Permissões',
 			'modify'          : 'Modificado',
 			'kind'            : 'Tipo',
 			'read'            : 'Ler',
@@ -177,7 +211,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Ajuda',
 			'webfm'           : 'Gerenciador de arquivos web',
 			'ver'             : 'Versão',
-			'protocol'        : 'Versão do protocolo',
+			'protocolver'     : 'Versão do protocolo',
 			'homepage'        : 'Home do projeto',
 			'docs'            : 'Documentação',
 			'github'          : 'Fork us on Github',
@@ -197,6 +231,23 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'selectForUpload' : 'Selecione arquivos para upload',
 			'moveFiles'       : 'Mover arquivos',
 			'copyFiles'       : 'Copiar arquivos',
+			'rmFromPlaces'    : 'Remover de Lugares',
+			'aspectRatio'     : 'Manter aspecto',
+			'scale'           : 'Tamanho',
+			'width'           : 'Largura',
+			'height'          : 'Altura',
+			'resize'          : 'Redimencionar',
+			'crop'            : 'Cortar',
+			'rotate'          : 'Rotacionar',
+			'rotate-cw'       : 'Girar 90 graus CW',
+			'rotate-ccw'      : 'Girar 90 graus CCW',
+			'degree'          : '°',
+			'netMountDialogTitle' : 'Montar Unidade de rede', // added 18.04.2012
+			'protocol'            : 'Protocolo', // added 18.04.2012
+			'host'                : 'Servidor', // added 18.04.2012
+			'port'                : 'Porta', // added 18.04.2012
+			'user'                : 'Usuário', // added 18.04.2012
+			'pass'                : 'Senha', // added 18.04.2012
 
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Desconhecio',

+ 30 - 12
main/inc/lib/elfinder/js/i18n/elfinder.ru.js

@@ -68,11 +68,26 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errNoArchive'         : 'Файл не является архивом допустимого типа.',
 			'errCmdNoSupport'      : 'Сервер не поддерживает эту комманду.',
 			'errReplByChild'       : 'Невозможно заменить папку "$1" содержащимся в ней объектом.',
-			'errArcSymlinks'       : 'По соображениям безопасности запрещена распаковка архивов, содержащих ссылки (symlinks).',
+			'errArcSymlinks'       : 'По соображениям безопасности запрещена распаковка архивов, содержащих ссылки (symlinks) или файлы с недопустимыми именами.', // edited 24.06.2012
 			'errArcMaxSize'        : 'Размер файлов в архиве превышает максимально разрешенный.',
 			'errResize'            : 'Не удалось изменить размер "$1".',
 			'errUsupportType'      : 'Неподдерживаемый тип файла.',
-			
+			'errNotUTF8Content'    : 'Файл "$1" содержит текст в кодировке отличной от UTF-8 и не может быть отредактирован.',  // added 9.11.2011
+			'errNetMount'          : 'Не удалось подключить "$1".',    // added 17.04.2012
+			'errNetMountNoDriver'  : 'Неподдерживаемый протокол.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Ошибка монтирования.',           // added 17.04.2012
+			'errNetMountHostReq'   : 'Host required.', // added 18.04.2012
+			'errSessionExpires'    : 'Сессия была завершена так как превышено время отсутствия активности',
+			'errCreatingTempDir'   : 'Ошибка при создании временной директории: "$1"',
+			'errFtpDownloadFile'   : 'Ошибка при скачивании файла с FTP: "$1"',
+			'errFtpUploadFile'     : 'Ошибка при загрузке файла на FTP: "$1"',
+			'errFtpMkdir'          : 'Ошибка при создании директории на FTP: "$1"',
+			'errArchiveExec'       : 'Ошибка при выполнении архивации: "$1"',
+			'errExtractExec'       : 'Ошибка при выполнении распаковки: "$1"',
+
+			'errUploadFile'        : 'Невозможно загрузить файл "$1"',
+
+
 			/******************************* commands names ********************************/
 			'cmdarchive'   : 'Создать архив',
 			'cmdback'      : 'Назад',
@@ -110,7 +125,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'btnApply'  : 'Применить',
 			'btnNo'     : 'Нет',
 			'btnYes'    : 'Да',
-			
+			'btnMount'  : 'Подключить',  // added 18.04.2012
 			/******************************** notifications ********************************/
 			'ntfopen'     : 'Открытие папки',
 			'ntffile'     : 'Открытие файла',
@@ -128,8 +143,9 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfarchive'  : 'Создание архива',
 			'ntfextract'  : 'Распаковка архива',
 			'ntfsearch'   : 'Поиск файлов',
-			'ntfsmth'     : 'Занят важным делом desu >_<',
-			
+			'ntfsmth'     : 'Занят важным делом',
+			'ntfnetmount' : 'Монтирую сетевой диск', // added 18.04.2012
+
 			/************************************ dates **********************************/
 			'dateUnknown' : 'Незвестно',
 			'Today'       : 'Сегодня',
@@ -174,14 +190,11 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Sat'         : 'Сбт',
 
 			/******************************** sort variants ********************************/
-			'sortnameDirsFirst' : 'по имени (папки в начале)', 
-			'sortkindDirsFirst' : 'по типу (папки в начале)', 
-			'sortsizeDirsFirst' : 'по размеру (папки в начале)', 
-			'sortdateDirsFirst' : 'по дате (папки в начале)', 
 			'sortname'          : 'по имени', 
 			'sortkind'          : 'по типу', 
 			'sortsize'          : 'по размеру',
 			'sortdate'          : 'по дате',
+			'sortFoldersFirst'  : 'Папки в начале',
 
 			/********************************** messages **********************************/
 			'confirmReq'      : 'Необходимо подтверждение.',
@@ -223,7 +236,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : 'Помощь',
 			'webfm'           : 'Файловый менеджер для web',
 			'ver'             : 'Версия',
-			'protocol'        : 'версия протокола',
+			'protocolver'     : 'версия протокола',
 			'homepage'        : 'Сайт проекта',
 			'docs'            : 'Документация',
 			'github'          : 'Fork us on Github',
@@ -256,7 +269,12 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'rotate-cw'       : 'Поворот на 90 градусов по часовой стрелке',
 			'rotate-ccw'      : 'Поворот на 90 градусов против часовой стрелке',
 			'degree'          : '°',
-
+			'netMountDialogTitle' : 'Подключить сетевой диск', // added 18.04.2012
+			'protocol'            : 'Протокол', // added 18.04.2012
+			'host'                : 'Хост', // added 18.04.2012
+			'port'                : 'Порт', // added 18.04.2012
+			'user'                : 'Пользователь', // added 18.04.2012
+			'pass'                : 'Пароль', // added 18.04.2012
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : 'Неизвестный',
 			'kindFolder'      : 'Папка',
@@ -334,7 +352,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'kindVideoFlash'  : 'Видео Flash',
 			'kindVideoMKV'    : 'Видео Matroska',
 			'kindVideoOGG'    : 'Видео Ogg'
-			
+			,'volume_files' : 'Файлы '
 		}
 	}
 }

+ 348 - 0
main/inc/lib/elfinder/js/i18n/elfinder.sk.js

@@ -0,0 +1,348 @@
+/**
+ * Slovak translation
+ * @author Jakub Ďuraš <jkblmr@gmail.com>
+ * @version 2013-7-24
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.sk = {
+		translator : 'Jakub Ďuraš &lt;jkblmr@gmail.com&gt;',
+		language   : 'slovenčina',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : 'Chyba',
+			'errUnknown'           : 'Neznáma chyba.',
+			'errUnknownCmd'        : 'Neznámy príkaz.',
+			'errJqui'              : 'Nesprávna jQuery UI konfigurácia. Selectable, draggable a droppable musia byť načítané.',
+			'errNode'              : 'elFinder vyžaduje vytvorenie DOM Elementu.',
+			'errURL'               : 'Nesprávna elFinder konfigurácia! URL nie je definovaná.',
+			'errAccess'            : 'Prístup zamietnutý.',
+			'errConnect'           : 'Nepodarilo sa pripojiť do backendu.',
+			'errAbort'             : 'Pripojenie zrušené.',
+			'errTimeout'           : 'Vypršal limit pripojenia.',
+			'errNotFound'          : 'Backend nenájdený.',
+			'errResponse'          : 'Nesprávna backend odpoveď.',
+			'errConf'              : 'Nesprávna backend konfigurácia.',
+			'errJSON'              : 'Požadovaný PHP JSON modul nie je nainštalovaný.',
+			'errNoVolumes'         : 'Nie je dostupné žiadne čitateľné médium.',
+			'errCmdParams'         : 'Nesprávne parametre pre príkaz "$1".',
+			'errDataNotJSON'       : 'Dáta nie sú formátu JSON.',
+			'errDataEmpty'         : 'Prázdne dáta.',
+			'errCmdReq'            : 'Backend požiadavka požaduje meno príkazu.',
+			'errOpen'              : 'Nie je možné otvoriť súbor "$1".',
+			'errNotFolder'         : 'Objekt nie je priečinok.',
+			'errNotFile'           : 'Objekt nie je súbor.',
+			'errRead'              : 'Nie je možné prečítať súbor "$1".',
+			'errWrite'             : 'Nie je možné písať do súboru "$1".',
+			'errPerm'              : 'Nepovolený prístup.',
+			'errLocked'            : '"$1" je uzamknutý, a nemôže byť premenovaný, presunutý alebo odstránený.',
+			'errExists'            : 'Súbor s menom "$1" už existuje.',
+			'errInvName'           : 'Nesprávne meno súboru.',
+			'errFolderNotFound'    : 'Priečinok nenájdený.',
+			'errFileNotFound'      : 'Súbor nenájdený.',
+			'errTrgFolderNotFound' : 'Zvolený priečinok "$1" nenájdený.',
+			'errPopup'             : 'Prehliadač zablokoval otvorenie vyskakovacieho okna. Pre otvorenie súboru povoľte vyskakovacie okná.',
+			'errMkdir'             : 'Nie je možné vytvoriť priečinok "$1".',
+			'errMkfile'            : 'Nie je možné vytvoriť súbor "$1".',
+			'errRename'            : 'Nie je možné premenovať "$1".',
+			'errCopyFrom'          : 'Kopírovanie súborov z média "$1" nie je povolené.',
+			'errCopyTo'            : 'Kopírovanie súborov na médium "$1" nie je povolené.',
+			'errUploadCommon'      : 'Problém s nahrávaním.',
+			'errUpload'            : 'Nie je možné nahrať "$1".',
+			'errUploadNoFiles'     : 'Žiadne súbory neboli nájdené na nahranie.',
+			'errMaxSize'           : 'Dáta prekračujú maximálnu povolenú veľkosť.',
+			'errFileMaxSize'       : 'Súbor prekračuje maximálnu povolenú veľkosť.',
+			'errUploadMime'        : 'Nepovolený typ súboru.',
+			'errUploadTransfer'    : 'Problém s nahrávaním "$1".', 
+			'errSave'              : 'Nie je možné uložiť "$1".',
+			'errCopy'              : 'Nie je možné kopíropvať "$1".',
+			'errMove'              : 'Nie je možné preniesť "$1".',
+			'errCopyInItself'      : 'Nie je možné kopírovať "$1" do seba.',
+			'errRm'                : 'Nie je možné vymazať "$1".',
+			'errExtract'           : 'Nie je možné extrahovať súbory z "$1".',
+			'errArchive'           : 'Nie je možné vytvoriť archív.',
+			'errArcType'           : 'Nepodporovaný typ archívu.',
+			'errNoArchive'         : 'Súbor nie je archívom, alebo je nepodporovaného typu.',
+			'errCmdNoSupport'      : 'Backend nepodporuje tento príkaz.',
+			'errReplByChild'       : 'Priečinok “$1” nemôže byť nahradený položkou, ktorú už obsahuje.',
+			'errArcSymlinks'       : 'Z bezpečnostných dôvodov bolo zakázané extrahovanie archívov obsahujúcich symlinky, alebo súborov s nepovolenými menami.', // edited 24.06.2012
+			'errArcMaxSize'        : 'Súbory archívu prekračujú maximálnu povolenú veľkosť.',
+			'errResize'            : 'Nie je možné zmeniť veľkost "$1".',
+			'errUsupportType'      : 'Nepodporovaný typ súboru.',
+			'errNotUTF8Content'    : 'Súbor "$1" nemá obsah kódovaný v UTF-8, a nemôže byť upravený.',  // added 9.11.2011
+			'errNetMount'          : 'Nie je možné pripojiť "$1".',     // added 17.04.2012
+			'errNetMountNoDriver'  : 'Nepodporovaný protokol.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Pripájanie zlyhalo.',             // added 17.04.2012
+			'errNetMountHostReq'   : 'Host je požadovaný.', // added 18.04.2012
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Vytvoriť archív',
+			'cmdback'      : 'Späť',
+			'cmdcopy'      : 'Kopírovať',
+			'cmdcut'       : 'Vystrihnúť',
+			'cmddownload'  : 'Stiahnuť',
+			'cmdduplicate' : 'Duplikovať',
+			'cmdedit'      : 'Upraviť súbor',
+			'cmdextract'   : 'Extrahovať súbory z archívu',
+			'cmdforward'   : 'Ďalej',
+			'cmdgetfile'   : 'Zvoliť súbory',
+			'cmdhelp'      : 'O tomto softvéri',
+			'cmdhome'      : 'Domov',
+			'cmdinfo'      : 'Získať info',
+			'cmdmkdir'     : 'Nový priečinok',
+			'cmdmkfile'    : 'Nový textový súbor',
+			'cmdopen'      : 'Otvoriť',
+			'cmdpaste'     : 'Vložiť',
+			'cmdquicklook' : 'Náhľad',
+			'cmdreload'    : 'Obnoviť',
+			'cmdrename'    : 'Premenovať',
+			'cmdrm'        : 'Vymazať',
+			'cmdsearch'    : 'Nájsť súbory',
+			'cmdup'        : 'Prejsť do nadradeného priečinka',
+			'cmdupload'    : 'Nahrať súbory',
+			'cmdview'      : 'Pozrieť',
+			'cmdresize'    : 'Zmeniť veľkosť obrázku',
+			'cmdsort'      : 'Zoradiť',
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Zavrieť',
+			'btnSave'   : 'Uložiť',
+			'btnRm'     : 'Vymazať',
+			'btnApply'  : 'Použiť',
+			'btnCancel' : 'Zrušiť',
+			'btnNo'     : 'Nie',
+			'btnYes'    : 'Áno',
+			
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Otváranie priečinka',
+			'ntffile'     : 'Otváranie súboru',
+			'ntfreload'   : 'Znovu-načítanie obsahu priečinka',
+			'ntfmkdir'    : 'Vytváranie priečinka',
+			'ntfmkfile'   : 'Vytváranie súborov',
+			'ntfrm'       : 'Vymazanie súborov',
+			'ntfcopy'     : 'Kopírovanie súborov',
+			'ntfmove'     : 'Premiestnenie súborov',
+			'ntfprepare'  : 'Príprava na kopírovanie súborov',
+			'ntfrename'   : 'Premenovanie súborov',
+			'ntfupload'   : 'Upload súborov',
+			'ntfdownload' : 'Download súborov',
+			'ntfsave'     : 'Uloženie súborov',
+			'ntfarchive'  : 'Vytváranie archívu',
+			'ntfextract'  : 'Extrahovanie súborov z archívu',
+			'ntfsearch'   : 'Prehľadávanie súborov',
+			'ntfsmth'     : 'Nejaká činnosť >_<',
+			'ntfloadimg'  : 'Nahrávanie obrázka',
+			'ntfnetmount' : 'Pripájanie sieťového média', // added 18.04.2012
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : 'neznámy',
+			'Today'       : 'Dnes',
+			'Yesterday'   : 'Včera',
+			'Jan'         : 'Jan',
+			'Feb'         : 'Feb',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Apr',
+			'May'         : 'Maj',
+			'Jun'         : 'Jun',
+			'Jul'         : 'Júl',
+			'Aug'         : 'Aug',
+			'Sep'         : 'Sep',
+			'Oct'         : 'Okt',
+			'Nov'         : 'Nov',
+			'Dec'         : 'Dec',
+			'January'     : 'Január',
+			'February'    : 'Február',
+			'March'       : 'Marec',
+			'April'       : 'Apríl',
+			'May'         : 'Máj',
+			'June'        : 'Jún',
+			'July'        : 'Júl',
+			'August'      : 'August',
+			'September'   : 'September',
+			'October'     : 'Október',
+			'November'    : 'November',
+			'December'    : 'December',
+			'Sunday'      : 'Nedeľa', 
+			'Monday'      : 'Pondelok', 
+			'Tuesday'     : 'Utorok', 
+			'Wednesday'   : 'Streda', 
+			'Thursday'    : 'Štvrtok', 
+			'Friday'      : 'Piatok', 
+			'Saturday'    : 'Sobota',
+			'Sun'         : 'Ned', 
+			'Mon'         : 'Pon', 
+			'Tue'         : 'Ut', 
+			'Wed'         : 'Str', 
+			'Thu'         : 'Štv', 
+			'Fri'         : 'Pia', 
+			'Sat'         : 'Sob',
+			/******************************** sort variants ********************************/
+			'sortname'          : 'podľa mena', 
+			'sortkind'          : 'podľa druhu', 
+			'sortsize'          : 'podľa veľkosti',
+			'sortdate'          : 'podľa dátumu',
+			'sortFoldersFirst'  : 'Najskôr Priečinky', // added 22.06.2012
+			
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Očakávam potvrdenie',
+			'confirmRm'       : 'Určite chcete vymazať súbory?<br/>Nebude sa to dať vrátiť späť!',
+			'confirmRepl'     : 'Nahradiť starý súbor novým?',
+			'apllyAll'        : 'Použiť na všetky',
+			'name'            : 'Meno',
+			'size'            : 'Veľkosť',
+			'perms'           : 'Povolenia',
+			'modify'          : 'Zmenené',
+			'kind'            : 'Druh',
+			'read'            : 'čítať',
+			'write'           : 'zapisovať',
+			'noaccess'        : 'bez prístupu',
+			'and'             : 'a',
+			'unknown'         : 'neznámy',
+			'selectall'       : 'Vybrať všetky súbory',
+			'selectfiles'     : 'Vybrať súbor(y)',
+			'selectffile'     : 'Vybrať prvý súbor',
+			'selectlfile'     : 'Vybrať posledný súbor',
+			'viewlist'        : 'Zoznam',
+			'viewicons'       : 'Ikony',
+			'places'          : 'Miesta',
+			'calc'            : 'Prepočítavanie', 
+			'path'            : 'Cesta',
+			'aliasfor'        : 'Alias pre',
+			'locked'          : 'Uzamknuté',
+			'dim'             : 'Rozmery',
+			'files'           : 'Súbory',
+			'folders'         : 'Priečinky',
+			'items'           : 'Položky',
+			'yes'             : 'áno',
+			'no'              : 'nie',
+			'link'            : 'Odkaz',
+			'searcresult'     : 'Výsledky hľadania',  
+			'selected'        : 'zvolené položky',
+			'about'           : 'O aplikácii',
+			'shortcuts'       : 'Skratky',
+			'help'            : 'Pomoc',
+			'webfm'           : 'Webový správca súborov',
+			'ver'             : 'Verzia',
+			'protocolver'     : 'verzia protokolu',
+			'homepage'        : 'Domovská stránka',
+			'docs'            : 'Dokumentácia',
+			'github'          : 'Pozri nás na Githube',
+			'twitter'         : 'Nasleduj nás na Twitteri',
+			'facebook'        : 'Pripoj sa k nám na Facebooku',
+			'team'            : 'Tím',
+			'chiefdev'        : 'Hlavný vývojár',
+			'developer'       : 'vývojár',
+			'contributor'     : 'prispievateľ',
+			'maintainer'      : 'správca',
+			'translator'      : 'prekladateľ',
+			'icons'           : 'Ikony',
+			'dontforget'      : 'and don\'t forget to take your towel',
+			'shortcutsof'     : 'Skratky zakázané',
+			'dropFiles'       : 'Sem pustite súbory',
+			'or'              : 'alebo',
+			'selectForUpload' : 'Zvoliť súbory na upload',
+			'moveFiles'       : 'Premiestniť súbory',
+			'copyFiles'       : 'Kopírovať súbory',
+			'rmFromPlaces'    : 'Odstrániť z umiestnení',
+			'untitled folder' : 'nepomenovaný priečinok',
+			'untitled file.txt' : 'untitled file.txt',
+			'aspectRatio'     : 'Pomer zobrazenia',
+			'scale'           : 'Mierka',
+			'width'           : 'Šírka',
+			'height'          : 'Výška',
+			'mode'            : 'Mód',
+			'resize'          : 'Zmeniť veľkosť',
+			'crop'            : 'Zrezať',
+			'rotate'          : 'Otočiť',
+			'rotate-cw'       : 'Otočiť o 90 stupňov (v smere h.r.)',
+			'rotate-ccw'      : 'Otočiť o 90 stupňov (proti smeru)',
+			'degree'          : 'Stupne',
+			'netMountDialogTitle' : 'Pripojiť sieťové médium', // added 18.04.2012
+			'protocol'            : 'Protokol', // added 18.04.2012
+			'host'                : 'Host', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'Užívateľ', // added 18.04.2012
+			'pass'                : 'Heslo', // added 18.04.2012
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Neznámy',
+			'kindFolder'      : 'Priečinok',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : 'Porušený alias',
+			// applications
+			'kindApp'         : 'Aplikácia',
+			'kindPostscript'  : 'Postscript dokument',
+			'kindMsOffice'    : 'Microsoft Office dokument',
+			'kindMsWord'      : 'Microsoft Word dokument',
+			'kindMsExcel'     : 'Microsoft Excel dokument',
+			'kindMsPP'        : 'Microsoft Powerpoint prezentácia',
+			'kindOO'          : 'Open Office dokument',
+			'kindAppFlash'    : 'Flashová aplikácia',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent súbor',
+			'kind7z'          : '7z archív',
+			'kindTAR'         : 'TAR archív',
+			'kindGZIP'        : 'GZIP archív',
+			'kindBZIP'        : 'BZIP archív',
+			'kindZIP'         : 'ZIP archív',
+			'kindRAR'         : 'RAR archív',
+			'kindJAR'         : 'Java JAR súbor',
+			'kindTTF'         : 'True Type font',
+			'kindOTF'         : 'Open Type font',
+			'kindRPM'         : 'RPM balík',
+			// texts
+			'kindText'        : 'Textový document',
+			'kindTextPlain'   : 'Obyčajný text',
+			'kindPHP'         : 'PHP zdrojový kód',
+			'kindCSS'         : 'Cascading style sheet (CSS)',
+			'kindHTML'        : 'HTML dokument',
+			'kindJS'          : 'Javascript zdrojový kód',
+			'kindRTF'         : 'Rich Text Format',
+			'kindC'           : 'C zdrojový kód',
+			'kindCHeader'     : 'C header zdrojový kód',
+			'kindCPP'         : 'C++ zdrojový kód',
+			'kindCPPHeader'   : 'C++ header zdrojový kód',
+			'kindShell'       : 'Unix shell script',
+			'kindPython'      : 'Python zdrojový kód',
+			'kindJava'        : 'Java zdrojový kód',
+			'kindRuby'        : 'Ruby zdrojový kód',
+			'kindPerl'        : 'Perl zdrojový kód',
+			'kindSQL'         : 'SQL zdrojový kód',
+			'kindXML'         : 'XML dokument',
+			'kindAWK'         : 'AWK zdrojový kód',
+			'kindCSV'         : 'Čiarkou oddeľované hodnoty',
+			'kindDOCBOOK'     : 'Docbook XML dokument',
+			// images
+			'kindImage'       : 'Obrázok',
+			'kindBMP'         : 'BMP Obrázok',
+			'kindJPEG'        : 'JPEG Obrázok',
+			'kindGIF'         : 'GIF Obrázok',
+			'kindPNG'         : 'PNG Obrázok',
+			'kindTIFF'        : 'TIFF Obrázok',
+			'kindTGA'         : 'TGA Obrázok',
+			'kindPSD'         : 'Adobe Photoshop Obrázok',
+			'kindXBITMAP'     : 'X bitmap Obrázok',
+			'kindPXM'         : 'Pixelmator Obrázok',
+			// media
+			'kindAudio'       : 'Zvukový súbor',
+			'kindAudioMPEG'   : 'MPEG zvuk',
+			'kindAudioMPEG4'  : 'MPEG-4 zvuk',
+			'kindAudioMIDI'   : 'MIDI zvuk',
+			'kindAudioOGG'    : 'Ogg Vorbis zvuk',
+			'kindAudioWAV'    : 'WAV zvuk',
+			'AudioPlaylist'   : 'MP3 playlist',
+			'kindVideo'       : 'Video súbor',
+			'kindVideoDV'     : 'DV video',
+			'kindVideoMPEG'   : 'MPEG video',
+			'kindVideoMPEG4'  : 'MPEG-4 video',
+			'kindVideoAVI'    : 'AVI video',
+			'kindVideoMOV'    : 'Quick Time video',
+			'kindVideoWM'     : 'Windows Media video',
+			'kindVideoFlash'  : 'Flash video',
+			'kindVideoMKV'    : 'Matroska video',
+			'kindVideoOGG'    : 'Ogg video'
+		}
+	}
+}
+

+ 340 - 0
main/inc/lib/elfinder/js/i18n/elfinder.sl.js

@@ -0,0 +1,340 @@
+/**
+ * Slovenian translation
+ * @author Damjan Rems <d_rems at yahoo.com>
+ * @version 2012-09-07
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.sl = {
+		translator : 'Damjan Rems &lt;d_rems at yahoo.com&gt;',
+		language   : 'Slovenščina',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : 'Napaka',
+			'errUnknown'           : 'Neznana napaka.',
+			'errUnknownCmd'        : 'Neznan ukaz.',
+			'errJqui'              : 'Napačna jQuery UI nastavitev. Selectable, draggable in droppable dodatki morajo biti vključeni.',
+			'errNode'              : 'elFinder potrebuje "DOM Element".',
+			'errURL'               : 'Napačna nastavitev elFinder-ja! Manjka URL nastavitev.',
+			'errAccess'            : 'Dostop zavrnjen.',
+			'errConnect'           : 'Ne morem se priključiti na "backend".',
+			'errAbort'             : 'Povezava prekinjena (aborted).',
+			'errTimeout'           : 'Povezava potekla (timeout).',
+			'errNotFound'          : 'Nisem našel "backend-a".',
+			'errResponse'          : 'Napačni "backend" odgovor.',
+			'errConf'              : 'Napačna "backend" nastavitev.',
+			'errJSON'              : 'JSON modul ni instaliran.',
+			'errNoVolumes'         : 'Readable volumes not available.',
+			'errCmdParams'         : 'Napačni parametri za ukaz "$1".',
+			'errDataNotJSON'       : 'Podatki niso v JSON obliki.',
+			'errDataEmpty'         : 'Ni podatkov oz. so prazni.',
+			'errCmdReq'            : '"Backend" zahtevek potrebuje ime ukaza.',
+			'errOpen'              : '"$1" ni možno odpreti.',
+			'errNotFolder'         : 'Objekt ni mapa.',
+			'errNotFile'           : 'Objekt ni datoteka.',
+			'errRead'              : '"$1" ni možno brati.',
+			'errWrite'             : 'Ne morem pisati v "$1".',
+			'errPerm'              : 'Dostop zavrnjen.',
+			'errLocked'            : '"$1" je zaklenjen(a) in je ni možno preimenovati, premakniti ali izbrisati.',
+			'errExists'            : 'Datoteka z imenom "$1" že obstaja.',
+			'errInvName'           : 'Napačno ime datoteke.',
+			'errFolderNotFound'    : 'Mape nisem našel.',
+			'errFileNotFound'      : 'Datoteke nisem našel.',
+			'errTrgFolderNotFound' : 'Ciljna mapa "$1" ne obstaja.',
+			'errPopup'             : 'Brskalnik je preprečil prikaz (popup) okna. Za vpogled datoteke omogočite nastavitev v vašem brskalniku.',
+			'errMkdir'             : 'Ni možno dodati mape "$1".',
+			'errMkfile'            : 'Ni možno dodati datoteke "$1".',
+			'errRename'            : 'Ni možno preimenovati "$1".',
+			'errCopyFrom'          : 'Kopiranje datotek iz "$1" ni dovoljeno.',
+			'errCopyTo'            : 'Kopiranje datotek na "$1" ni dovoljeno.',
+			'errUploadCommon'      : 'Napaka pri prenosu.',
+			'errUpload'            : '"$1" ni možno naložiti (upload).',
+			'errUploadNoFiles'     : 'Ni datotek za nalaganje (upload).',
+			'errMaxSize'           : 'Podatki presegajo največjo dovoljeno velikost.',
+			'errFileMaxSize'       : 'Datoteka presega največjo dovoljeno velikost.',
+			'errUploadMime'        : 'Datoteke s to končnico niso dovoljene.',
+			'errUploadTransfer'    : '"$1" napaka pri prenosu.', 
+			'errSave'              : '"$1" ni možno shraniti.',
+			'errCopy'              : '"$1" ni možno kopirati.',
+			'errMove'              : '"$1" ni možno premakniti.',
+			'errCopyInItself'      : '"$1" ni možno kopirati samo vase.',
+			'errRm'                : '"$1" ni možno izbrisati.',
+			'errExtract'           : 'Datotek iz "$1" ni možno odpakirati.',
+			'errArchive'           : 'Napaka pri delanju arhiva.',
+			'errArcType'           : 'Nepodprta vrsta arhiva.',
+			'errNoArchive'         : 'Datoteka ni arhiv ali vrsta arhiva ni podprta.',
+			'errCmdNoSupport'      : '"Backend" ne podpira tega ukaza.',
+			'errReplByChild'       : 'Mape “$1” ni možno zamenjati z vsebino mape.',
+			'errArcSymlinks'       : 'Zaradi varnostnih razlogov arhiva ki vsebuje "symlinks" ni možno odpakirati.',
+			'errArcMaxSize'        : 'Datoteke v arhivu presegajo največjo dovoljeno velikost.',
+			'errResize'            : '"$1" ni možno razširiti.',
+			'errUsupportType'      : 'Nepodprta vrsta datoteke.',
+			
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Naredi arhiv',
+			'cmdback'      : 'Nazaj',
+			'cmdcopy'      : 'Kopiraj',
+			'cmdcut'       : 'Izreži',
+			'cmddownload'  : 'Poberi (download)',
+			'cmdduplicate' : 'Podvoji',
+			'cmdedit'      : 'Uredi datoteko',
+			'cmdextract'   : 'Odpakiraj datoteke iz arhiva',
+			'cmdforward'   : 'Naprej',
+			'cmdgetfile'   : 'Izberi datoteke',
+			'cmdhelp'      : 'Več o',
+			'cmdhome'      : 'Domov',
+			'cmdinfo'      : 'Lastnosti',
+			'cmdmkdir'     : 'Nova mapa',
+			'cmdmkfile'    : 'Nova datoteka',
+			'cmdopen'      : 'Odpri',
+			'cmdpaste'     : 'Prilepi',
+			'cmdquicklook' : 'Hitri ogled',
+			'cmdreload'    : 'Osveži',
+			'cmdrename'    : 'Preimenuj',
+			'cmdrm'        : 'Izbriši',
+			'cmdsearch'    : 'Poišči datoteke',
+			'cmdup'        : 'Mapa nazaj',
+			'cmdupload'    : 'Naloži (upload)',
+			'cmdview'      : 'Ogled',
+			'cmdresize'    : 'Povečaj (pomanjšaj) sliko',
+			'cmdsort'      : 'Razvrsti',
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Zapri',
+			'btnSave'   : 'Shrani',
+			'btnRm'     : 'Izbriši',
+			'btnApply'  : 'Uporabi',
+			'btnCancel' : 'Prekliči',
+			'btnNo'     : 'Ne',
+			'btnYes'    : 'Da',
+			
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Odpri mapo',
+			'ntffile'     : 'Odpri datoteko',
+			'ntfreload'   : 'Osveži vsebino mape',
+			'ntfmkdir'    : 'Ustvarjam mapo',
+			'ntfmkfile'   : 'Ustvarjam datoteke',
+			'ntfrm'       : 'Brišem datoteke',
+			'ntfcopy'     : 'Kopiram datoteke',
+			'ntfmove'     : 'Premikam datoteke',
+			'ntfprepare'  : 'Pripravljam se na kopiranje datotek',
+			'ntfrename'   : 'Preimenujem datoteke',
+			'ntfupload'   : 'Nalagam (upload) datoteke',
+			'ntfdownload' : 'Pobiram (download) datoteke',
+			'ntfsave'     : 'Shranjujem datoteke',
+			'ntfarchive'  : 'Ustvarjam arhiv',
+			'ntfextract'  : 'Razpakiram datoteke iz arhiva',
+			'ntfsearch'   : 'Iščem datoteke',
+			'ntfsmth'     : 'Počakaj delam >_<',
+			'ntfloadimg'  : 'Nalagam sliko',
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : 'neznan',
+			'Today'       : 'Danes',
+			'Yesterday'   : 'Včeraj',
+			'Jan'         : 'Jan',
+			'Feb'         : 'Feb',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Apr',
+			'May'         : 'Maj',
+			'Jun'         : 'Jun',
+			'Jul'         : 'Jul',
+			'Aug'         : 'Avg',
+			'Sep'         : 'Sep',
+			'Oct'         : 'Okt',
+			'Nov'         : 'Nov',
+			'Dec'         : 'Dec',
+			'January'     : 'Januar',
+			'February'    : 'Februar',
+			'March'       : 'Marec',
+			'April'       : 'April',
+			'May'         : 'Maj',
+			'June'        : 'Junij',
+			'July'        : 'Julij',
+			'August'      : 'Avgust',
+			'September'   : 'September',
+			'October'     : 'Oktober',
+			'November'    : 'November',
+			'December'    : 'December',
+			'Sunday'      : 'Nedelja', 
+			'Monday'      : 'Ponedeljek', 
+			'Tuesday'     : 'Torek', 
+			'Wednesday'   : 'Sreda', 
+			'Thursday'    : 'Četrtek', 
+			'Friday'      : 'Petek', 
+			'Saturday'    : 'Sobota',
+			'Sun'         : 'Ned', 
+			'Mon'         : 'Pon', 
+			'Tue'         : 'Tor', 
+			'Wed'         : 'Sre', 
+			'Thu'         : 'Čet', 
+			'Fri'         : 'Pet', 
+			'Sat'         : 'Sob',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'po imenu (mape na začetku)', 
+			'sortkindDirsFirst' : 'po vrsti (mape na začetku)', 
+			'sortsizeDirsFirst' : 'po velikosti (mape na začetku)', 
+			'sortdateDirsFirst' : 'po datumu (mape na začetku)', 
+			'sortname'          : 'po imenu', 
+			'sortkind'          : 'po vrsti', 
+			'sortsize'          : 'po velikosti',
+			'sortdate'          : 'po datumu',
+			
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Zahtevana je potrditev',
+			'confirmRm'       : 'Ste prepričani, da želite izbrisati datoteko?<br/>POZOR! Tega ukaza ni možno preklicati!',
+			'confirmRepl'     : 'Zamenjam staro datoteko z novo?',
+			'apllyAll'        : 'Uporabi pri vseh',
+			'name'            : 'Ime',
+			'size'            : 'Velikost',
+			'perms'           : 'Dovoljenja',
+			'modify'          : 'Spremenjeno',
+			'kind'            : 'Vrsta',
+			'read'            : 'beri',
+			'write'           : 'piši',
+			'noaccess'        : 'ni dostopa',
+			'and'             : 'in',
+			'unknown'         : 'neznan',
+			'selectall'       : 'Izberi vse datoteke',
+			'selectfiles'     : 'Izberi datotek(o)e',
+			'selectffile'     : 'Izberi prvo datoteko',
+			'selectlfile'     : 'Izberi zadnjo datoteko',
+			'viewlist'        : 'Seznam',
+			'viewicons'       : 'Ikone',
+			'places'          : 'Mesta (places)',
+			'calc'            : 'Izračun', 
+			'path'            : 'Pot do',
+			'aliasfor'        : 'Sopomenka (alias) za',
+			'locked'          : 'Zaklenjeno',
+			'dim'             : 'Dimenzije',
+			'files'           : 'Datoteke',
+			'folders'         : 'Mape',
+			'items'           : 'Predmeti',
+			'yes'             : 'da',
+			'no'              : 'ne',
+			'link'            : 'Povezava',
+			'searcresult'     : 'Rezultati iskanja',  
+			'selected'        : 'izbrani predmeti',
+			'about'           : 'Več o',
+			'shortcuts'       : 'Bližnjice',
+			'help'            : 'Pomoč',
+			'webfm'           : 'Spletni upravitelj datotek',
+			'ver'             : 'Verzija',
+			'protocol'        : 'verzija protokola',
+			'homepage'        : 'Domača stran',
+			'docs'            : 'Dokumentacija',
+			'github'          : 'Fork us on Github',
+			'twitter'         : 'Sledi na twitterju',
+			'facebook'        : 'Pridruži se nam na facebook-u',
+			'team'            : 'Tim',
+			'chiefdev'        : 'Glavni razvijalec',
+			'developer'       : 'razvijalec',
+			'contributor'     : 'contributor',
+			'maintainer'      : 'vzdrževalec',
+			'translator'      : 'prevajalec',
+			'icons'           : 'Ikone',
+			'dontforget'      : 'In ne pozabi na brisačo',
+			'shortcutsof'     : 'Bližnjica onemogočena',
+			'dropFiles'       : 'Datoteke spusti tukaj',
+			'or'              : 'ali',
+			'selectForUpload' : 'Izberi datoteke za nalaganje',
+			'moveFiles'       : 'Premakni datoteke',
+			'copyFiles'       : 'Kopiraj datoteke',
+			'rmFromPlaces'    : 'Izbriši iz mesta (places)',
+			'untitled folder' : 'mapa brez imena',
+			'untitled file.txt' : 'brez imena file.txt',
+			'aspectRatio'     : 'Razmerje slike',
+			'scale'           : 'Razširi',
+			'width'           : 'Širina',
+			'height'          : 'Višina',
+			'mode'            : 'Način (mode)',
+			'resize'          : 'Povečaj',
+			'crop'            : 'Obreži',
+			'rotate'          : 'Zavrti',
+			'rotate-cw'       : 'Zavrti 90 st. v smeri ure',
+			'rotate-ccw'      : 'Zavrti 90 st. v obratni smeri ure',
+			'degree'          : 'Stopnja',
+			
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Neznan',
+			'kindFolder'      : 'Mapa',
+			'kindAlias'       : 'Sopomenka (alias)',
+			'kindAliasBroken' : 'Nedelujoča sopomenka (alias)',
+			// applications
+			'kindApp'         : 'Program',
+			'kindPostscript'  : 'Postscript dokument',
+			'kindMsOffice'    : 'Microsoft Office dokument',
+			'kindMsWord'      : 'Microsoft Word dokument',
+			'kindMsExcel'     : 'Microsoft Excel dokument',
+			'kindMsPP'        : 'Microsoft Powerpoint predstavitev',
+			'kindOO'          : 'Open Office dokument',
+			'kindAppFlash'    : 'Flash program',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent datoteka',
+			'kind7z'          : '7z arhiv',
+			'kindTAR'         : 'TAR arhiv',
+			'kindGZIP'        : 'GZIP arhiv',
+			'kindBZIP'        : 'BZIP arhiv',
+			'kindZIP'         : 'ZIP arhiv',
+			'kindRAR'         : 'RAR arhiv',
+			'kindJAR'         : 'Java JAR datoteka',
+			'kindTTF'         : 'True Type font',
+			'kindOTF'         : 'Open Type font',
+			'kindRPM'         : 'RPM paket',
+			// texts
+			'kindText'        : 'Tekst dokument',
+			'kindTextPlain'   : 'Samo tekst',
+			'kindPHP'         : 'PHP koda',
+			'kindCSS'         : 'Cascading style sheet (CSS)',
+			'kindHTML'        : 'HTML dokument',
+			'kindJS'          : 'Javascript koda',
+			'kindRTF'         : 'Rich Text Format (RTF)',
+			'kindC'           : 'C koda',
+			'kindCHeader'     : 'C header koda',
+			'kindCPP'         : 'C++ koda',
+			'kindCPPHeader'   : 'C++ header koda',
+			'kindShell'       : 'Unix shell skripta',
+			'kindPython'      : 'Python kdoa',
+			'kindJava'        : 'Java koda',
+			'kindRuby'        : 'Ruby koda',
+			'kindPerl'        : 'Perl skripta',
+			'kindSQL'         : 'SQL koda',
+			'kindXML'         : 'XML dokument',
+			'kindAWK'         : 'AWK koda',
+			'kindCSV'         : 'Besedilo ločeno z vejico (CSV)',
+			'kindDOCBOOK'     : 'Docbook XML dokument',
+			// images
+			'kindImage'       : 'Slika',
+			'kindBMP'         : 'BMP slika',
+			'kindJPEG'        : 'JPEG slika',
+			'kindGIF'         : 'GIF slika',
+			'kindPNG'         : 'PNG slika',
+			'kindTIFF'        : 'TIFF slika',
+			'kindTGA'         : 'TGA slika',
+			'kindPSD'         : 'Adobe Photoshop slika',
+			'kindXBITMAP'     : 'X bitmap slika',
+			'kindPXM'         : 'Pixelmator slika',
+			// media
+			'kindAudio'       : 'Avdio medija',
+			'kindAudioMPEG'   : 'MPEG zvok',
+			'kindAudioMPEG4'  : 'MPEG-4 zvok',
+			'kindAudioMIDI'   : 'MIDI zvok',
+			'kindAudioOGG'    : 'Ogg Vorbis zvok',
+			'kindAudioWAV'    : 'WAV zvok',
+			'AudioPlaylist'   : 'MP3 seznam',
+			'kindVideo'       : 'Video medija',
+			'kindVideoDV'     : 'DV film',
+			'kindVideoMPEG'   : 'MPEG film',
+			'kindVideoMPEG4'  : 'MPEG-4 film',
+			'kindVideoAVI'    : 'AVI film',
+			'kindVideoMOV'    : 'Quick Time film',
+			'kindVideoWM'     : 'Windows Media film',
+			'kindVideoFlash'  : 'Flash film',
+			'kindVideoMKV'    : 'Matroska film',
+			'kindVideoOGG'    : 'Ogg film'
+		}
+	}
+}

+ 353 - 0
main/inc/lib/elfinder/js/i18n/elfinder.sv.js

@@ -0,0 +1,353 @@
+/**
+ * Swedish translation
+ * @author Gabriel Satzger <gabriel.satzger@sbg.se>
+ * @version 2012-09-10
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.sv = {
+		translator : 'Gabriel Satzger &lt;gabriel.satzger@sbg.se&gt;',
+		language   : 'Svenska',
+		direction  : 'ltr',
+		dateFormat : 'Y-m-d H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : 'Error',
+			'errUnknown'           : 'Okänt error.',
+			'errUnknownCmd'        : 'Okänt kommando.',
+			'errJqui'              : 'Felaktig jQuery UI konfiguration. Komponenterna selectable, draggable och droppable måste vara inkluderade.',
+			'errNode'              : 'elFinder kräver att DOM Elementen skapats.',
+			'errURL'               : 'Felaktig elFinder konfiguration! URL parametern är inte satt.',
+			'errAccess'            : 'Åtkomst nekad.',
+			'errConnect'           : 'Kan inte ansluta till backend.',
+			'errAbort'             : 'Anslutningen avbröts.',
+			'errTimeout'           : 'Anslutningen löpte ut.',
+			'errNotFound'          : 'Backend hittades inte.',
+			'errResponse'          : 'Ogiltig backend svar.',
+			'errConf'              : 'Ogiltig backend konfiguration.',
+			'errJSON'              : 'PHP JSON modul är inte installerad.',
+			'errNoVolumes'         : 'Läsbara volymer är inte tillgängliga.',
+			'errCmdParams'         : 'Ogiltiga parametrar för kommandot "$1".',
+			'errDataNotJSON'       : 'Datan är inte JSON.',
+			'errDataEmpty'         : 'Datan är tom.',
+			'errCmdReq'            : 'Backend begäran kräver kommandonamn.',
+			'errOpen'              : 'Kan inte öppna "$1".',
+			'errNotFolder'         : 'Objektet är inte en mapp.',
+			'errNotFile'           : 'Objektet är inte en fil.',
+			'errRead'              : 'Kan inte läsa "$1".',
+			'errWrite'             : 'Kan inte skriva till "$1".',
+			'errPerm'              : 'Tillstånd nekat.',
+			'errLocked'            : '"$1" är låst och kan inte döpas om, flyttas eller tas bort.',
+			'errExists'            : 'Fil med namn "$1" finns redan.',
+			'errInvName'           : 'Ogiltigt filnamn.',
+			'errFolderNotFound'    : 'Mappen hittades inte.',
+			'errFileNotFound'      : 'Filen hittades inte.',
+			'errTrgFolderNotFound' : 'Målmappen "$1" hittades inte.',
+			'errPopup'             : 'Webbläsaren hindrade popup-fönstret att öppnas. Ändra i webbläsarens inställningar för att kunna öppna filen.',
+			'errMkdir'             : 'Kan inte skapa mappen "$1".',
+			'errMkfile'            : 'Kan inte skapa filen "$1".',
+			'errRename'            : 'Kan inte döpa om "$1".',
+			'errCopyFrom'          : 'Kopiera filer från volym "$1" tillåts inte.',
+			'errCopyTo'            : 'Kopiera filer till volym "$1" tillåts inte.',
+			'errUploadCommon'      : 'Error vid uppladdningen.',
+			'errUpload'            : 'Kan inte ladda upp "$1".',
+			'errUploadNoFiles'     : 'Inga filer hittades för uppladdning.',
+			'errMaxSize'           : 'Data överskrider den högsta tillåtna storleken.',
+			'errFileMaxSize'       : 'Filen överskrider den högsta tillåtna storleken.',
+			'errUploadMime'        : 'Otillåten filtyp.',
+			'errUploadTransfer'    : '"$1" överföringsfel.', 
+			'errSave'              : 'Kan inte spara "$1".',
+			'errCopy'              : 'Kan inte kopiera "$1".',
+			'errMove'              : 'Kan inte flytta "$1".',
+			'errCopyInItself'      : 'Kan inte flytta "$1" till sig själv.',
+			'errRm'                : 'Kan inte ta bort "$1".',
+			'errExtract'           : 'Kan inte packa upp filen från "$1".',
+			'errArchive'           : 'Kan inte skapa arkiv.',
+			'errArcType'           : 'Arkivtypen stöds inte.',
+			'errNoArchive'         : 'Filen är inte av typen arkiv.',
+			'errCmdNoSupport'      : 'Backend stöder inte detta kommando.',
+			'errReplByChild'       : 'Mappen “$1” kan inte ersättas av ett objekt den innehåller.',
+			'errArcSymlinks'       : 'Av säkerhetsskäl nekas arkivet att packas upp då det innehåller symboliska länkar eller filer med ej tillåtna namn.', // edited 24.06.2012
+			'errArcMaxSize'        : 'Arkivfiler överskrider största tillåtna storlek.',
+			'errResize'            : 'Kan inte ändra storlek "$1".',
+			'errUsupportType'      : 'Filtypen stöds inte.',
+			'errNotUTF8Content'    : 'Filen "$1" är inte i UTF-8 och kan inte redigeras.',  // added 9.11.2011
+			'errNetMount'          : 'Kan inte koppla "$1".',     // added 17.04.2012
+			'errNetMountNoDriver'  : 'Protokollet stöds inte.',     // added 17.04.2012
+			'errNetMountFailed'    : 'Kopplingen misslyckades.',             // added 17.04.2012
+			'errNetMountHostReq'   : 'Host krävs.', // added 18.04.2012
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Skapa arkiv',
+			'cmdback'      : 'Tillbaka',
+			'cmdcopy'      : 'Kopiera',
+			'cmdcut'       : 'Klipp ut',
+			'cmddownload'  : 'Ladda ned',
+			'cmdduplicate' : 'Duplicera',
+			'cmdedit'      : 'Redigera fil',
+			'cmdextract'   : 'Extrahera filer från arkiv',
+			'cmdforward'   : 'Framåt',
+			'cmdgetfile'   : 'Välj filer',
+			'cmdhelp'      : 'Om denna programvara',
+			'cmdhome'      : 'Hem',
+			'cmdinfo'      : 'Visa info',
+			'cmdmkdir'     : 'Ny mapp',
+			'cmdmkfile'    : 'Ny textfil',
+			'cmdopen'      : 'Öpna',
+			'cmdpaste'     : 'Klistra in',
+			'cmdquicklook' : 'Förhandsgranska',
+			'cmdreload'    : 'Ladda om',
+			'cmdrename'    : 'Döp om',
+			'cmdrm'        : 'Radera',
+			'cmdsearch'    : 'Hitta filer',
+			'cmdup'        : 'Gå till överordnade katalog',
+			'cmdupload'    : 'Ladda upp filer',
+			'cmdview'      : 'Visa',
+			'cmdresize'    : 'Ändra bildstorlek',
+			'cmdsort'      : 'Sortera',
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : 'Stäng',
+			'btnSave'   : 'Spara',
+			'btnRm'     : 'Ta bort',
+			'btnApply'  : 'Verkställ',
+			'btnCancel' : 'Ångra',
+			'btnNo'     : 'Nej',
+			'btnYes'    : 'Ja',
+			
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Öppnar mapp',
+			'ntffile'     : 'Öppnar fil',
+			'ntfreload'   : 'Laddar om mappinnehållet',
+			'ntfmkdir'    : 'Skapar katalog',
+			'ntfmkfile'   : 'Skapar fil',
+			'ntfrm'       : 'Tar bort filer',
+			'ntfcopy'     : 'Kopierar filer',
+			'ntfmove'     : 'Flyttar filer',
+			'ntfprepare'  : 'Förbereder att flytta filer',
+			'ntfrename'   : 'Döper om filer',
+			'ntfupload'   : 'Laddar upp filer',
+			'ntfdownload' : 'Laddar ner filer',
+			'ntfsave'     : 'Sparar filer',
+			'ntfarchive'  : 'Skapar arkiv',
+			'ntfextract'  : 'Extraherar filer från arkiv',
+			'ntfsearch'   : 'Söker filer',
+			'ntfsmth'     : 'Gör någonting >_<',
+			'ntfloadimg'  : 'Laddar bild',
+			'ntfnetmount' : 'kopplar nätverksvolym', // added 18.04.2012
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : 'okänt',
+			'Today'       : 'Idag',
+			'Yesterday'   : 'Igår',
+			'Jan'         : 'Jan',
+			'Feb'         : 'Feb',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Apr',
+			'May'         : 'Maj',
+			'Jun'         : 'Jun',
+			'Jul'         : 'Jul',
+			'Aug'         : 'Aug',
+			'Sep'         : 'Sep',
+			'Oct'         : 'Okt',
+			'Nov'         : 'Nov',
+			'Dec'         : 'Dec',
+			'January'     : 'Januari',
+			'February'    : 'Februari',
+			'March'       : 'Mars',
+			'April'       : 'April',
+			'May'         : 'Maj',
+			'June'        : 'Juni',
+			'July'        : 'Juli',
+			'August'      : 'Augusti',
+			'September'   : 'September',
+			'October'     : 'Oktober',
+			'November'    : 'November',
+			'December'    : 'December',
+			'Sunday'      : 'Söndag', 
+			'Monday'      : 'Måndag', 
+			'Tuesday'     : 'Tisdag', 
+			'Wednesday'   : 'Onsdag', 
+			'Thursday'    : 'Torsdag', 
+			'Friday'      : 'Fredag', 
+			'Saturday'    : 'Lördag',
+			'Sun'         : 'Sön', 
+			'Mon'         : 'Mån', 
+			'Tue'         : 'Tis', 
+			'Wed'         : 'Ons', 
+			'Thu'         : 'Tor', 
+			'Fri'         : 'Fre', 
+			'Sat'         : 'Lör',
+			
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'namn (mappar först)', 
+			'sortkindDirsFirst' : 'efter sort (mappar först)', 
+			'sortsizeDirsFirst' : 'efter storlek (mappar först)', 
+			'sortdateDirsFirst' : 'efter datum (mappar först)',
+			'sortname'          : 'efter namn', 
+			'sortkind'          : 'efter sort', 
+			'sortsize'          : 'efter storlek',
+			'sortdate'          : 'efter datum',
+			'sortFoldersFirst'  : 'Mappar först', // added 22.06.2012
+			
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Bekräftelse krävs',
+			'confirmRm'       : 'Är du säker på att du vill ta bort filer? <br/> Detta kan inte ångras!',
+			'confirmRepl'     : 'Ersätt den gamla filen med en ny?',
+			'apllyAll'        : 'Använd för alla',
+			'name'            : 'Namn',
+			'size'            : 'Storlek',
+			'perms'           : 'Rättigheter',
+			'modify'          : 'Ändrad',
+			'kind'            : 'Sort',
+			'read'            : 'läs',
+			'write'           : 'skriv',
+			'noaccess'        : 'ingen åtkomst',
+			'and'             : 'och',
+			'unknown'         : 'okänd',
+			'selectall'       : 'Välj alla filer',
+			'selectfiles'     : 'Välj fil(er)',
+			'selectffile'     : 'Välj första filen',
+			'selectlfile'     : 'Välj sista filen',
+			'viewlist'        : 'Listvy',
+			'viewicons'       : 'Ikonvy',
+			'places'          : 'Platser',
+			'calc'            : 'Beräkna', 
+			'path'            : 'Sökväg',
+			'aliasfor'        : 'Alias för',
+			'locked'          : 'Låst',
+			'dim'             : 'Dimensioner',
+			'files'           : 'Filer',
+			'folders'         : 'Mappar',
+			'items'           : 'Objekt',
+			'yes'             : 'ja',
+			'no'              : 'nej',
+			'link'            : 'Länk',
+			'searcresult'     : 'Sökresultat',  
+			'selected'        : 'valda objekt',
+			'about'           : 'Om',
+			'shortcuts'       : 'Genväg',
+			'help'            : 'Hjälp',
+			'webfm'           : 'Webbfilhanterare',
+			'ver'             : 'Version',
+			'protocolver'     : 'protokolversion',
+			'homepage'        : 'Projekt hemsida',
+			'docs'            : 'Dokumentation',
+			'github'          : 'Forka oss på Github',
+			'twitter'         : 'Följ oss på twitter',
+			'facebook'        : 'Följ oss på facebook',
+			'team'            : 'Team',
+			'chiefdev'        : 'senior utvecklare',
+			'developer'       : 'utvecklare',
+			'contributor'     : 'bidragsgivare',
+			'maintainer'      : 'underhållare',
+			'translator'      : 'översättare',
+			'icons'           : 'Ikoner',
+			'dontforget'      : 'och glöm inte att ta med din handduk',
+			'shortcutsof'     : 'Genvägar avaktiverade',
+			'dropFiles'       : 'Släpp filerna här',
+			'or'              : 'eller',
+			'selectForUpload' : 'Välj filer att ladda upp',
+			'moveFiles'       : 'Flytta filer',
+			'copyFiles'       : 'Kopiera filer',
+			'rmFromPlaces'    : 'Ta bort från platser',
+			'untitled folder' : 'namnlös mapp',
+			'untitled file.txt' : 'namnlös fil.txt',
+			'aspectRatio'     : 'Aspekt ratio',
+			'scale'           : 'Skala',
+			'width'           : 'Bredd',
+			'height'          : 'Höjd',
+			'mode'            : 'Läge',
+			'resize'          : 'Ändra storlek',
+			'crop'            : 'Beskär',
+			'rotate'          : 'Rotera',
+			'rotate-cw'       : 'Rotera 90 grader medurs',
+			'rotate-ccw'      : 'Rotera 90 grader moturs',
+			'degree'          : 'Grader',
+			'netMountDialogTitle' : 'Koppla nätverksvolym', // added 18.04.2012
+			'protocol'            : 'Protokol', // added 18.04.2012
+			'host'                : 'Host', // added 18.04.2012
+			'port'                : 'Port', // added 18.04.2012
+			'user'                : 'användare', // added 18.04.2012
+			'pass'                : 'Lösenord', // added 18.04.2012
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Okänd',
+			'kindFolder'      : 'Mapp',
+			'kindAlias'       : 'Alias',
+			'kindAliasBroken' : 'Trasigt alias',
+			// applications
+			'kindApp'         : 'Applikation',
+			'kindPostscript'  : 'Postscript',
+			'kindMsOffice'    : 'Microsoft Office',
+			'kindMsWord'      : 'Microsoft Word',
+			'kindMsExcel'     : 'Microsoft Excel',
+			'kindMsPP'        : 'Microsoft Powerpoint',
+			'kindOO'          : 'Open Office',
+			'kindAppFlash'    : 'Flash',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent',
+			'kind7z'          : '7z',
+			'kindTAR'         : 'TAR',
+			'kindGZIP'        : 'GZIP',
+			'kindBZIP'        : 'BZIP',
+			'kindZIP'         : 'ZIP',
+			'kindRAR'         : 'RAR',
+			'kindJAR'         : 'Java JAR',
+			'kindTTF'         : 'True Type',
+			'kindOTF'         : 'Open Type',
+			'kindRPM'         : 'RPM',
+			// texts
+			'kindText'        : 'Text',
+			'kindTextPlain'   : 'Plain',
+			'kindPHP'         : 'PHP',
+			'kindCSS'         : 'Cascading style sheet',
+			'kindHTML'        : 'HTML',
+			'kindJS'          : 'Javascript',
+			'kindRTF'         : 'Rich Text Format',
+			'kindC'           : 'C',
+			'kindCHeader'     : 'C header',
+			'kindCPP'         : 'C++',
+			'kindCPPHeader'   : 'C++ header',
+			'kindShell'       : 'Unix shell script',
+			'kindPython'      : 'Python',
+			'kindJava'        : 'Java',
+			'kindRuby'        : 'Ruby',
+			'kindPerl'        : 'Perl',
+			'kindSQL'         : 'SQL',
+			'kindXML'         : 'XML',
+			'kindAWK'         : 'AWK',
+			'kindCSV'         : 'CSV',
+			'kindDOCBOOK'     : 'Docbook XML',
+			// images
+			'kindImage'       : 'Bild',
+			'kindBMP'         : 'BMP',
+			'kindJPEG'        : 'JPEG',
+			'kindGIF'         : 'GIF',
+			'kindPNG'         : 'PNG',
+			'kindTIFF'        : 'TIFF',
+			'kindTGA'         : 'TGA',
+			'kindPSD'         : 'Adobe Photoshop',
+			'kindXBITMAP'     : 'X bitmap',
+			'kindPXM'         : 'Pixelmator',
+			// media
+			'kindAudio'       : 'Audio media',
+			'kindAudioMPEG'   : 'MPEG audio',
+			'kindAudioMPEG4'  : 'MPEG-4 audio',
+			'kindAudioMIDI'   : 'MIDI audio',
+			'kindAudioOGG'    : 'Ogg Vorbis audio',
+			'kindAudioWAV'    : 'WAV audio',
+			'AudioPlaylist'   : 'MP3 playlist',
+			'kindVideo'       : 'Video media',
+			'kindVideoDV'     : 'DV movie',
+			'kindVideoMPEG'   : 'MPEG movie',
+			'kindVideoMPEG4'  : 'MPEG-4 movie',
+			'kindVideoAVI'    : 'AVI movie',
+			'kindVideoMOV'    : 'Quick Time movie',
+			'kindVideoWM'     : 'Windows Media movie',
+			'kindVideoFlash'  : 'Flash movie',
+			'kindVideoMKV'    : 'Matroska movie',
+			'kindVideoOGG'    : 'Ogg movie'
+		}
+	}
+}
+

+ 340 - 0
main/inc/lib/elfinder/js/i18n/elfinder.tr.js

@@ -0,0 +1,340 @@
+/**
+ * Turkish translation
+ * @author I.Taskinoglu & A.Kaya <alikaya@armsyazilim.com>
+ * @version 2012-06-15
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.tr = {
+		translator : 'I.Taskinoglu & A.Kaya &lt;alikaya@armsyazilim.com&gt;',
+		language   : 'Türkçe',
+		direction  : 'ltr',
+		dateFormat : 'd.m.Y H:i',
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+
+			/********************************** errors **********************************/
+			'error'                : 'Hata',
+			'errUnknown'           : 'Bilinmeyen hata.',
+			'errUnknownCmd'        : 'Bilinmeyen komut.',
+			'errJqui'              : 'Geçersiz Jquery configurasyonu.',
+			'errNode'              : 'DOM objesine ihtiyaç duyuluyor.',
+			'errURL'               : 'Geçersiz konfigurasyon, URL ayarlanmamış.',
+			'errAccess'            : 'Erişim yok.',
+			'errConnect'           : 'Sunucya bağlanamadı.',
+			'errAbort'             : 'Bağlantı kesildi.',
+			'errTimeout'           : 'Bağlantı zaman aşımına uğradı.',
+			'errNotFound'          : 'Sunucu bulunamadı.',
+			'errResponse'          : 'Sunucu cevabı geçersiz.',
+			'errConf'              : 'Sunucu ayarları geçersiz.',
+			'errJSON'              : 'PHP JSON modülü kurulmamış.',
+			'errNoVolumes'         : 'Okunabilir fiziksel disk yok.',
+			'errCmdParams'         : '"$1" komutu için geçersiz parametre.',
+			'errDataNotJSON'       : 'Veri JSON formatında değil.',
+			'errDataEmpty'         : 'Veri Boş.',
+			'errCmdReq'            : 'Sunucu isteği komut gerektiriyor.',
+			'errOpen'              : '"$1" açılamadı.',
+			'errNotFolder'         : 'Obje Klasör değil.',
+			'errNotFile'           : 'Obje Dosya değil.',
+			'errRead'              : '"$1" okunamadı.',
+			'errWrite'             : '"$1" Dosyasına yazılamadı.',
+			'errPerm'              : 'Yetki Yok.',                        
+			'errLocked'            : '"$1" dosyası kilitli olduğu için adı değiştirilemedi, taşındı veya silindi.',
+			'errExists'            : '"$1" adlı dosya var zaten.',
+			'errInvName'           : 'Geçersiz dosya adı.',
+			'errFolderNotFound'    : 'Dizin bulunamadı.',
+			'errFileNotFound'      : 'Dosya bulunamadı.',
+			'errTrgFolderNotFound' : 'Hedef klasör ["$1"] bulunamadı.',
+			'errPopup'             : 'İnternet gezgininiz açılır pencereleri engellememeli. Ayarlardan izin verip tekrar deneyin.',
+			'errMkdir'             : '"$1" dizin oluşturulamadı.',
+			'errMkfile'            : '"$1" dosya oluşturulamadı.',
+			'errRename'            : '"$1" adı değiştirilemedi.',
+			'errCopyFrom'          : '"$1" dizininden kopyalamaya izin verilmedi.',
+			'errCopyTo'            : '"$1" dizinine kopyalamaya izin verilmedi.',
+			'errUploadCommon'      : 'Dosya gönderme hatası.',
+			'errUpload'            : '"$1" dosya gönderilemedi.',
+			'errUploadNoFiles'     : 'Göndermek için dosya bulunamadı.',
+			'errMaxSize'           : 'Data izin verilen boyuttan büyük.',
+			'errFileMaxSize'       : 'Dosya izin verilen boyuttan büyük.',
+			'errUploadMime'        : 'Dosya tipine izin verilmiyor.',
+			'errUploadTransfer'    : '"$1" transfer hatası.', 
+			'errSave'              : '"$1" kaydedilemez.',
+			'errCopy'              : '"$1" kopylanamaz.',
+			'errMove'              : '"$1" taşınamaz.',
+			'errCopyInItself'      : '"$1" kendi içinde kopyalanamaz.',
+			'errRm'                : '"$1" silinemedi.',
+			'errExtract'           : '"$1" arşivi açılamadı.',
+			'errArchive'           : 'Arşiv oluşturulamadı.',
+			'errArcType'           : 'Desteklenmeyen Arşiv Tipi.',
+			'errNoArchive'         : 'Dosya arşiv değil veya desteklenmiyor.',
+			'errCmdNoSupport'      : 'Bu komut desteklenmiyor.',
+			'errReplByChild'       : 'Klasör “$1” içerdiği dosyadan dolayı değiştirilemedi',
+			'errArcSymlinks'       : 'Güvenlik nedeni ile arşiv açılamadı.',
+			'errArcMaxSize'        : 'Arşiv dosyası izin verilen maksimum boyutun üstünde.',
+			'errResize'            : 'Boyutlandırılamadı "$1".',
+			'errUsupportType'      : 'Desteklenmeyen Dosya Tipi.',
+
+			/******************************* commands names ********************************/
+			'cmdarchive'   : 'Arşiv Oluştur',
+			'cmdback'      : 'Geri',
+			'cmdcopy'      : 'Kopyala',
+			'cmdcut'       : 'Kes',
+			'cmddownload'  : 'İndir',
+			'cmdduplicate' : 'Dosyayı Çoğalt',
+			'cmdedit'      : 'Dosyayı Düzenle',
+			'cmdextract'   : 'Dosyaları Arşivden Çıkar',
+			'cmdforward'   : 'İleri',
+			'cmdgetfile'   : 'Dosyayı Seç',
+			'cmdhelp'      : 'elFinde Hakkında',
+			'cmdhome'      : 'Ana Sayfa',
+			'cmdinfo'      : 'Bilgi',
+			'cmdmkdir'     : 'Yeni Klasör',
+			'cmdmkfile'    : 'Yeni Boş Dosya',
+			'cmdopen'      : 'Aç',
+			'cmdpaste'     : 'Yapıştır',
+			'cmdquicklook' : 'Önizleme',
+			'cmdreload'    : 'Yenile',
+			'cmdrename'    : 'Adını Değiştir',
+			'cmdrm'        : 'Sil',
+			'cmdsearch'    : 'Dosya Ara',
+			'cmdup'        : 'Üst Klasöre Git',
+			'cmdupload'    : 'Dosya Gönder',
+			'cmdview'      : 'Aç',
+			'cmdresize'    : 'Resmi Yeniden Boyutlandır',
+			'cmdsort'      : 'Sırala',
+
+			/*********************************** buttons ***********************************/
+			'btnClose'  : 'Kapat',
+			'btnSave'   : 'Kaydet',
+			'btnRm'     : 'Sil',
+			'btnApply'  : 'Uygula',
+			'btnCancel' : 'Vazgeç',
+			'btnNo'     : 'Hayır',
+			'btnYes'    : 'Evet',
+
+			/******************************** notifications ********************************/
+			'ntfopen'     : 'Klasör Aç',
+			'ntffile'     : 'Dosya Aç',
+			'ntfreload'   : 'Klasörü Yenile',
+			'ntfmkdir'    : 'Klasör Oluşuturuluyor',
+			'ntfmkfile'   : 'Dosya Oluşturuluyor',
+			'ntfrm'       : 'Dosyaları Sil',
+			'ntfcopy'     : 'Dosyaları Kopyala',
+			'ntfmove'     : 'Dosyaları Taşı',
+			'ntfprepare'  : 'Kopyalamak için Hazırla',
+			'ntfrename'   : 'Dosyaları Adlandır',
+			'ntfupload'   : 'Dosyalar Yükleniyor',
+			'ntfdownload' : 'Dosyalar İndiriliyor',
+			'ntfsave'     : 'Dosyalar Kaydediliyor',
+			'ntfarchive'  : 'Arşiv Oluşturuluyor',
+			'ntfextract'  : 'Dosyalar Arşivde Çıkarılıyor',
+			'ntfsearch'   : 'Dosyalar Aranıyor',
+			'ntfsmth'     : 'Birşeyler Yapılıyor >_<',
+			'ntfloadimg'  : 'Resim Yükleniyor',
+
+			/************************************ dates **********************************/
+			'dateUnknown' : 'bilinmiyor',
+			'Today'       : 'Bugün',
+			'Yesterday'   : 'Dün',
+			'Jan'         : 'Oca',
+			'Feb'         : 'Şub',
+			'Mar'         : 'Mar',
+			'Apr'         : 'Nis',
+			'May'         : 'May',
+			'Jun'         : 'Haz',
+			'Jul'         : 'Tem',
+			'Aug'         : 'Ağu',
+			'Sep'         : 'Eyl',
+			'Oct'         : 'Ekm',
+			'Nov'         : 'Kas',
+			'Dec'         : 'Ara',
+			'January'     : 'Ocak',
+			'February'    : 'Şubat',
+			'March'       : 'Mart',
+			'April'       : 'Nisan',
+			'May'         : 'Mayıs',
+			'June'        : 'Haziran',
+			'July'        : 'Temmuz',
+			'August'      : 'Ağustos',
+			'September'   : 'Eylül',
+			'October'     : 'Ekim',
+			'November'    : 'Kasım',
+			'December'    : 'Aralık',
+			'Sunday'      : 'Pazar', 
+			'Monday'      : 'Pazartesi', 
+			'Tuesday'     : 'Salı', 
+			'Wednesday'   : 'Çarşamba', 
+			'Thursday'    : 'Perşembe', 
+			'Friday'      : 'Cuma', 
+			'Saturday'    : 'Cumartesi',
+			'Sun'         : 'Paz', 
+			'Mon'         : 'Pzt', 
+			'Tue'         : 'Sal', 
+			'Wed'         : 'Çar', 
+			'Thu'         : 'Per', 
+			'Fri'         : 'Cum', 
+			'Sat'         : 'Cmt',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : 'Ada göre (önce klasörler)', 
+			'sortkindDirsFirst' : 'Türe göre (önce klasörler)', 
+			'sortsizeDirsFirst' : 'Boyuta göre (önce klasörler)', 
+			'sortdateDirsFirst' : 'Tarihe göre (önce klasörler)', 
+			'sortname'          : 'Ada göre', 
+			'sortkind'          : 'Türe göre', 
+			'sortsize'          : 'Boyuta göre',
+			'sortdate'          : 'Tarihe göre',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : 'Onay gerekli',
+			'confirmRm'       : 'Dosyaları silmek istediğinize emin misiniz?<br/>Bu geri alınamaz!',
+			'confirmRepl'     : 'Eski dosyaları yenileriyle değiştir?',
+			'apllyAll'        : 'Tümünü uygula',
+			'name'            : 'Ad',
+			'size'            : 'Boyut',
+			'perms'           : 'Yetkiler',
+			'modify'          : 'Değiştildi',
+			'kind'            : 'Tür',
+			'read'            : 'oku',
+			'write'           : 'yaz',
+			'noaccess'        : 'yetki yok',
+			'and'             : 've',
+			'unknown'         : 'bilinmeyen',
+			'selectall'       : 'Tüm Dosyaları Seç',
+			'selectfiles'     : 'Dosyaları Seç',
+			'selectffile'     : 'İlk Dosyayı Seç',
+			'selectlfile'     : 'Son Dosyayı Seç',
+			'viewlist'        : 'Liste görünümü',
+			'viewicons'       : 'İkon görünümü',
+			'places'          : 'Klasörler',
+			'calc'            : 'Hesapla', 
+			'path'            : 'Dizin',
+			'aliasfor'        : 'Takma adı :',
+			'locked'          : 'Kilitli',
+			'dim'             : 'Ölçüler',
+			'files'           : 'Dosyalar',
+			'folders'         : 'Klasörler',
+			'items'           : 'Nesneler',
+			'yes'             : 'evet',
+			'no'              : 'hayır',
+			'link'            : 'Bağlantı',
+			'searcresult'     : 'Arama Sonuçları',  
+			'selected'        : 'Şeçili Nesne',
+			'about'           : 'Hakkında',
+			'shortcuts'       : 'Kısayollar',
+			'help'            : 'Yardım',
+			'webfm'           : 'Dosya Yöneticisi',
+			'ver'             : 'Versiyon',
+			'protocol'        : 'protocol versiyonu',
+			'homepage'        : 'Proje Ana Sayfası',
+			'docs'            : 'Yardım',
+			'github'          : 'Fork us on Github',
+			'twitter'         : 'twittwer da takip et',
+			'facebook'        : 'facebookda bize katıl',
+			'team'            : 'Takım',
+			'chiefdev'        : 'Yapımcı',
+			'developer'       : 'yapımcı',
+			'contributor'     : 'katkı',
+			'maintainer'      : 'geliştirici',
+			'translator'      : 'çeviri',
+			'icons'           : 'İkonlar',
+			'dontforget'      : 'Ve... havlunuzu almayı unutmayın',
+			'shortcutsof'     : 'Kısayollar Kapalı',
+			'dropFiles'       : 'Dosyaları buraya sürükleyin',
+			'or'              : 'veya',
+			'selectForUpload' : 'Yüklenecek Dosyaları Seçin',
+			'moveFiles'       : 'Dosyaları Taşı',
+			'copyFiles'       : 'Dosyaları Kopyala',
+			'rmFromPlaces'    : 'Klasörlerden Sil',
+			'untitled folder' : 'basliksiz_klasor',
+			'untitled file.txt' : 'basliksiz_dosya.txt',
+			'aspectRatio'     : 'Oran',
+			'scale'           : 'Ölçekle',
+			'width'           : 'Genişlik',
+			'height'          : 'Yükseklik',
+			'mode'            : 'Mod',
+			'resize'          : 'Boyutlandır',
+			'crop'            : 'Kes',
+			'rotate'          : 'Döndür',
+			'rotate-cw'       : '90 Derece Sağa Döndür',
+			'rotate-ccw'      : '90 Derece Sola Döndür',
+			'degree'          : 'Açı',
+
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : 'Bilinmiyor',
+			'kindFolder'      : 'Klasör',
+			'kindAlias'       : 'Takma Ad',
+			'kindAliasBroken' : 'Bozuk Takma Ad',
+			// applications
+			'kindApp'         : 'Uygulama',
+			'kindPostscript'  : 'Postscript Döküman',
+			'kindMsOffice'    : 'Microsoft Office Dökümanı',
+			'kindMsWord'      : 'Microsoft Word Dökümanı',
+			'kindMsExcel'     : 'Microsoft Excel Dökümanı',
+			'kindMsPP'        : 'Microsoft Powerpoint Sunum',
+			'kindOO'          : 'Open Office Dökümanı',
+			'kindAppFlash'    : 'Flash Uygulaması',
+			'kindPDF'         : 'Adobe Acrobat (PDF)',
+			'kindTorrent'     : 'Bittorrent dosyası',
+			'kind7z'          : '7z arşivi',
+			'kindTAR'         : 'TAR arşivi',
+			'kindGZIP'        : 'GZIP arşivi',
+			'kindBZIP'        : 'BZIP arşivi',
+			'kindZIP'         : 'ZIP arşivi',
+			'kindRAR'         : 'RAR arşivi',
+			'kindJAR'         : 'Java JAR dosyası',
+			'kindTTF'         : 'True Type font',
+			'kindOTF'         : 'Open Type font',
+			'kindRPM'         : 'RPM paketi',
+			// texts
+			'kindText'        : 'Text Dökümanı',
+			'kindTextPlain'   : 'Plain text',
+			'kindPHP'         : 'PHP dosyası',
+			'kindCSS'         : 'CSS dosyası',
+			'kindHTML'        : 'HTML dosyası',
+			'kindJS'          : 'Javascript dosyası',
+			'kindRTF'         : 'RTF dosyası',
+			'kindC'           : 'C dosyası',
+			'kindCHeader'     : 'C başlık dosyası',
+			'kindCPP'         : 'C++ dosyası',
+			'kindCPPHeader'   : 'C++ başlık dosyası',
+			'kindShell'       : 'Unix shell dosyası',
+			'kindPython'      : 'Python dosyası',
+			'kindJava'        : 'Java dosyası',
+			'kindRuby'        : 'Ruby dosyası',
+			'kindPerl'        : 'Perl dosyası',
+			'kindSQL'         : 'SQL dosyası',
+			'kindXML'         : 'XML dosyası',
+			'kindAWK'         : 'AWK dosyası',
+			'kindCSV'         : 'CSV dosyası',
+			'kindDOCBOOK'     : 'Docbook XML dosyası',
+			// images
+			'kindImage'       : 'Resim',
+			'kindBMP'         : 'BMP Resim',
+			'kindJPEG'        : 'JPEG Resim',
+			'kindGIF'         : 'GIF Resim',
+			'kindPNG'         : 'PNG Resim',
+			'kindTIFF'        : 'TIFF Resim',
+			'kindTGA'         : 'TGA Resim',
+			'kindPSD'         : 'Adobe Photoshop Resim',
+			'kindXBITMAP'     : 'X bitmap Resim',
+			'kindPXM'         : 'Pixelmator Resim',
+			// media
+			'kindAudio'       : 'Ses Dosyası',
+			'kindAudioMPEG'   : 'MPEG ses',
+			'kindAudioMPEG4'  : 'MPEG-4 ses',
+			'kindAudioMIDI'   : 'MIDI ses',
+			'kindAudioOGG'    : 'Ogg Vorbis ses',
+			'kindAudioWAV'    : 'WAV ses',
+			'AudioPlaylist'   : 'MP3 Çalma Listesi',
+			'kindVideo'       : 'Video Dosyası',
+			'kindVideoDV'     : 'DV video',
+			'kindVideoMPEG'   : 'MPEG video',
+			'kindVideoMPEG4'  : 'MPEG-4 video',
+			'kindVideoAVI'    : 'AVI video',
+			'kindVideoMOV'    : 'Quick Time video',
+			'kindVideoWM'     : 'Windows Media video',
+			'kindVideoFlash'  : 'Flash video',
+			'kindVideoMKV'    : 'Matroska video',
+			'kindVideoOGG'    : 'Ogg video'
+		}
+	}
+}

+ 340 - 0
main/inc/lib/elfinder/js/i18n/elfinder.vi.js

@@ -0,0 +1,340 @@
+/**
+ * Vietnamese translation
+ * @author Chung Thủy f <chungthuyf@gmail.com>
+ * @version 16-01-2013
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+  elFinder.prototype.i18.vi = {
+    translator : 'Chung Thủy f &lt;chungthuyf@gmail.com&gt;',
+    language : 'Ngôn ngữ Việt Nam',
+    direction : 'ltr',
+    dateFormat : 'd.m.Y H:i',
+    fancyDateFormat : '$1 H:i',
+    messages : {
+
+        /********************************** errors **********************************/
+        'error'                : 'Lỗi',
+        'errUnknown'           : 'Lỗi không xác định được.',
+        'errUnknownCmd'        : 'Lỗi không rõ lệnh.',
+        'errJqui'              : 'Invalid jQuery UI configuration. Selectable, draggable and droppable components must be included.',
+        'errNode'              : 'elFinder requires DOM Element to be created.',
+        'errURL'               : 'Cấu elFinder không hợp lệ! URL không được thiết lập tùy chọn.',
+        'errAccess'            : 'Truy cập bị từ chối.',
+        'errConnect'           : 'Unable to connect to backend.',
+        'errAbort'             : 'Kết nối bị hủy bỏ.',
+        'errTimeout'           : 'Connection timeout.',
+        'errNotFound'          : 'Backend not found.',
+        'errResponse'          : 'Invalid backend response.',
+        'errConf'              : 'Invalid backend configuration.',
+        'errJSON'              : 'PHP JSON module not installed.',
+        'errNoVolumes'         : 'Readable volumes not available.',
+        'errCmdParams'         : 'Invalid parameters for command "$1".',
+        'errDataNotJSON'       : 'Data is not JSON.',
+        'errDataEmpty'         : 'Data is empty.',
+        'errCmdReq'            : 'Backend request requires command name.',
+        'errOpen'              : 'Unable to open "$1".',
+        'errNotFolder'         : 'Object is not a folder.',
+        'errNotFile'           : 'Object is not a file.',
+        'errRead'              : 'Unable to read "$1".',
+        'errWrite'             : 'Unable to write into "$1".',
+        'errPerm'              : 'Permission denied.',
+        'errLocked'            : '"$1" is locked and can not be renamed, moved or removed.',
+        'errExists'            : 'File named "$1" already exists.',
+        'errInvName'           : 'Invalid file name.',
+        'errFolderNotFound'    : 'Folder not found.',
+        'errFileNotFound'      : 'File not found.',
+        'errTrgFolderNotFound' : 'Target folder "$1" not found.',
+        'errPopup'             : 'Browser prevented opening popup window. To open file enable it in browser options.',
+        'errMkdir'             : 'Unable to create folder "$1".',
+        'errMkfile'            : 'Unable to create file "$1".',
+        'errRename'            : 'Unable to rename "$1".',
+        'errCopyFrom'          : 'Copying files from volume "$1" not allowed.',
+        'errCopyTo'            : 'Copying files to volume "$1" not allowed.',
+        'errUploadCommon'      : 'Upload error.',
+        'errUpload'            : 'Unable to upload "$1".',
+        'errUploadNoFiles'     : 'No files found for upload.',
+        'errMaxSize'           : 'Data exceeds the maximum allowed size.',
+        'errFileMaxSize'       : 'File exceeds maximum allowed size.',
+        'errUploadMime'        : 'File type not allowed.',
+        'errUploadTransfer'    : '"$1" transfer error.', 
+        'errSave'              : 'Unable to save "$1".',
+        'errCopy'              : 'Unable to copy "$1".',
+        'errMove'              : 'Unable to move "$1".',
+        'errCopyInItself'      : 'Unable to copy "$1" into itself.',
+        'errRm'                : 'Unable to remove "$1".',
+        'errExtract'           : 'Unable to extract files from "$1".',
+        'errArchive'           : 'Unable to create archive.',
+        'errArcType'           : 'Unsupported archive type.',
+        'errNoArchive'         : 'File is not archive or has unsupported archive type.',
+        'errCmdNoSupport'      : 'Backend does not support this command.',
+        'errReplByChild'       : 'The folder “$1” can’t be replaced by an item it contains.',
+        'errArcSymlinks'       : 'For security reason denied to unpack archives contains symlinks.',
+        'errArcMaxSize'        : 'Archive files exceeds maximum allowed size.',
+        'errResize'            : 'Unable to resize "$1".',
+        'errUsupportType'      : 'Unsupported file type.',
+
+        /******************************* commands names ********************************/
+        'cmdarchive'   : 'Tạo tập tin nén',
+        'cmdback'      : 'Trở lại',
+        'cmdcopy'      : 'Sao chép',
+        'cmdcut'       : 'Cắt',
+        'cmddownload'  : 'Tải về',
+        'cmdduplicate' : 'Bản sao',
+        'cmdedit'      : 'Sửa tập tin',
+        'cmdextract'   : 'Giải nén tập tin',
+        'cmdforward'   : 'Trước',
+        'cmdgetfile'   : 'Chọn tập tin',
+        'cmdhelp'      : 'Giới thiệu phần mềm',
+        'cmdhome'      : 'Home',
+        'cmdinfo'      : 'Thông tin',
+        'cmdmkdir'     : 'Thư mục',
+        'cmdmkfile'    : 'Tạo tập tin Text',
+        'cmdopen'      : 'Mở',
+        'cmdpaste'     : 'Paste',
+        'cmdquicklook' : 'Xem trước',
+        'cmdreload'    : 'Nạp lại',
+        'cmdrename'    : 'Đổi tên',
+        'cmdrm'        : 'Xóa',
+        'cmdsearch'    : 'Tìm tập tin',
+        'cmdup'        : 'Go to parent directory',
+        'cmdupload'    : 'Tải tập tin lên',
+        'cmdview'      : 'Xem',
+        'cmdresize'    : 'Resize image',
+        'cmdsort'      : 'Sắp xếp',
+
+        /*********************************** buttons ***********************************/ 
+        'btnClose'  : 'Đóng',
+        'btnSave'   : 'Lưu',
+        'btnRm'     : 'Gỡ bỏ',
+        'btnApply'  : 'Áp dụng',
+        'btnCancel' : 'Hủy bỏ',
+        'btnNo'     : 'Không',
+        'btnYes'    : 'Đồng ý',
+
+        /******************************** notifications ********************************/
+        'ntfopen'     : 'Mở thư mục',
+        'ntffile'     : 'Mở tập tin',
+        'ntfreload'   : 'Nạp lại nội dung thư mục',
+        'ntfmkdir'    : 'Tạo thư mục',
+        'ntfmkfile'   : 'Tạo tập tin',
+        'ntfrm'       : 'Xóa tập tin',
+        'ntfcopy'     : 'Sao chép tập tin',
+        'ntfmove'     : 'Di chuyển tập tin',
+        'ntfprepare'  : 'Chuẩn bị để sao chép các tập tin',
+        'ntfrename'   : 'Đổi tên tập tin',
+        'ntfupload'   : 'Tải tập tin lên',
+        'ntfdownload' : 'Tải tập tin',
+        'ntfsave'     : 'Lưu tập tin',
+        'ntfarchive'  : 'Tạo tập tin nén',
+        'ntfextract'  : 'Giải nén tập tin',
+        'ntfsearch'   : 'Tìm kiếm tập tin',
+        'ntfsmth'     : 'Doing something >_<',
+        'ntfloadimg'  : 'Đang tải hình ảnh',
+
+        /************************************ dates **********************************/
+        'dateUnknown' : 'Chưa biết',
+        'Today'       : 'Hôm nay',
+        'Yesterday'   : 'Yesterday',
+        'Jan'         : 'Jan',
+        'Feb'         : 'Feb',
+        'Mar'         : 'Mar',
+        'Apr'         : 'Apr',
+        'May'         : 'May',
+        'Jun'         : 'Jun',
+        'Jul'         : 'Jul',
+        'Aug'         : 'Aug',
+        'Sep'         : 'Sep',
+        'Oct'         : 'Oct',
+        'Nov'         : 'Nov',
+        'Dec'         : 'Dec',
+        'January'     : 'January',
+        'February'    : 'February',
+        'March'       : 'March',
+        'April'       : 'April',
+        'May'         : 'May',
+        'June'        : 'June',
+        'July'        : 'July',
+        'August'      : 'August',
+        'September'   : 'September',
+        'October'     : 'October',
+        'November'    : 'November',
+        'December'    : 'December',
+        'Sunday'      : 'Sunday', 
+        'Monday'      : 'Monday', 
+        'Tuesday'     : 'Tuesday', 
+        'Wednesday'   : 'Wednesday', 
+        'Thursday'    : 'Thursday', 
+        'Friday'      : 'Friday', 
+        'Saturday'    : 'Saturday',
+        'Sun'         : 'Sun', 
+        'Mon'         : 'Mon', 
+        'Tue'         : 'Tue', 
+        'Wed'         : 'Wed', 
+        'Thu'         : 'Thu', 
+        'Fri'         : 'Fri', 
+        'Sat'         : 'Sat',
+        /******************************** sort variants ********************************/
+        'sortnameDirsFirst' : 'by name (folders first)', 
+        'sortkindDirsFirst' : 'by kind (folders first)', 
+        'sortsizeDirsFirst' : 'by size (folders first)', 
+        'sortdateDirsFirst' : 'by date (folders first)', 
+        'sortname'          : 'by name', 
+        'sortkind'          : 'by kind', 
+        'sortsize'          : 'by size',
+        'sortdate'          : 'by date',
+
+        /********************************** messages **********************************/
+        'confirmReq'      : 'Confirmation required',
+        'confirmRm'       : 'Are you sure you want to remove files?<br/>This cannot be undone!',
+        'confirmRepl'     : 'Replace old file with new one?',
+        'apllyAll'        : 'Apply to all',
+        'name'            : 'Name',
+        'size'            : 'Size',
+        'perms'           : 'Permissions',
+        'modify'          : 'Modified',
+        'kind'            : 'Kind',
+        'read'            : 'read',
+        'write'           : 'write',
+        'noaccess'        : 'no access',
+        'and'             : 'and',
+        'unknown'         : 'unknown',
+        'selectall'       : 'Select all files',
+        'selectfiles'     : 'Select file(s)',
+        'selectffile'     : 'Select first file',
+        'selectlfile'     : 'Select last file',
+        'viewlist'        : 'List view',
+        'viewicons'       : 'Icons view',
+        'places'          : 'Places',
+        'calc'            : 'Calculate', 
+        'path'            : 'Path',
+        'aliasfor'        : 'Alias for',
+        'locked'          : 'Locked',
+        'dim'             : 'Dimensions',
+        'files'           : 'Files',
+        'folders'         : 'Folders',
+        'items'           : 'Items',
+        'yes'             : 'yes',
+        'no'              : 'no',
+        'link'            : 'Link',
+        'searcresult'     : 'Search results',  
+        'selected'        : 'selected items',
+        'about'           : 'About',
+        'shortcuts'       : 'Shortcuts',
+        'help'            : 'Help',
+        'webfm'           : 'Web file manager',
+        'ver'             : 'Version',
+        'protocol'        : 'protocol version',
+        'homepage'        : 'Project home',
+        'docs'            : 'Documentation',
+        'github'          : 'Fork us on Github',
+        'twitter'         : 'Follow us on twitter',
+        'facebook'        : 'Join us on facebook',
+        'team'            : 'Team',
+        'chiefdev'        : 'chief developer',
+        'developer'       : 'developer',
+        'contributor'     : 'contributor',
+        'maintainer'      : 'maintainer',
+        'translator'      : 'translator',
+        'icons'           : 'Icons',
+        'dontforget'      : 'and don\'t forget to take your towel',
+        'shortcutsof'     : 'Shortcuts disabled',
+        'dropFiles'       : 'Drop files here',
+        'or'              : 'or',
+        'selectForUpload' : 'Select files to upload',
+        'moveFiles'       : 'Move files',
+        'copyFiles'       : 'Copy files',
+        'rmFromPlaces'    : 'Remove from places',
+        'untitled folder' : 'untitled folder',
+        'untitled file.txt' : 'untitled file.txt',
+        'aspectRatio'     : 'Aspect ratio',
+        'scale'           : 'Scale',
+        'width'           : 'Width',
+        'height'          : 'Height',
+        'mode'            : 'Mode',
+        'resize'          : 'Resize',
+        'crop'            : 'Crop',
+        'rotate'          : 'Rotate',
+        'rotate-cw'       : 'Rotate 90 degrees CW',
+        'rotate-ccw'      : 'Rotate 90 degrees CCW',
+        'degree'          : 'Degree',
+
+        /********************************** mimetypes **********************************/
+        'kindUnknown'     : 'Unknown',
+        'kindFolder'      : 'Folder',
+        'kindAlias'       : 'Alias',
+        'kindAliasBroken' : 'Broken alias',
+        // applications
+        'kindApp'         : 'Application',
+        'kindPostscript'  : 'Postscript document',
+        'kindMsOffice'    : 'Microsoft Office document',
+        'kindMsWord'      : 'Microsoft Word document',
+        'kindMsExcel'     : 'Microsoft Excel document',
+        'kindMsPP'        : 'Microsoft Powerpoint presentation',
+        'kindOO'          : 'Open Office document',
+        'kindAppFlash'    : 'Flash application',
+        'kindPDF'         : 'Portable Document Format (PDF)',
+        'kindTorrent'     : 'Bittorrent file',
+        'kind7z'          : '7z archive',
+        'kindTAR'         : 'TAR archive',
+        'kindGZIP'        : 'GZIP archive',
+        'kindBZIP'        : 'BZIP archive',
+        'kindZIP'         : 'ZIP archive',
+        'kindRAR'         : 'RAR archive',
+        'kindJAR'         : 'Java JAR file',
+        'kindTTF'         : 'True Type font',
+        'kindOTF'         : 'Open Type font',
+        'kindRPM'         : 'RPM package',
+        // texts
+        'kindText'        : 'Text document',
+        'kindTextPlain'   : 'Plain text',
+        'kindPHP'         : 'PHP source',
+        'kindCSS'         : 'Cascading style sheet',
+        'kindHTML'        : 'HTML document',
+        'kindJS'          : 'Javascript source',
+        'kindRTF'         : 'Rich Text Format',
+        'kindC'           : 'C source',
+        'kindCHeader'     : 'C header source',
+        'kindCPP'         : 'C++ source',
+        'kindCPPHeader'   : 'C++ header source',
+        'kindShell'       : 'Unix shell script',
+        'kindPython'      : 'Python source',
+        'kindJava'        : 'Java source',
+        'kindRuby'        : 'Ruby source',
+        'kindPerl'        : 'Perl script',
+        'kindSQL'         : 'SQL source',
+        'kindXML'         : 'XML document',
+        'kindAWK'         : 'AWK source',
+        'kindCSV'         : 'Comma separated values',
+        'kindDOCBOOK'     : 'Docbook XML document',
+        // images
+        'kindImage'       : 'Image',
+        'kindBMP'         : 'BMP image',
+        'kindJPEG'        : 'JPEG image',
+        'kindGIF'         : 'GIF Image',
+        'kindPNG'         : 'PNG Image',
+        'kindTIFF'        : 'TIFF image',
+        'kindTGA'         : 'TGA image',
+        'kindPSD'         : 'Adobe Photoshop image',
+        'kindXBITMAP'     : 'X bitmap image',
+        'kindPXM'         : 'Pixelmator image',
+        // media
+        'kindAudio'       : 'Audio media',
+        'kindAudioMPEG'   : 'MPEG audio',
+        'kindAudioMPEG4'  : 'MPEG-4 audio',
+        'kindAudioMIDI'   : 'MIDI audio',
+        'kindAudioOGG'    : 'Ogg Vorbis audio',
+        'kindAudioWAV'    : 'WAV audio',
+        'AudioPlaylist'   : 'MP3 playlist',
+        'kindVideo'       : 'Video media',
+        'kindVideoDV'     : 'DV movie',
+        'kindVideoMPEG'   : 'MPEG movie',
+        'kindVideoMPEG4'  : 'MPEG-4 movie',
+        'kindVideoAVI'    : 'AVI movie',
+        'kindVideoMOV'    : 'Quick Time movie',
+        'kindVideoWM'     : 'Windows Media movie',
+        'kindVideoFlash'  : 'Flash movie',
+        'kindVideoMKV'    : 'Matroska movie',
+        'kindVideoOGG'    : 'Ogg movie'
+    }
+  }
+}

+ 86 - 12
main/inc/lib/elfinder/js/i18n/elfinder.zh_CN.js

@@ -1,13 +1,16 @@
 /**
  * Simplified Chinese translation
- * @author 翻译者 <deerchao@gmail.com>
- * @version 2011-09-08
+ * @author deerchao <deerchao@gmail.com>
+ * @author Andy Hu <andyhu7@yahoo.com.hk>
+ * @version 2013-01-29
  */
 if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
 	elFinder.prototype.i18.zh_CN = {
-		translator : '翻译者 &lt;deerchao@gmail.com&gt;',
+		translator : '翻译者 deerchao &lt;deerchao@gmail.com&gt;, Andy Hu &lt;andyhu7@yahoo.com.hk&gt;',
 		language   : '简体中文',
 		direction  : 'ltr',
+		dateFormat : 'Y-m-d H:i',
+		fancyDateFormat : '$1 H:i',
 		messages   : {
 			
 			/********************************** errors **********************************/
@@ -48,24 +51,36 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'errRename'            : '不能重命名 "$1".',
 			'errCopyFrom'          : '不允许从卷 "$1" 复制.',
 			'errCopyTo'            : '不允许向卷 "$1" 复制.',
-			'errUploadCommon'      : '上传出错.',
-			'errUpload'            : '无法上传 "$1".',
+			'errUpload'            : '上传出错.',
+			'errUploadFile'        : '无法上传 "$1".',
 			'errUploadNoFiles'     : '未找到要上传的文件.',
-			'errMaxSize'           : '数据超过了允许的最大大小.',
-			'errFileMaxSize'       : '文件超过了允许的最大大小.',
+			'errUploadTotalSize'   : '数据超过了允许的最大大小.',
+			'errUploadFileSize'    : '文件超过了允许的最大大小.',
 			'errUploadMime'        : '不允许的文件类型.',
 			'errUploadTransfer'    : '"$1" 传输错误.', 
+			'errNotReplace'        : '对象 "$1" 已经在此位置存在, 不能被其他对象替换.', // new
+			'errReplace'           : '无法替换 "$1".',
 			'errSave'              : '无法保存 "$1".',
 			'errCopy'              : '无法复制 "$1".',
 			'errMove'              : '无法移动 "$1".',
 			'errCopyInItself'      : '不能移动 "$1" 到原有位置.',
 			'errRm'                : '无法删除 "$1".',
+			'errRmSrc'             : '不能删除源文件.',
 			'errExtract'           : '无法从 "$1" 提取文件.',
 			'errArchive'           : '无法创建压缩包.',
 			'errArcType'           : '不支持的压缩格式.',
 			'errNoArchive'         : '文件不是压缩包, 或者不支持该压缩格式.',
 			'errCmdNoSupport'      : '后端不支持该命令.',
-			
+			'errReplByChild'       : '文件夹 “$1” 不能被它所包含的项目替换.',
+			'errArcSymlinks'       : '出于安全上的考虑,不允许解压包含符号链接的压缩包.',
+			'errArcMaxSize'        : '压缩包文件超过最大允许文件大小范围.',
+			'errResize'            : '无法重新调整大小 "$1".',
+			'errUsupportType'      : '不被支持的文件格式.',
+			'errNotUTF8Content'    : '文件 "$1" 不是 UTF-8 格式, 不能编辑.',  // added 9.11.2011
+			'errNetMount'          : '无法装载 "$1".', // added 17.04.2012
+			'errNetMountNoDriver'  : '不支持该协议.',     // added 17.04.2012
+			'errNetMountFailed'    : '装载失败.',         // added 17.04.2012
+			'errNetMountHostReq'   : '需要指定主机.', // added 18.04.2012
 			/******************************* commands names ********************************/
 			'cmdarchive'   : '创建压缩包',
 			'cmdback'      : '后退',
@@ -92,15 +107,19 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'cmdup'        : '转到上一级文件夹',
 			'cmdupload'    : '上传文件',
 			'cmdview'      : '查看',
+			'cmdresize'    : '重新调整大小',
+			'cmdsort'      : '排序',
+			'cmdnetmount'  : '装载网络卷', // added 18.04.2012
 			
 			/*********************************** buttons ***********************************/ 
 			'btnClose'  : '关闭',
 			'btnSave'   : '保存',
 			'btnRm'     : '删除',
+			'btnApply'  : '应用',
 			'btnCancel' : '取消',
 			'btnNo'     : '否',
 			'btnYes'    : '是',
-			
+			'btnMount'  : '装载',  // added 18.04.2012
 			/******************************** notifications ********************************/
 			'ntfopen'     : '打开文件夹',
 			'ntffile'     : '打开文件',
@@ -118,7 +137,10 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'ntfarchive'  : '创建压缩包',
 			'ntfextract'  : '从压缩包提取文件',
 			'ntfsearch'   : '搜索文件',
+			'ntfresize'   : '正在更改尺寸',
 			'ntfsmth'     : '正在忙 >_<',
+			'ntfloadimg'  : '正在加载图片',
+      		'ntfnetmount' : '正在装载网络卷', // added 18.04.2012
 			
 			/************************************ dates **********************************/
 			'dateUnknown' : '未知',
@@ -136,6 +158,41 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'Oct'         : '十月',
 			'Nov'         : '十一月',
 			'Dec'         : '十二月',
+			'January'     : '一月',
+			'February'    : '二月',
+			'March'       : '三月',
+			'April'       : '四月',
+			'May'         : '五月',
+			'June'        : '六月',
+			'July'        : '七月',
+			'August'      : '八月',
+			'September'   : '九月',
+			'October'     : '十月',
+			'November'    : '十一月',
+			'December'    : '十二月',
+			'Sunday'      : '星期日',
+			'Monday'      : '星期一',
+			'Tuesday'     : '星期二',
+			'Wednesday'   : '星期三',
+			'Thursday'    : '星期四',
+			'Friday'      : '星期五',
+			'Saturday'    : '星期六',
+			'Sun'         : '周日', 
+			'Mon'         : '周一', 
+			'Tue'         : '周二', 
+			'Wed'         : '周三', 
+			'Thu'         : '周四', 
+			'Fri'         : '周五', 
+			'Sat'         : '周六',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : '按名称 (文件夹在最前)', 
+			'sortkindDirsFirst' : '按类型 (文件夹在最前)', 
+			'sortsizeDirsFirst' : '按大小 (文件夹在最前)', 
+			'sortdateDirsFirst' : '按日期 (文件夹在最前)', 
+			'sortname'          : '按名称', 
+			'sortkind'          : '按类型', 
+			'sortsize'          : '按大小',
+			'sortdate'          : '按日期',
 
 			/********************************** messages **********************************/
 			'confirmReq'      : '请确认',
@@ -177,7 +234,7 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'help'            : '帮助',
 			'webfm'           : '网络文件管理器',
 			'ver'             : '版本',
-			'protocol'        : '协议版本',
+			'protocolver'     : '协议版本',
 			'homepage'        : '项目主页',
 			'docs'            : '文档',
 			'github'          : 'Fork us on Github',
@@ -190,13 +247,30 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'maintainer'      : '维护',
 			'translator'      : '翻译',
 			'icons'           : '图标',
-			'dontforget'      : '别忘了带上你的毛巾',
+			'dontforget'      : '别忘了带上你擦汗的毛巾',
 			'shortcutsof'     : '快捷键已禁用',
 			'dropFiles'       : '把文件拖到这里',
 			'or'              : '或者',
 			'selectForUpload' : '选择要上传的文件',
 			'moveFiles'       : '移动文件',
 			'copyFiles'       : '复制文件',
+			'rmFromPlaces'    : '从位置中删除',
+			'untitled folder' : '未命名文件夹',
+			'untitled file.txt' : '未命名文件.txt',
+			'aspectRatio'     : '保持比例',
+			'scale'           : '高宽比',
+			'width'           : '宽',
+			'height'          : '高',
+			'mode'            : '模式',
+			'resize'          : '重新调整大小',
+			'crop'            : '裁切',
+			'rotate'          : '旋转',
+			'rotate-cw'       : '顺时针旋转90度',
+			'rotate-ccw'      : '逆时针旋转90度',
+			'degree'          : '度',
+			'port'            : '端口', // added 18.04.2012
+			'user'            : '用户', // added 18.04.2012
+			'pass'            : '密码', // added 18.04.2012
 			
 			/********************************** mimetypes **********************************/
 			'kindUnknown'     : '未知',
@@ -276,5 +350,5 @@ if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object'
 			'kindVideoMKV'    : 'Matroska 视频',
 			'kindVideoOGG'    : 'Ogg 视频'
 		}
-	};
+	}
 }

+ 353 - 0
main/inc/lib/elfinder/js/i18n/elfinder.zh_TW.js

@@ -0,0 +1,353 @@
+/**
+ * Traditional Chinese translation
+ * @author Yuwei Chuang <ywchuang.tw@gmail.com>
+ * @version 2013-05-07
+ */
+if (elFinder && elFinder.prototype && typeof(elFinder.prototype.i18) == 'object') {
+	elFinder.prototype.i18.zh_TW = {
+		translator : 'Yuwei Chuang &lt;ywchuang.tw@gmail.com&gt;',
+		language   : '正體中文',
+		direction  : 'ltr',
+		dateFormat : 'M d, Y h:i A', // Mar 13, 2012 05:27 PM
+		fancyDateFormat : '$1 H:i',
+		messages   : {
+			
+			/********************************** errors **********************************/
+			'error'                : '錯誤',
+			'errUnknown'           : '未知的錯誤.',
+			'errUnknownCmd'        : '未知的指令.',
+			'errJqui'              : '無效的 jQuery UI 設定. 必須包含 Selectable, draggable 以及 droppable 元件.',
+			'errNode'              : 'elFinder 需要能建立 DOM 元素.',
+			'errURL'               : '無效的 elFinder 設定! 尚未設定 URL 選項.',
+			'errAccess'            : '拒絕存取.',
+			'errConnect'           : '無法連線至後端.',
+			'errAbort'             : '連線中斷.',
+			'errTimeout'           : '連線逾時.',
+			'errNotFound'          : '後端不存在.',
+			'errResponse'          : '無效的後端回復.',
+			'errConf'              : '無效的後端設定.',
+			'errJSON'              : '未安裝 PHP JSON 模組.',
+			'errNoVolumes'         : '無可讀取的 volumes.',
+			'errCmdParams'         : '無效的參數, 指令: "$1".',
+			'errDataNotJSON'       : '資料不是 JSON 格式.',
+			'errDataEmpty'         : '沒有資料.',
+			'errCmdReq'            : '後端請求需要命令名稱.',
+			'errOpen'              : '無法打開 "$1".',
+			'errNotFolder'         : '非資料夾.',
+			'errNotFile'           : '非檔案.',
+			'errRead'              : '無法讀取 "$1".',
+			'errWrite'             : '無法寫入 "$1".',
+			'errPerm'              : '無權限.',
+			'errLocked'            : '"$1" 被鎖定,不能重新命名, 移動或删除.',
+			'errExists'            : '檔案 "$1" 已經存在了.',
+			'errInvName'           : '無效的檔案名稱.',
+			'errFolderNotFound'    : '未找到資料夾.',
+			'errFileNotFound'      : '未找到檔案.',
+			'errTrgFolderNotFound' : '未找到目標資料夾 "$1".',
+			'errPopup'             : '連覽器攔截了彈跳視窗. 請在瀏覽器選項允許彈跳視窗.',
+			'errMkdir'             : '不能建立資料夾 "$1".',
+			'errMkfile'            : '不能建立檔案 "$1".',
+			'errRename'            : '不能重新命名 "$1".',
+			'errCopyFrom'          : '不允許從 volume "$1" 複製.',
+			'errCopyTo'            : '不允複製到 volume "$1".',
+			'errUpload'            : '上船錯誤.',
+			'errUploadFile'        : '無法上傳 "$1".',
+			'errUploadNoFiles'     : '未找到要上傳的檔案.',
+			'errUploadTotalSize'   : '資料超過了最大允許大小.',
+			'errUploadFileSize'    : '檔案超過了最大允許大小.',
+			'errUploadMime'        : '不允許的檔案類型.',
+			'errUploadTransfer'    : '"$1" 傳輸錯誤.', 
+			'errNotReplace'        : '"$1" 已經存在此位置, 不能被其他的替换.', // new
+			'errReplace'           : '無法替换 "$1".',
+			'errSave'              : '無法保存 "$1".',
+			'errCopy'              : '無法複製 "$1".',
+			'errMove'              : '無法移動 "$1".',
+			'errCopyInItself'      : '無法移動 "$1" 到原有位置.',
+			'errRm'                : '無法删除 "$1".',
+			'errRmSrc'             : '無法删除來源檔案.',
+			'errExtract'           : '無法從 "$1" 解壓縮檔案.',
+			'errArchive'           : '無法建立壓縮膽案.',
+			'errArcType'           : '不支援的壓縮格式.',
+			'errNoArchive'         : '檔案不是壓縮檔案, 或者不支援該壓缩格式.',
+			'errCmdNoSupport'      : '後端不支援該指令.',
+			'errReplByChild'       : '資料夾 “$1” 不能被它所包含的檔案(資料夾)替换.',
+			'errArcSymlinks'       : '出于安全上的考量,禁止解壓縮檔案包含不允許的檔案名稱.',
+			'errArcMaxSize'        : '壓縮檔案超過最大允許檔案大小範圍.',
+			'errResize'            : '無法重新調整大小 "$1".',
+			'errUsupportType'      : '不支援的檔案格式.',
+			'errNotUTF8Content'    : '檔案 "$1" 不是 UTF-8 格式, 不能編輯.',  // added 9.11.2011
+			'errNetMount'          : '無法掛載 "$1".', // added 17.04.2012
+			'errNetMountNoDriver'  : '不支援該通訊協議.',     // added 17.04.2012
+			'errNetMountFailed'    : '掛載失敗.',         // added 17.04.2012
+			'errNetMountHostReq'   : '需要指定主機位置.', // added 18.04.2012
+			/******************************* commands names ********************************/
+			'cmdarchive'   : '建立壓縮檔案',
+			'cmdback'      : '後退',
+			'cmdcopy'      : '複製',
+			'cmdcut'       : '剪下',
+			'cmddownload'  : '下載',
+			'cmdduplicate' : '建立副本',
+			'cmdedit'      : '編輯檔案',
+			'cmdextract'   : '從壓縮檔案解壓縮',
+			'cmdforward'   : '前進',
+			'cmdgetfile'   : '選擇檔案',
+			'cmdhelp'      : '關於本軟體',
+			'cmdhome'      : '首頁',
+			'cmdinfo'      : '查看關於',
+			'cmdmkdir'     : '建立資料夾',
+			'cmdmkfile'    : '建立文字檔案',
+			'cmdopen'      : '打開',
+			'cmdpaste'     : '貼上',
+			'cmdquicklook' : '預覽',
+			'cmdreload'    : '更新',
+			'cmdrename'    : '重新命名',
+			'cmdrm'        : '删除',
+			'cmdsearch'    : '搜尋檔案',
+			'cmdup'        : '移到上一層資料夾',
+			'cmdupload'    : '上傳檔案',
+			'cmdview'      : '查看',
+			'cmdresize'    : '重新調整大小',
+			'cmdsort'      : '排序',
+			'cmdnetmount'  : '掛載 net volume', // added 18.04.2012
+			
+			/*********************************** buttons ***********************************/ 
+			'btnClose'  : '關閉',
+			'btnSave'   : '儲存',
+			'btnRm'     : '删除',
+			'btnApply'  : '使用',
+			'btnCancel' : '取消',
+			'btnNo'     : '否',
+			'btnYes'    : '是',
+			'btnMount'  : '掛載',  // added 18.04.2012
+			/******************************** notifications ********************************/
+			'ntfopen'     : '打開資料夾',
+			'ntffile'     : '打開檔案',
+			'ntfreload'   : '更新資料夾内容',
+			'ntfmkdir'    : '建立資料夾',
+			'ntfmkfile'   : '建立檔案',
+			'ntfrm'       : '删除檔案',
+			'ntfcopy'     : '複製檔案',
+			'ntfmove'     : '移動檔案',
+			'ntfprepare'  : '準備複製檔案',
+			'ntfrename'   : '重新命名檔案',
+			'ntfupload'   : '上傳檔案',
+			'ntfdownload' : '下載檔案',
+			'ntfsave'     : '儲存檔案',
+			'ntfarchive'  : '建立壓縮檔案',
+			'ntfextract'  : '從壓縮檔案解壓縮',
+			'ntfsearch'   : '搜尋檔案',
+			'ntfresize'   : '正在更改尺寸',
+			'ntfsmth'     : '正在忙 >_<',
+			'ntfloadimg'  : '正在讀取圖片',
+      		'ntfnetmount' : '正在掛載 net volume', // added 18.04.2012
+			
+			/************************************ dates **********************************/
+			'dateUnknown' : '未知',
+			'Today'       : '今天',
+			'Yesterday'   : '昨天',
+			'Jan'         : '一月',
+			'Feb'         : '二月',
+			'Mar'         : '三月',
+			'Apr'         : '四月',
+			'May'         : '五月',
+			'Jun'         : '六月',
+			'Jul'         : '七月',
+			'Aug'         : '八月',
+			'Sep'         : '九月',
+			'Oct'         : '十月',
+			'Nov'         : '十一月',
+			'Dec'         : '十二月',
+			'January'     : '一月',
+			'February'    : '二月',
+			'March'       : '三月',
+			'April'       : '四月',
+			'May'         : '五月',
+			'June'        : '六月',
+			'July'        : '七月',
+			'August'      : '八月',
+			'September'   : '九月',
+			'October'     : '十月',
+			'November'    : '十一月',
+			'December'    : '十二月',
+			'Sunday'      : '星期日',
+			'Monday'      : '星期一',
+			'Tuesday'     : '星期二',
+			'Wednesday'   : '星期三',
+			'Thursday'    : '星期四',
+			'Friday'      : '星期五',
+			'Saturday'    : '星期六',
+			'Sun'         : '周日', 
+			'Mon'         : '周一', 
+			'Tue'         : '周二', 
+			'Wed'         : '周三', 
+			'Thu'         : '周四', 
+			'Fri'         : '周五', 
+			'Sat'         : '周六',
+			/******************************** sort variants ********************************/
+			'sortnameDirsFirst' : '按名稱 (資料夾在最前)', 
+			'sortkindDirsFirst' : '按類型 (資料夾在最前)', 
+			'sortsizeDirsFirst' : '按大小 (資料夾在最前)', 
+			'sortdateDirsFirst' : '按日期 (資料夾在最前)', 
+			'sortname'          : '按名稱', 
+			'sortkind'          : '按類型', 
+			'sortsize'          : '按大小',
+			'sortdate'          : '按日期',
+
+			/********************************** messages **********************************/
+			'confirmReq'      : '請確認',
+			'confirmRm'       : '確定要删除檔案嗎?<br/>該操作不可回復!',
+			'confirmRepl'     : '用新的檔案替换原有檔案?',
+			'apllyAll'        : '全部使用',
+			'name'            : '名稱',
+			'size'            : '大小',
+			'perms'           : '權限',
+			'modify'          : '修改于',
+			'kind'            : '類別',
+			'read'            : '讀取',
+			'write'           : '寫入',
+			'noaccess'        : '無權限',
+			'and'             : '和',
+			'unknown'         : '未知',
+			'selectall'       : '選擇所有檔案',
+			'selectfiles'     : '選擇檔案',
+			'selectffile'     : '選擇第一個檔案',
+			'selectlfile'     : '選擇最後一個檔案',
+			'viewlist'        : '列表檢視',
+			'viewicons'       : '圖示檢視',
+			'places'          : '位置',
+			'calc'            : '計算', 
+			'path'            : '路徑',
+			'aliasfor'        : '别名',
+			'locked'          : '鎖定',
+			'dim'             : '尺寸',
+			'files'           : '檔案',
+			'folders'         : '資料夾',
+			'items'           : '項目',
+			'yes'             : '是',
+			'no'              : '否',
+			'link'            : '連結',
+			'searcresult'     : '搜尋结果',  
+			'selected'        : '選取的項目',
+			'about'           : '關於',
+			'shortcuts'       : '快捷鍵',
+			'help'            : '幫助',
+			'webfm'           : '網路檔案總管',
+			'ver'             : '版本',
+			'protocolver'     : '協定版本',
+			'homepage'        : '首頁',
+			'docs'            : '文件',
+			'github'          : 'Fork us on Github',
+			'twitter'         : 'Follow us on twitter',
+			'facebook'        : 'Join us on facebook',
+			'team'            : '團隊',
+			'chiefdev'        : '首席開發者',
+			'developer'       : '開發者',
+			'contributor'     : '貢獻者',
+			'maintainer'      : '維護者',
+			'translator'      : '翻譯',
+			'icons'           : '圖示',
+			'dontforget'      : '别忘了帶上你擦汗的毛巾',
+			'shortcutsof'     : '快捷鍵已禁用',
+			'dropFiles'       : '把檔案拖到此處',
+			'or'              : '或者',
+			'selectForUpload' : '選擇要上傳的檔案',
+			'moveFiles'       : '移動檔案',
+			'copyFiles'       : '複製檔案',
+			'rmFromPlaces'    : '從位置中删除',
+			'untitled folder' : '未命名資料夾',
+			'untitled file.txt' : '未命名檔案.txt',
+			'aspectRatio'     : '保持比例',
+			'scale'           : '寬高比',
+			'width'           : '寬',
+			'height'          : '高',
+			'mode'            : '模式',
+			'resize'          : '重新調整大小',
+			'crop'            : '裁切',
+			'rotate'          : '旋轉',
+			'rotate-cw'       : '順時針旋轉90度',
+			'rotate-ccw'      : '逆時針旋轉90度',
+			'degree'          : '度',
+			'port'            : '接口', // added 18.04.2012
+			'user'            : '使用者', // added 18.04.2012
+			'pass'            : '密碼', // added 18.04.2012
+			
+			/********************************** mimetypes **********************************/
+			'kindUnknown'     : '未知',
+			'kindFolder'      : '資料夾',
+			'kindAlias'       : '别名',
+			'kindAliasBroken' : '錯誤的别名',
+			// applications
+			'kindApp'         : '應用程式',
+			'kindPostscript'  : 'Postscript 文件',
+			'kindMsOffice'    : 'Microsoft Office 文件',
+			'kindMsWord'      : 'Microsoft Word 文件',
+			'kindMsExcel'     : 'Microsoft Excel 文件',
+			'kindMsPP'        : 'Microsoft Powerpoint 簡報',
+			'kindOO'          : 'Open Office 文件',
+			'kindAppFlash'    : 'Flash 應用程式',
+			'kindPDF'         : 'Portable Document Format (PDF)',
+			'kindTorrent'     : 'Bittorrent 檔案',
+			'kind7z'          : '7z 壓縮檔案',
+			'kindTAR'         : 'TAR 壓縮檔案',
+			'kindGZIP'        : 'GZIP 壓縮檔案',
+			'kindBZIP'        : 'BZIP 壓縮檔案',
+			'kindZIP'         : 'ZIP 壓縮檔案',
+			'kindRAR'         : 'RAR 壓縮檔案',
+			'kindJAR'         : 'Java JAR 檔案',
+			'kindTTF'         : 'True Type 字體',
+			'kindOTF'         : 'Open Type 字體',
+			'kindRPM'         : 'RPM 封裝',
+			// texts
+			'kindText'        : '文字檔案',
+			'kindTextPlain'   : '純文字',
+			'kindPHP'         : 'PHP 程式碼',
+			'kindCSS'         : 'CSS',
+			'kindHTML'        : 'HTML 文件',
+			'kindJS'          : 'Javascript 程式碼',
+			'kindRTF'         : '富文字格式(RTF)',
+			'kindC'           : 'C 程式碼',
+			'kindCHeader'     : 'C 標頭檔',
+			'kindCPP'         : 'C++ 程式碼',
+			'kindCPPHeader'   : 'C++ 標頭檔',
+			'kindShell'       : 'Unix Shell 脚本',
+			'kindPython'      : 'Python 程式碼',
+			'kindJava'        : 'Java 程式碼',
+			'kindRuby'        : 'Ruby 程式碼',
+			'kindPerl'        : 'Perl 程式碼',
+			'kindSQL'         : 'SQL 脚本',
+			'kindXML'         : 'XML 文件',
+			'kindAWK'         : 'AWK 程式碼',
+			'kindCSV'         : '逗號分隔值檔案(CSV)',
+			'kindDOCBOOK'     : 'Docbook XML 文件',
+			// images
+			'kindImage'       : '圖片',
+			'kindBMP'         : 'BMP 圖片',
+			'kindJPEG'        : 'JPEG 圖片',
+			'kindGIF'         : 'GIF 圖片',
+			'kindPNG'         : 'PNG 圖片',
+			'kindTIFF'        : 'TIFF 圖片',
+			'kindTGA'         : 'TGA 圖片',
+			'kindPSD'         : 'Adobe Photoshop 圖片',
+			'kindXBITMAP'     : 'X bitmap 圖片',
+			'kindPXM'         : 'Pixelmator 圖片',
+			// media
+			'kindAudio'       : '聲音',
+			'kindAudioMPEG'   : 'MPEG 聲音',
+			'kindAudioMPEG4'  : 'MPEG-4 聲音',
+			'kindAudioMIDI'   : 'MIDI 聲音',
+			'kindAudioOGG'    : 'Ogg Vorbis 聲音',
+			'kindAudioWAV'    : 'WAV 聲音',
+			'AudioPlaylist'   : 'MP3 播放列表',
+			'kindVideo'       : '影片',
+			'kindVideoDV'     : 'DV 影片',
+			'kindVideoMPEG'   : 'MPEG 影片',
+			'kindVideoMPEG4'  : 'MPEG-4 影片',
+			'kindVideoAVI'    : 'AVI 影片',
+			'kindVideoMOV'    : 'Quick Time 影片',
+			'kindVideoWM'     : 'Windows Media 影片',
+			'kindVideoFlash'  : 'Flash 影片',
+			'kindVideoMKV'    : 'Matroska 影片',
+			'kindVideoOGG'    : 'Ogg 影片'
+		}
+	}
+}

+ 1 - 1
main/inc/lib/elfinder/js/proxy/elFinderSupportVer1.js

@@ -46,7 +46,7 @@ window.elFinderSupportVer1 = function(upload) {
 			xhr;
 			
 		dfrd.abort = function() {
-			!xhr.isRejected() && !xhr.isResolved() && xhr.abort();
+			xhr.state() == 'pending' && xhr.abort();
 		}
 		
 		switch (cmd) {

+ 47 - 0
main/inc/lib/elfinder/php/connector.minimal.php

@@ -0,0 +1,47 @@
+<?php
+
+error_reporting(0); // Set E_ALL for debuging
+
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderConnector.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinder.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeDriver.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeLocalFileSystem.class.php';
+// Required for MySQL storage connector
+// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeMySQL.class.php';
+// Required for FTP connector support
+// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeFTP.class.php';
+
+
+/**
+ * Simple function to demonstrate how to control file access using "accessControl" callback.
+ * This method will disable accessing files/folders starting from '.' (dot)
+ *
+ * @param  string  $attr  attribute name (read|write|locked|hidden)
+ * @param  string  $path  file path relative to volume root directory started with directory separator
+ * @return bool|null
+ **/
+function access($attr, $path, $data, $volume) {
+	return strpos(basename($path), '.') === 0       // if file/folder begins with '.' (dot)
+		? !($attr == 'read' || $attr == 'write')    // set read+write to false, other (locked+hidden) set to true
+		:  null;                                    // else elFinder decide it itself
+}
+
+
+// Documentation for connector options:
+// https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options
+$opts = array(
+	// 'debug' => true,
+	'roots' => array(
+		array(
+			'driver'        => 'LocalFileSystem',   // driver for accessing file system (REQUIRED)
+			'path'          => '../files/',         // path to files (REQUIRED)
+			'URL'           => dirname($_SERVER['PHP_SELF']) . '/../files/', // URL to files (REQUIRED)
+			'accessControl' => 'access'             // disable and hide dot starting files (OPTIONAL)
+		)
+	)
+);
+
+// run elFinder
+$connector = new elFinderConnector(new elFinder($opts));
+$connector->run();
+

+ 47 - 0
main/inc/lib/elfinder/php/connector.php

@@ -0,0 +1,47 @@
+<?php
+
+error_reporting(0); // Set E_ALL for debuging
+
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderConnector.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinder.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeDriver.class.php';
+include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeLocalFileSystem.class.php';
+// Required for MySQL storage connector
+// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeMySQL.class.php';
+// Required for FTP connector support
+// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeFTP.class.php';
+
+
+/**
+ * Simple function to demonstrate how to control file access using "accessControl" callback.
+ * This method will disable accessing files/folders starting from '.' (dot)
+ *
+ * @param  string  $attr  attribute name (read|write|locked|hidden)
+ * @param  string  $path  file path relative to volume root directory started with directory separator
+ * @return bool|null
+ **/
+function access($attr, $path, $data, $volume) {
+	return strpos(basename($path), '.') === 0       // if file/folder begins with '.' (dot)
+		? !($attr == 'read' || $attr == 'write')    // set read+write to false, other (locked+hidden) set to true
+		:  null;                                    // else elFinder decide it itself
+}
+
+
+// Documentation for connector options:
+// https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options
+$opts = array(
+	// 'debug' => true,
+	'roots' => array(
+		array(
+			'driver'        => 'LocalFileSystem',   // driver for accessing file system (REQUIRED)
+			'path'          => '../files/',         // path to files (REQUIRED)
+			'URL'           => dirname($_SERVER['PHP_SELF']) . '/../files/', // URL to files (REQUIRED)
+			'accessControl' => 'access'             // disable and hide dot starting files (OPTIONAL)
+		)
+	)
+);
+
+// run elFinder
+$connector = new elFinderConnector(new elFinder($opts));
+$connector->run();
+

+ 504 - 39
main/inc/lib/elfinder/php/elFinder.class.php

@@ -25,6 +25,8 @@ class elFinder {
 	 **/
 	protected $volumes = array();
 
+	public static $netDrivers = array();
+
 	/**
 	 * Mounted volumes count
 	 * Required to create unique volume id
@@ -59,7 +61,7 @@ class elFinder {
 		'rename'    => array('target' => true, 'name' => true, 'mimes' => false),
 		'duplicate' => array('targets' => true, 'suffix' => false),
 		'paste'     => array('dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false),
-		'upload'    => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false),
+		'upload'    => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false),
 		'get'       => array('target' => true),
 		'put'       => array('target' => true, 'content' => '', 'mimes' => false),
 		'archive'   => array('targets' => true, 'type' => true, 'mimes' => false),
@@ -67,9 +69,17 @@ class elFinder {
 		'search'    => array('q' => true, 'mimes' => false),
 		'info'      => array('targets' => true),
 		'dim'       => array('target' => true),
-		'resize'    => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false)
+		'resize'    => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false),
+		'netmount'  => array('protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => true, 'pass' => true, 'alias' => false, 'options' => false)
 	);
 
+	/**
+	 * Plugins instance
+	 *
+	 * @var array
+	 **/
+	protected $plugins = array();
+
 	/**
 	 * Commands listeners
 	 *
@@ -96,6 +106,13 @@ class elFinder {
 	 **/
 	protected $debug = false;
 
+	/**
+	 * session expires timeout
+	 *
+	 * @var int
+	 **/
+	protected $timeout = 0;
+
 	/**
 	 * undocumented class variable
 	 *
@@ -157,6 +174,18 @@ class elFinder {
 	const ERROR_RESIZE            = 'errResize';
 	const ERROR_UNSUPPORT_TYPE    = 'errUsupportType';
 	const ERROR_NOT_UTF8_CONTENT  = 'errNotUTF8Content';
+	const ERROR_NETMOUNT          = 'errNetMount';
+	const ERROR_NETMOUNT_NO_DRIVER = 'errNetMountNoDriver';
+	const ERROR_NETMOUNT_FAILED       = 'errNetMountFailed';
+
+	const ERROR_SESSION_EXPIRES 	= 'errSessionExpires';
+
+	const ERROR_CREATING_TEMP_DIR 	= 'errCreatingTempDir';
+	const ERROR_FTP_DOWNLOAD_FILE 	= 'errFtpDownloadFile';
+	const ERROR_FTP_UPLOAD_FILE 	= 'errFtpUploadFile';
+	const ERROR_FTP_MKDIR 		= 'errFtpMkdir';
+	const ERROR_ARCHIVE_EXEC 	= 'errArchiveExec';
+	const ERROR_EXTRACT_EXEC 	= 'errExtractExec';
 
 	/**
 	 * Constructor
@@ -166,45 +195,82 @@ class elFinder {
 	 * @author Dmitry (dio) Levashov
 	 **/
 	public function __construct($opts) {
+		if (session_id() == '') {
+			session_start();
+		}
 
 		$this->time  = $this->utime();
 		$this->debug = (isset($opts['debug']) && $opts['debug'] ? true : false);
+		$this->timeout = (isset($opts['timeout']) ? $opts['timeout'] : 0);
 
 		setlocale(LC_ALL, !empty($opts['locale']) ? $opts['locale'] : 'en_US.UTF-8');
 
 		// bind events listeners
-
 		if (!empty($opts['bind']) && is_array($opts['bind'])) {
-			foreach ($opts['bind'] as $cmd => $handler) {
-				$this->bind($cmd, $handler);
+			$_req = $_SERVER["REQUEST_METHOD"] == 'POST' ? $_POST : $_GET;
+			$_reqCmd = isset($_req['cmd']) ? $_req['cmd'] : '';
+			foreach ($opts['bind'] as $cmd => $handlers) {
+				$doRegist = (strpos($cmd, '*') !== false);
+				if (! $doRegist) {
+					$_getcmd = create_function('$cmd', 'list($ret) = explode(\'.\', $cmd);return trim($ret);');
+					$doRegist = ($_reqCmd && in_array($_reqCmd, array_map($_getcmd, explode(' ', $cmd))));
+				}
+				if ($doRegist) {
+					if (! is_array($handlers) || is_object($handlers[0])) {
+						$handlers = array($handlers);
+					}
+					foreach($handlers as $handler) {
+						if ($handler) {
+							if (is_string($handler) && strpos($handler, '.')) {
+								list($_domain, $_name, $_method) = array_pad(explode('.', $handler), 3, '');
+								if (strcasecmp($_domain, 'plugin') === 0) {
+									if ($plugin = $this->getPluginInstance($_name, isset($opts['plugin'][$_name])? $opts['plugin'][$_name] : array())
+											and method_exists($plugin, $_method)) {
+										$this->bind($cmd, array($plugin, $_method));
+									}
+								}
+							} else {
+								$this->bind($cmd, $handler);
+							}
+						}
+					}
+				}
 			}
 		}
 
+		if (!isset($opts['roots']) || !is_array($opts['roots'])) {
+			$opts['roots'] = array();
+		}
+
+		// check for net volumes stored in session
+		foreach ($this->getNetVolumes() as $root) {
+			$opts['roots'][] = $root;
+		}
+
 		// "mount" volumes
-		if (isset($opts['roots']) && is_array($opts['roots'])) {
+		foreach ($opts['roots'] as $i => $o) {
+			$class = (isset($o['driver']) ? $o['driver'] : '');
 
-			foreach ($opts['roots'] as $i => $o) {
-				$class = 'elFinderVolume'.(isset($o['driver']) ? $o['driver'] : '');
+			if (class_exists($class)) {
 
-				if (class_exists($class)) {
-					$volume = new $class();
+				$volume = new $class();
 
-					if ($volume->mount($o)) {
-						// unique volume id (ends on "_") - used as prefix to files hash
-						$id = $volume->id();
+				if ($volume->mount($o)) {
+					// unique volume id (ends on "_") - used as prefix to files hash
+					$id = $volume->id();
 
-						$this->volumes[$id] = $volume;
-						if (!$this->default && $volume->isReadable()) {
-							$this->default = $this->volumes[$id];
-						}
-					} else {
-						$this->mountErrors[] = 'Driver "'.$class.'" : '.implode(' ', $volume->error());
+					$this->volumes[$id] = $volume;
+					if (!$this->default && $volume->isReadable()) {
+						$this->default = $this->volumes[$id];
 					}
 				} else {
-					$this->mountErrors[] = 'Driver "'.$class.'" does not exists';
+					$this->mountErrors[] = 'Driver "'.$class.'" : '.implode(' ', $volume->error());
 				}
+			} else {
+				$this->mountErrors[] = 'Driver "'.$class.'" does not exists';
 			}
 		}
+
 		// if at least one redable volume - ii desu >_<
 		$this->loaded = !empty($this->default);
 	}
@@ -238,18 +304,33 @@ class elFinder {
 	 * @author Dmitry (dio) Levashov
 	 **/
 	public function bind($cmd, $handler) {
-		$cmds = array_map('trim', explode(' ', $cmd));
+		$allCmds = array_keys($this->commands);
+		$cmds = array();
+		foreach(explode(' ', $cmd) as $_cmd) {
+			if ($_cmd !== '') {
+				if ($all = strpos($_cmd, '*') !== false) {
+					list(, $sub) = array_pad(explode('.', $_cmd), 2, '');
+					if ($sub) {
+						$sub = str_replace('\'', '\\\'', $sub);
+						$addSub = create_function('$cmd', 'return $cmd . \'.\' . trim(\'' . $sub . '\');');
+						$cmds = array_merge($cmds, array_map($addSub, $allCmds));
+					} else {
+						$cmds = array_merge($cmds, $allCmds);
+					}
+				} else {
+					$cmds[] = $_cmd;
+				}
+			}
+		}
+		$cmds = array_unique($cmds);
 
 		foreach ($cmds as $cmd) {
-			if ($cmd) {
-				if (!isset($this->listeners[$cmd])) {
-					$this->listeners[$cmd] = array();
-				}
+			if (!isset($this->listeners[$cmd])) {
+				$this->listeners[$cmd] = array();
+			}
 
-				if ((is_array($handler) && count($handler) == 2 && is_object($handler[0]) && method_exists($handler[0], $handler[1]))
-				|| function_exists($handler)) {
-					$this->listeners[$cmd][] = $handler;
-				}
+			if (is_callable($handler)) {
+				$this->listeners[$cmd][] = $handler;
 			}
 		}
 
@@ -298,6 +379,21 @@ class elFinder {
 		return $this->commandExists($cmd) ? $this->commands[$cmd] : array();
 	}
 
+	private function session_expires() {
+
+		if (!isset($_SESSION['LAST_ACTIVITY'])) {
+			$_SESSION['LAST_ACTIVITY'] = time();
+			return false;
+		}
+
+		if ( ($this->timeout > 0) && (time() - $_SESSION['LAST_ACTIVITY'] > $this->timeout) ) {
+			return true;
+		}
+
+		$_SESSION['LAST_ACTIVITY'] = time();
+		return false;
+	}
+
 	/**
 	 * Exec command and return result
 	 *
@@ -312,6 +408,10 @@ class elFinder {
 			return array('error' => $this->error(self::ERROR_CONF, self::ERROR_CONF_NO_VOL));
 		}
 
+		if ($this->session_expires()) {
+			return array('error' => $this->error(self::ERROR_SESSION_EXPIRES));
+		}
+
 		if (!$this->commandExists($cmd)) {
 			return array('error' => $this->error(self::ERROR_UNKNOWN_CMD));
 		}
@@ -322,6 +422,14 @@ class elFinder {
 			}
 		}
 
+		// call pre handlers for this command
+		if (!empty($this->listeners[$cmd.'.pre'])) {
+			$volume = isset($args['target'])? $this->volume($args['target']) : false;
+			foreach ($this->listeners[$cmd.'.pre'] as $handler) {
+				call_user_func_array($handler, array($cmd, &$args, $this, $volume));
+			}
+		}
+
 		$result = $this->$cmd($args);
 
 		if (isset($result['removed'])) {
@@ -334,8 +442,7 @@ class elFinder {
 		// call handlers for this command
 		if (!empty($this->listeners[$cmd])) {
 			foreach ($this->listeners[$cmd] as $handler) {
-				if ((is_array($handler) && $handler[0]->{$handler[1]}($cmd, $result, $args, $this))
-				||  (!is_array($handler) && $handler($cmd, $result, $args, $this))) {
+				if (call_user_func($handler,$cmd,$result,$args,$this)) {
 					// handler return true to force sync client after command completed
 					$result['sync'] = true;
 				}
@@ -396,6 +503,50 @@ class elFinder {
 		return $volume->realpath($hash);
 	}
 
+	/**
+	 * Return network volumes config.
+	 *
+	 * @return array
+	 * @author Dmitry (dio) Levashov
+	 */
+	protected function getNetVolumes() {
+		return isset($_SESSION['elFinderNetVolumes']) && is_array($_SESSION['elFinderNetVolumes']) ? $_SESSION['elFinderNetVolumes'] : array();
+	}
+
+	/**
+	 * Save network volumes config.
+	 *
+	 * @param  array  $volumes  volumes config
+	 * @return void
+	 * @author Dmitry (dio) Levashov
+	 */
+	protected function saveNetVolumes($volumes) {
+		$_SESSION['elFinderNetVolumes'] = $volumes;
+	}
+
+	/**
+	 * Get plugin instance & set to $this->plugins
+	 *
+	 * @param  string $name   Plugin name (dirctory name)
+	 * @param  array  $opts   Plugin options (optional)
+	 * @return object | bool Plugin object instance Or false
+	 * @author Naoki Sawada
+	 */
+	protected function getPluginInstance($name, $opts = array()) {
+		$key = strtolower($name);
+		if (! isset($this->plugins[$key])) {
+			$p_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'plugin.php';
+			if (is_file($p_file)) {
+				require_once $p_file;
+				$class = 'elFinderPlugin' . $name;
+				$this->plugins[$key] = new $class($opts);
+			} else {
+				$this->plugins[$key] = false;
+			}
+		}
+		return $this->plugins[$key];
+	}
+
 	/***************************************************************************/
 	/*                                 commands                                */
 	/***************************************************************************/
@@ -420,6 +571,47 @@ class elFinder {
 		return count($errors) ? $errors : array(self::ERROR_UNKNOWN);
 	}
 
+	protected function netmount($args) {
+		$options  = array();
+		$protocol = $args['protocol'];
+		$driver   = isset(self::$netDrivers[$protocol]) ? $protocol : '';
+		$class    = 'elfindervolume'.$protocol;
+
+		if (!$driver) {
+			return array('error' => $this->error(self::ERROR_NETMOUNT, $args['host'], self::ERROR_NETMOUNT_NO_DRIVER));
+		}
+
+		if (!$args['path']) {
+			$args['path'] = '/';
+		}
+
+		foreach ($args as $k => $v) {
+			if ($k != 'options' && $k != 'protocol' && $v) {
+				$options[$k] = $v;
+			}
+		}
+
+		if (is_array($args['options'])) {
+			foreach ($args['options'] as $key => $value) {
+				$options[$key] = $value;
+			}
+		}
+
+		$volume = new $class();
+
+		if ($volume->mount($options)) {
+			$netVolumes        = $this->getNetVolumes();
+			$options['driver'] = $driver;
+			$netVolumes[]      = $options;
+			$netVolumes        = array_unique($netVolumes);
+			$this->saveNetVolumes($netVolumes);
+			return array('sync' => true);
+		} else {
+			return array('error' => $this->error(self::ERROR_NETMOUNT, $args['host'], implode(' ', $volume->error())));
+		}
+
+	}
+
 	/**
 	 * "Open" directory
 	 * Return array with following elements
@@ -461,7 +653,6 @@ class elFinder {
 		// get folders trees
 		if ($args['tree']) {
 			foreach ($this->volumes as $id => $v) {
-
 				if (($tree = $v->tree('', 0, $cwd['hash'])) != false) {
 					$files = array_merge($files, $tree);
 				}
@@ -488,6 +679,8 @@ class elFinder {
 		if (!empty($args['init'])) {
 			$result['api'] = $this->version;
 			$result['uplMaxSize'] = ini_get('upload_max_filesize');
+			$result['uplMaxFile'] = ini_get('max_file_uploads');
+			$result['netDrivers'] = array_keys(self::$netDrivers);
 		}
 
 		return $result;
@@ -614,6 +807,8 @@ class elFinder {
 			$ua = $_SERVER["HTTP_USER_AGENT"];
 			if (preg_match('/MSIE [4-8]/', $ua)) { // IE < 9 do not support RFC 6266 (RFC 2231/RFC 5987)
 				$filename = 'filename="'.$filenameEncoded.'"';
+			} elseif (strpos($ua, 'Chrome') === false && strpos($ua, 'Safari') !== false) { // Safari
+				$filename = 'filename="'.str_replace('"', '', $file['name']).'"';
 			} else { // RFC 6266 (RFC 2231/RFC 5987)
 				$filename = 'filename*=UTF-8\'\''.$filenameEncoded;
 			}
@@ -774,6 +969,198 @@ class elFinder {
 		return $result;
 	}
 
+	/**
+	* Get remote contents
+	*
+	* @param  string  $url     target url
+	* @param  int     $timeout timeout (sec)
+	* @param  int     $redirect_max redirect max count
+	* @param  string  $ua
+	* @return string or bool(false)
+	* @retval string contents
+	* @retval false  error
+	* @author Naoki Sawada
+	**/
+	protected function get_remote_contents( $url, $timeout = 30, $redirect_max = 5, $ua = 'Mozilla/5.0' ) {
+		$method = (function_exists('curl_exec') && !ini_get('safe_mode'))? 'curl_get_contents' : 'fsock_get_contents';
+		return $this->$method( $url, $timeout, $redirect_max, $ua );
+	}
+
+	/**
+	 * Get remote contents with cURL
+	 *
+	 * @param  string  $url     target url
+	 * @param  int     $timeout timeout (sec)
+	 * @param  int     $redirect_max redirect max count
+	 * @param  string  $ua
+	 * @return string or bool(false)
+	 * @retval string contents
+	 * @retval false  error
+	 * @author Naoki Sawada
+	 **/
+	 protected function curl_get_contents( $url, $timeout, $redirect_max, $ua ){
+		$ch = curl_init();
+		curl_setopt( $ch, CURLOPT_URL, $url );
+		curl_setopt( $ch, CURLOPT_HEADER, false );
+		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
+		curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
+		curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
+		curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
+		curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
+		curl_setopt( $ch, CURLOPT_MAXREDIRS, $redirect_max);
+		curl_setopt( $ch, CURLOPT_USERAGENT, $ua);
+		$result = curl_exec( $ch );
+		curl_close( $ch );
+		return $result;
+	}
+
+	/**
+	 * Get remote contents with fsockopen()
+	 *
+	 * @param  string  $url          url
+	 * @param  int     $timeout      timeout (sec)
+	 * @param  int     $redirect_max redirect max count
+	 * @param  string  $ua
+	 * @return string or bool(false)
+	 * @retval string contents
+	 * @retval false  error
+	 * @author Naoki Sawada
+	 */
+	protected function fsock_get_contents( $url, $timeout, $redirect_max, $ua ) {
+
+		$connect_timeout = 3;
+		$connect_try = 3;
+		$method = 'GET';
+		$readsize = 4096;
+
+		$getSize = null;
+		$headers = '';
+
+		$arr = parse_url($url);
+		if (!$arr){
+			// Bad request
+			return false;
+		}
+
+		// query
+		$arr['query'] = isset($arr['query']) ? '?'.$arr['query'] : '';
+		// port
+		$arr['port'] = isset($arr['port']) ? $arr['port'] : (!empty($arr['https'])? 443 : 80);
+
+		$url_base = $arr['scheme'].'://'.$arr['host'].':'.$arr['port'];
+		$url_path = isset($arr['path']) ? $arr['path'] : '/';
+		$uri = $url_path.$arr['query'];
+
+		$query = $method.' '.$uri." HTTP/1.0\r\n";
+		$query .= "Host: ".$arr['host']."\r\n";
+		if (!empty($ua)) $query .= "User-Agent: ".$ua."\r\n";
+		if (!is_null($getSize)) $query .= 'Range: bytes=0-' . ($getSize - 1) . "\r\n";
+
+		$query .= $headers;
+
+		$query .= "\r\n";
+
+		$fp = $connect_try_count = 0;
+		while( !$fp && $connect_try_count < $connect_try ) {
+
+			$errno = 0;
+			$errstr = "";
+			$fp = @ fsockopen(
+			$arr['https'].$arr['host'],
+			$arr['port'],
+			$errno,$errstr,$connect_timeout);
+			if ($fp) break;
+			$connect_try_count++;
+			if (connection_aborted()) {
+				exit();
+			}
+			sleep(1); // wait 1sec
+		}
+
+		$fwrite = 0;
+		for ($written = 0; $written < strlen($query); $written += $fwrite) {
+			$fwrite = fwrite($fp, substr($query, $written));
+			if (!$fwrite) {
+				break;
+			}
+		}
+
+		$response = '';
+
+		if ($timeout) {
+			socket_set_timeout($fp, $timeout);
+		}
+
+		$_response = true;
+		while ($_response && (is_null($getSize) || strlen($response) < $getSize)) {
+			if (connection_aborted()) {
+				exit();
+			}
+			if ($_response = fread($fp, $readsize)) {
+				$response .= $_response;
+			}
+		}
+
+		if ($timeout) {
+			$_status = socket_get_status($fp);
+			if ($_status['timed_out']) {
+				fclose($fp);
+				return false; // Request Time-out
+			}
+		}
+
+		fclose($fp);
+
+		$resp = array_pad(explode("\r\n\r\n",$response,2), 2, '');
+		$rccd = array_pad(explode(' ',$resp[0],3), 3, ''); // array('HTTP/1.1','200','OK\r\n...')
+		$rc = (int)$rccd[1];
+
+		// Redirect
+		switch ($rc) {
+			case 307: // Temporary Redirect
+			case 303: // See Other
+			case 302: // Moved Temporarily
+			case 301: // Moved Permanently
+				$matches = array();
+				if (preg_match('/^Location: (.+?)(#.+)?$/im',$resp[0],$matches) && --$redirect_max > 0) {
+					$url = trim($matches[1]);
+					$hash = isset($matches[2])? trim($matches[2]) : '';
+					if (!preg_match('/^https?:\//',$url)) { // no scheme
+						if ($url{0} != '/') { // Relative path
+							// to Absolute path
+							$url = substr($url_path,0,strrpos($url_path,'/')).'/'.$url;
+						}
+						// add sheme,host
+						$url = $url_base.$url;
+					}
+					return $this->fsock_get_contents( $url, $timeout, $redirect_max, $ua );
+				}
+		}
+
+		return $resp[1]; // Data
+	}
+
+	/**
+	 * Parse Data URI scheme
+	 *
+	 * @param  string $str
+	 * @param  array  $extTable
+	 * @return array
+	 * @author Naoki Sawada
+	 */
+	protected function parse_data_scheme( $str, $extTable ) {
+		$data = $name = '';
+		if ($fp = fopen('data://'.substr($str, 5), 'rb')) {
+			if ($data = stream_get_contents($fp)) {
+				$meta = stream_get_meta_data($fp);
+				$ext = isset($extTable[$meta['mediatype']])? '.' . $extTable[$meta['mediatype']] : '';
+				$name = substr(md5($data), 0, 8) . $ext;
+			}
+			fclose($fp);
+		}
+		return array($data, $name);
+	}
+
 	/**
 	 * Save uploaded files
 	 *
@@ -786,15 +1173,62 @@ class elFinder {
 		$volume = $this->volume($target);
 		$files  = isset($args['FILES']['upload']) && is_array($args['FILES']['upload']) ? $args['FILES']['upload'] : array();
 		$result = array('added' => array(), 'header' => empty($args['html']) ? false : 'Content-Type: text/html; charset=utf-8');
-
-		if (empty($files)) {
-			return array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_UPLOAD_NO_FILES), 'header' => $header);
-		}
+		$paths = $args['upload_path']? $args['upload_path'] : array();
 
 		if (!$volume) {
 			return array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target), 'header' => $header);
 		}
 
+		// file extentions table by MIME
+		$extTable = array_flip($volume->getMimeTable());
+
+		$non_uploads = array();
+		if (empty($files)) {
+			if (isset($args['upload']) && is_array($args['upload'])) {
+				foreach($args['upload'] as $i => $url) {
+					// check is data:
+					if (substr($url, 0, 5) === 'data:') {
+						list($data, $args['name'][$i]) = $this->parse_data_scheme($url, $extTable);
+					} else {
+						$data = $this->get_remote_contents($url);
+					}
+					if ($data) {
+						$_name = isset($args['name'][$i])? $args['name'][$i] : preg_replace('~^.*?([^/#?]+)(?:\?.*)?(?:#.*)?$~', '$1', rawurldecode($url));
+						if ($_name) {
+							$_ext = '';
+							if (preg_match('/(\.[a-z0-9]{1,7})$/', $_name, $_match)) {
+								$_ext = $_match[1];
+							}
+							$tmpfname = DIRECTORY_SEPARATOR . 'ELF_FATCH_' . md5($url.microtime()) . $_ext;
+							$tmpPath = sys_get_temp_dir();
+							if (! @ touch($tmpPath . $tmpfname)) {
+								if ($tmpPath = $volume->getTempPath()) {
+									$tmpfname = $tmpPath . $tmpfname;
+								} else {
+									$tmpfname = '';
+								}
+							} else {
+								$tmpfname = $tmpPath . $tmpfname;
+							}
+							if ($tmpfname) {
+								if (file_put_contents($tmpfname, $data)) {
+									$non_uploads[$tmpfname] = true;
+									$files['tmp_name'][$i] = $tmpfname;
+									$files['name'][$i] = preg_replace('/[\/\\?*:|"<>]/', '_', $_name);
+									$files['error'][$i] = 0;
+								} else {
+									@ unlink($tmpfname);
+								}
+							}
+						}
+					}
+				}
+			}
+			if (empty($files)) {
+				return array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_UPLOAD_NO_FILES), 'header' => $header);
+			}
+		}
+
 		foreach ($files['name'] as $i => $name) {
 			if (($error = $files['error'][$i]) > 0) {
 				$result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $error == UPLOAD_ERR_INI_SIZE || $error == UPLOAD_ERR_FORM_SIZE ? self::ERROR_UPLOAD_FILE_SIZE : self::ERROR_UPLOAD_TRANSFER);
@@ -803,23 +1237,54 @@ class elFinder {
 			}
 
 			$tmpname = $files['tmp_name'][$i];
+			$path = ($paths && !empty($paths[$i]))? $paths[$i] : '';
+			if ($name === 'blob') {
+				// for form clipboard with Google Chrome
+				$type = $files['type'][$i];
+				$ext = isset($extTable[$type])? '.' . $extTable[$type] : '';
+				$name = substr(md5(basename($tmpname)), 0, 8) . $ext;
+			}
+
+			// do hook function 'upload.presave'
+			if (! empty($this->listeners['upload.presave'])) {
+				foreach($this->listeners['upload.presave'] as $handler) {
+					call_user_func_array($handler, array(&$path, &$name, $tmpname, $this, $volume));
+				}
+			}
 
 			if (($fp = fopen($tmpname, 'rb')) == false) {
 				$result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, self::ERROR_UPLOAD_TRANSFER);
 				$this->uploadDebug = 'Upload error: unable open tmp file';
+				if (! is_uploaded_file($tmpname)) {
+					if (@ unlink($tmpname)) unset($non_uploads[$tmpfname]);
+					continue;
+				}
 				break;
 			}
-
-			if (($file = $volume->upload($fp, $target, $name, $tmpname)) === false) {
+			if ($path) {
+				$_target = $volume->getUploadTaget($target, $path, $result);
+			} else {
+				$_target = $target;
+			}
+			if (! $_target || ($file = $volume->upload($fp, $_target, $name, $tmpname)) === false) {
 				$result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $volume->error());
 				fclose($fp);
+				if (! is_uploaded_file($tmpname)) {
+					if (@ unlink($tmpname)) unset($non_uploads[$tmpfname]);;
+					continue;
+				}
 				break;
 			}
 
 			fclose($fp);
+			if (! is_uploaded_file($tmpname) && @ unlink($tmpname)) unset($non_uploads[$tmpfname]);
 			$result['added'][] = $file;
 		}
-
+		if ($non_uploads) {
+			foreach(array_keys($non_uploads) as $_temp) {
+				@ unlink($_temp);
+			}
+		}
 		return $result;
 	}
 

File diff suppressed because it is too large
+ 201 - 139
main/inc/lib/elfinder/php/elFinderVolumeDriver.class.php


+ 1418 - 0
main/inc/lib/elfinder/php/elFinderVolumeFTP.class.php

@@ -0,0 +1,1418 @@
+<?php
+
+function chmodnum($chmod) {
+    $trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
+    $chmod = substr(strtr($chmod, $trans), 1);
+    $array = str_split($chmod, 3);
+    return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
+}
+
+elFinder::$netDrivers['ftp'] = 'FTP';
+
+/**
+ * Simple elFinder driver for FTP
+ *
+ * @author Dmitry (dio) Levashov
+ * @author Cem (discofever)
+ **/
+class elFinderVolumeFTP extends elFinderVolumeDriver {
+	
+	/**
+	 * Driver id
+	 * Must be started from letter and contains [a-z0-9]
+	 * Used as part of volume id
+	 *
+	 * @var string
+	 **/
+	protected $driverId = 'f';
+	
+	/**
+	 * FTP Connection Instance
+	 *
+	 * @var ftp
+	 **/
+	protected $connect = null;
+	
+	/**
+	 * Directory for tmp files
+	 * If not set driver will try to use tmbDir as tmpDir
+	 *
+	 * @var string
+	 **/
+	protected $tmpPath = '';
+	
+	/**
+	 * Last FTP error message
+	 *
+	 * @var string
+	 **/
+	protected $ftpError = '';
+	
+	/**
+	 * FTP server output list as ftp on linux
+	 *
+	 * @var bool
+	 **/
+	protected $ftpOsUnix;
+	
+	/**
+	 * Tmp folder path
+	 *
+	 * @var string
+	 **/
+	protected $tmp = '';
+	
+	/**
+	 * Constructor
+	 * Extend options with required fields
+	 *
+	 * @return void
+	 * @author Dmitry (dio) Levashov
+	 * @author Cem (DiscoFever)
+	 **/
+	public function __construct() {
+		$opts = array(
+			'host'          => 'localhost',
+			'user'          => '',
+			'pass'          => '',
+			'port'          => 21,
+			'mode'        	=> 'passive',
+			'path'			=> '/',
+			'timeout'		=> 20,
+			'owner'         => true,
+			'tmbPath'       => '',
+			'tmpPath'       => '',
+			'dirMode'       => 0755,
+			'fileMode'      => 0644
+		);
+		$this->options = array_merge($this->options, $opts); 
+		$this->options['mimeDetect'] = 'internal';
+	}
+	
+	/*********************************************************************/
+	/*                        INIT AND CONFIGURE                         */
+	/*********************************************************************/
+	
+	/**
+	 * Prepare FTP connection
+	 * Connect to remote server and check if credentials are correct, if so, store the connection id in $ftp_conn
+	 *
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 * @author Cem (DiscoFever)
+	 **/
+	protected function init() {
+		if (!$this->options['host'] 
+		||  !$this->options['user'] 
+		||  !$this->options['pass'] 
+		||  !$this->options['port']) {
+			return $this->setError('Required options undefined.');
+		}
+		
+		if (!function_exists('ftp_connect')) {
+			return $this->setError('FTP extension not loaded.');
+		}
+
+		// remove protocol from host
+		$scheme = parse_url($this->options['host'], PHP_URL_SCHEME);
+
+		if ($scheme) {
+			$this->options['host'] = substr($this->options['host'], strlen($scheme)+3);
+		}
+
+		// normalize root path
+		$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
+		
+		if (empty($this->options['alias'])) {
+			$this->options['alias'] = $this->options['user'].'@'.$this->options['host'];
+			// $num = elFinder::$volumesCnt-1;
+			// $this->options['alias'] = $this->root == '/' || $this->root == '.' ? 'FTP folder '.$num : basename($this->root);
+		}
+
+		$this->rootName = $this->options['alias'];
+		$this->options['separator'] = '/';
+
+		return $this->connect();
+		
+	}
+
+
+	/**
+	 * Configure after successfull mount.
+	 *
+	 * @return void
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function configure() {
+		parent::configure();
+		
+		if (!empty($this->options['tmpPath'])) {
+			if ((is_dir($this->options['tmpPath']) || @mkdir($this->options['tmpPath'], 0755, true)) && is_writable($this->options['tmpPath'])) {
+				$this->tmp = $this->options['tmpPath'];
+			}
+		}
+		
+		if (!$this->tmp && $this->tmbPath) {
+			$this->tmp = $this->tmbPath;
+		}
+		
+		if (!$this->tmp) {
+			$this->disabled[] = 'mkfile';
+			$this->disabled[] = 'paste';
+			$this->disabled[] = 'duplicate';
+			$this->disabled[] = 'upload';
+			$this->disabled[] = 'edit';
+			$this->disabled[] = 'archive';
+			$this->disabled[] = 'extract';
+		}
+		
+		// echo $this->tmp;
+		
+	}
+	
+	/**
+	 * Connect to ftp server
+	 *
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function connect() {
+		if (!($this->connect = ftp_connect($this->options['host'], $this->options['port'], $this->options['timeout']))) {
+			return $this->setError('Unable to connect to FTP server '.$this->options['host']);
+		}
+		if (!ftp_login($this->connect, $this->options['user'], $this->options['pass'])) {
+			$this->umount();
+			return $this->setError('Unable to login into '.$this->options['host']);
+		}
+		
+		// switch off extended passive mode - may be usefull for some servers
+		@ftp_exec($this->connect, 'epsv4 off' );
+		// enter passive mode if required
+		ftp_pasv($this->connect, $this->options['mode'] == 'passive');
+
+		// enter root folder
+		if (!ftp_chdir($this->connect, $this->root) 
+		|| $this->root != ftp_pwd($this->connect)) {
+			$this->umount();
+			return $this->setError('Unable to open root folder.');
+		}
+		
+		// check for MLST support
+		$features = ftp_raw($this->connect, 'FEAT');
+		if (!is_array($features)) {
+			$this->umount();
+			return $this->setError('Server does not support command FEAT.');
+		}
+
+		foreach ($features as $feat) {
+			if (strpos(trim($feat), 'MLST') === 0) {
+				return true;
+			}
+		}
+		
+		return $this->setError('Server does not support command MLST.');
+	}
+	
+	/*********************************************************************/
+	/*                               FS API                              */
+	/*********************************************************************/
+
+	/**
+	 * Close opened connection
+	 *
+	 * @return void
+	 * @author Dmitry (dio) Levashov
+	 **/
+	public function umount() {
+		$this->connect && @ftp_close($this->connect);
+	}
+
+
+	/**
+	 * Parse line from ftp_rawlist() output and return file stat (array)
+	 *
+	 * @param  string  $raw  line from ftp_rawlist() output
+	 * @return array
+	 * @author Dmitry Levashov
+	 **/
+	protected function parseRaw($raw) {
+		$info = preg_split("/\s+/", $raw, 9);
+		$stat = array();
+
+		if (count($info) < 9 || $info[8] == '.' || $info[8] == '..') {
+			return false;
+		}
+
+		if (!isset($this->ftpOsUnix)) {
+			$this->ftpOsUnix = !preg_match('/\d/', substr($info[0], 0, 1));
+		}
+		
+		if ($this->ftpOsUnix) {
+			
+			$stat['ts'] = strtotime($info[5].' '.$info[6].' '.$info[7]);
+			if (empty($stat['ts'])) {
+				$stat['ts'] = strtotime($info[6].' '.$info[5].' '.$info[7]);
+			}
+			
+			$name = $info[8];
+			
+			if (preg_match('|(.+)\-\>(.+)|', $name, $m)) {
+				$name   = trim($m[1]);
+				$target = trim($m[2]);
+				if (substr($target, 0, 1) != '/') {
+					$target = $this->root.'/'.$target;
+				}
+				$target = $this->_normpath($target);
+				$stat['name']  = $name;
+				if ($this->_inpath($target, $this->root) 
+				&& ($tstat = $this->stat($target))) {
+					$stat['size']  = $tstat['mime'] == 'directory' ? 0 : $info[4];
+					$stat['alias'] = $this->_relpath($target);
+					$stat['thash'] = $tstat['hash'];
+					$stat['mime']  = $tstat['mime'];
+					$stat['read']  = $tstat['read'];
+					$stat['write']  = $tstat['write'];
+				} else {
+					
+					$stat['mime']  = 'symlink-broken';
+					$stat['read']  = false;
+					$stat['write'] = false;
+					$stat['size']  = 0;
+					
+				}
+				return $stat;
+			}
+			
+			$perm = $this->parsePermissions($info[0]);
+			$stat['name']  = $name;
+			$stat['mime']  = substr(strtolower($info[0]), 0, 1) == 'd' ? 'directory' : $this->mimetype($stat['name']);
+			$stat['size']  = $stat['mime'] == 'directory' ? 0 : $info[4];
+			$stat['read']  = $perm['read'];
+			$stat['write'] = $perm['write'];
+			$stat['perm']  = substr($info[0], 1);
+		} else {
+			die('Windows ftp servers not supported yet');
+		}
+
+		return $stat;
+	}
+	
+	/**
+	 * Parse permissions string. Return array(read => true/false, write => true/false)
+	 *
+	 * @param  string  $perm  permissions string
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function parsePermissions($perm) {
+		$res   = array();
+		$parts = array();
+		$owner = $this->options['owner'];
+		for ($i = 0, $l = strlen($perm); $i < $l; $i++) {
+			$parts[] = substr($perm, $i, 1);
+		}
+
+		$read = ($owner && $parts[0] == 'r') || $parts[4] == 'r' || $parts[7] == 'r';
+		
+		return array(
+			'read'  => $parts[0] == 'd' ? $read && (($owner && $parts[3] == 'x') || $parts[6] == 'x' || $parts[9] == 'x') : $read,
+			'write' => ($owner && $parts[2] == 'w') || $parts[5] == 'w' || $parts[8] == 'w'
+		);
+	}
+	
+	/**
+	 * Cache dir contents
+	 *
+	 * @param  string  $path  dir path
+	 * @return void
+	 * @author Dmitry Levashov
+	 **/
+	protected function cacheDir($path) {
+		$this->dirsCache[$path] = array();
+
+		if (preg_match('/\'|\"/', $path)) {
+			foreach (ftp_nlist($this->connect, $path) as $p) {
+				if (($stat = $this->_stat($p)) &&empty($stat['hidden'])) {
+					// $files[] = $stat;
+					$this->dirsCache[$path][] = $p;
+				}
+			}
+			return;
+		}
+		foreach (ftp_rawlist($this->connect, $path) as $raw) {
+			if (($stat = $this->parseRaw($raw))) {
+				$p    = $path.'/'.$stat['name'];
+				$stat = $this->updateCache($p, $stat);
+				if (empty($stat['hidden'])) {
+					// $files[] = $stat;
+					$this->dirsCache[$path][] = $p;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Return ftp transfer mode for file
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function ftpMode($path) {
+		return strpos($this->mimetype($path), 'text/') === 0 ? FTP_ASCII : FTP_BINARY;
+	}
+
+	/*********************** paths/urls *************************/
+	
+	/**
+	 * Return parent directory path
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _dirname($path) {
+		return dirname($path);
+	}
+
+	/**
+	 * Return file name
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _basename($path) {
+		return basename($path);
+	}
+
+	/**
+	 * Join dir name and file name and retur full path
+	 *
+	 * @param  string  $dir
+	 * @param  string  $name
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _joinPath($dir, $name) {
+		return $dir.DIRECTORY_SEPARATOR.$name;
+	}
+	
+	/**
+	 * Return normalized path, this works the same as os.path.normpath() in Python
+	 *
+	 * @param  string  $path  path
+	 * @return string
+	 * @author Troex Nevelin
+	 **/
+	protected function _normpath($path) {
+		if (empty($path)) {
+			$path = '.';
+		}
+		// path must be start with /
+		$path = preg_replace('|^\.\/?|', '/', $path);
+		$path = preg_replace('/^([^\/])/', "/$1", $path);
+
+		if (strpos($path, '/') === 0) {
+			$initial_slashes = true;
+		} else {
+			$initial_slashes = false;
+		}
+			
+		if (($initial_slashes) 
+		&& (strpos($path, '//') === 0) 
+		&& (strpos($path, '///') === false)) {
+			$initial_slashes = 2;
+		}
+			
+		$initial_slashes = (int) $initial_slashes;
+
+		$comps = explode('/', $path);
+		$new_comps = array();
+		foreach ($comps as $comp) {
+			if (in_array($comp, array('', '.'))) {
+				continue;
+			}
+				
+			if (($comp != '..') 
+			|| (!$initial_slashes && !$new_comps) 
+			|| ($new_comps && (end($new_comps) == '..'))) {
+				array_push($new_comps, $comp);
+			} elseif ($new_comps) {
+				array_pop($new_comps);
+			}
+		}
+		$comps = $new_comps;
+		$path = implode('/', $comps);
+		if ($initial_slashes) {
+			$path = str_repeat('/', $initial_slashes) . $path;
+		}
+		
+		return $path ? $path : '.';
+	}
+	
+	/**
+	 * Return file path related to root dir
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _relpath($path) {
+		return $path == $this->root ? '' : substr($path, strlen($this->root)+1);
+	}
+	
+	/**
+	 * Convert path related to root dir into real path
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _abspath($path) {
+		return $path == $this->separator ? $this->root : $this->root.$this->separator.$path;
+	}
+	
+	/**
+	 * Return fake path started from root dir
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _path($path) {
+		return $this->rootName.($path == $this->root ? '' : $this->separator.$this->_relpath($path));
+	}
+	
+	/**
+	 * Return true if $path is children of $parent
+	 *
+	 * @param  string  $path    path to check
+	 * @param  string  $parent  parent path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _inpath($path, $parent) {
+		return $path == $parent || strpos($path, $parent.'/') === 0;
+	}
+	
+	/***************** file stat ********************/
+	/**
+	 * Return stat for given path.
+	 * Stat contains following fields:
+	 * - (int)    size    file size in b. required
+	 * - (int)    ts      file modification time in unix time. required
+	 * - (string) mime    mimetype. required for folders, others - optionally
+	 * - (bool)   read    read permissions. required
+	 * - (bool)   write   write permissions. required
+	 * - (bool)   locked  is object locked. optionally
+	 * - (bool)   hidden  is object hidden. optionally
+	 * - (string) alias   for symlinks - link target path relative to root path. optionally
+	 * - (string) target  for symlinks - link target path. optionally
+	 *
+	 * If file does not exists - returns empty array or false.
+	 *
+	 * @param  string  $path    file path 
+	 * @return array|false
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _stat($path) {
+		$raw = ftp_raw($this->connect, 'MLST '.$path);
+
+		if (is_array($raw) && count($raw) > 1 && substr(trim($raw[0]), 0, 1) == 2) {
+			$parts = explode(';', trim($raw[1]));
+			array_pop($parts);
+			$parts = array_map('strtolower', $parts);
+			$stat  = array();
+			// debug($parts);
+			foreach ($parts as $part) {
+
+				list($key, $val) = explode('=', $part);
+
+				switch ($key) {
+					case 'type':
+						$stat['mime'] = strpos($val, 'dir') !== false ? 'directory' : $this->mimetype($path);
+						break;
+
+					case 'size':
+						$stat['size'] = $val;
+						break;
+
+					case 'modify':
+						$ts = mktime(intval(substr($val, 8, 2)), intval(substr($val, 10, 2)), intval(substr($val, 12, 2)), intval(substr($val, 4, 2)), intval(substr($val, 6, 2)), substr($val, 0, 4));
+						$stat['ts'] = $ts;
+						// $stat['date'] = $this->formatDate($ts);
+						break;
+
+					case 'unix.mode':
+						$stat['chmod'] = $val;
+						break;
+
+					case 'perm':
+						$val = strtolower($val);
+						$stat['read']  = (int)preg_match('/e|l|r/', $val);
+						$stat['write'] = (int)preg_match('/w|m|c/', $val);
+						if (!preg_match('/f|d/', $val)) {
+							$stat['locked'] = 1;
+						}
+						break;
+				}
+			}
+			if (empty($stat['mime'])) {
+				return array();
+			}
+			if ($stat['mime'] == 'directory') {
+				$stat['size'] = 0;
+			}
+			
+			if (isset($stat['chmod'])) {
+				$stat['perm'] = '';
+				if ($stat['chmod'][0] == 0) {
+					$stat['chmod'] = substr($stat['chmod'], 1);
+				}
+
+				for ($i = 0; $i <= 2; $i++) {
+					$perm[$i] = array(false, false, false);
+					$n = isset($stat['chmod'][$i]) ? $stat['chmod'][$i] : 0;
+					
+					if ($n - 4 >= 0) {
+						$perm[$i][0] = true;
+						$n = $n - 4;
+						$stat['perm'] .= 'r';
+					} else {
+						$stat['perm'] .= '-';
+					}
+					
+					if ($n - 2 >= 0) {
+						$perm[$i][1] = true;
+						$n = $n - 2;
+						$stat['perm'] .= 'w';
+					} else {
+						$stat['perm'] .= '-';
+					}
+
+					if ($n - 1 == 0) {
+						$perm[$i][2] = true;
+						$stat['perm'] .= 'x';
+					} else {
+						$stat['perm'] .= '-';
+					}
+					
+					$stat['perm'] .= ' ';
+				}
+				
+				$stat['perm'] = trim($stat['perm']);
+
+				$owner = $this->options['owner'];
+				$read = ($owner && $perm[0][0]) || $perm[1][0] || $perm[2][0];
+
+				$stat['read']  = $stat['mime'] == 'directory' ? $read && (($owner && $perm[0][2]) || $perm[1][2] || $perm[2][2]) : $read;
+				$stat['write'] = ($owner && $perm[0][1]) || $perm[1][1] || $perm[2][1];
+				unset($stat['chmod']);
+
+			}
+			
+			return $stat;
+			
+		}
+		
+		return array();
+	}
+	
+	/**
+	 * Return true if path is dir and has at least one childs directory
+	 *
+	 * @param  string  $path  dir path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _subdirs($path) {
+		
+		if (preg_match('/\s|\'|\"/', $path)) {
+			foreach (ftp_nlist($this->connect, $path) as $p) {
+				if (($stat = $this->stat($path.'/'.$p)) && $stat['mime'] == 'directory') {
+					return true;
+				}
+			}
+			return false;
+		}
+		
+		foreach (ftp_rawlist($this->connect, $path) as $str) {
+			if (($stat = $this->parseRaw($str)) && $stat['mime'] == 'directory') {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Return object width and height
+	 * Ususaly used for images, but can be realize for video etc...
+	 *
+	 * @param  string  $path  file path
+	 * @param  string  $mime  file mime type
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _dimensions($path, $mime) {
+		return false;
+	}
+	
+	/******************** file/dir content *********************/
+		
+	/**
+	 * Return files list in directory.
+	 *
+	 * @param  string  $path  dir path
+	 * @return array
+	 * @author Dmitry (dio) Levashov
+	 * @author Cem (DiscoFever)
+	 **/
+	protected function _scandir($path) {
+		$files = array();
+
+		foreach (ftp_rawlist($this->connect, $path) as $str) {
+			if (($stat = $this->parseRaw($str))) {
+				$files[] = $path.DIRECTORY_SEPARATOR.$stat['name'];
+			}
+		}
+
+		return $files;
+	}
+		
+	/**
+	 * Open file and return file pointer
+	 *
+	 * @param  string  $path  file path
+	 * @param  bool    $write open file for writing
+	 * @return resource|false
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _fopen($path, $mode='rb') {
+		
+		if ($this->tmp) {
+			$local = $this->tmp.DIRECTORY_SEPARATOR.md5($path);
+
+			if (ftp_get($this->connect, $local, $path, FTP_BINARY)) {
+				return @fopen($local, $mode);
+			}
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Close opened file
+	 *
+	 * @param  resource  $fp  file pointer
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _fclose($fp, $path='') {
+		@fclose($fp);
+		if ($path) {
+			@unlink($this->tmp.DIRECTORY_SEPARATOR.md5($path));
+		}
+	}
+	
+	/********************  file/dir manipulations *************************/
+	
+	/**
+	 * Create dir and return created dir path or false on failed
+	 *
+	 * @param  string  $path  parent dir path
+	 * @param string  $name  new directory name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _mkdir($path, $name) {
+		$path = $path.'/'.$name;
+		if (ftp_mkdir($this->connect, $path) === false) {
+			return false;
+		} 
+		
+		$this->options['dirMode'] && @ftp_chmod($this->connect, $this->options['dirMode'], $path);
+		return $path;
+	}
+	
+	/**
+	 * Create file and return it's path or false on failed
+	 *
+	 * @param  string  $path  parent dir path
+	 * @param string  $name  new file name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _mkfile($path, $name) {
+		if ($this->tmp) {
+			$path = $path.'/'.$name;
+			$local = $this->tmp.DIRECTORY_SEPARATOR.md5($path);
+			$res = touch($local) && ftp_put($this->connect, $path, $local, FTP_ASCII);
+			@unlink($local);
+			return $res ? $path : false;
+		}
+		return false;
+	}
+	
+	/**
+	 * Create symlink. FTP driver does not support symlinks.
+	 *
+	 * @param  string  $target  link target
+	 * @param  string  $path    symlink path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _symlink($target, $path, $name) {
+		return false;
+	}
+	
+	/**
+	 * Copy file into another file
+	 *
+	 * @param  string  $source     source file path
+	 * @param  string  $targetDir  target directory path
+	 * @param  string  $name       new file name
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _copy($source, $targetDir, $name) {
+		$res = false;
+		
+		if ($this->tmp) {
+			$local  = $this->tmp.DIRECTORY_SEPARATOR.md5($source);
+			$target = $targetDir.DIRECTORY_SEPARATOR.$name;
+
+			if (ftp_get($this->connect, $local, $source, FTP_BINARY)
+			&& ftp_put($this->connect, $target, $local, $this->ftpMode($target))) {
+				$res = $target;
+			}
+			@unlink($local);
+		}
+		
+		return $res;
+	}
+	
+	/**
+	 * Move file into another parent dir.
+	 * Return new file path or false.
+	 *
+	 * @param  string  $source  source file path
+	 * @param  string  $target  target dir path
+	 * @param  string  $name    file name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _move($source, $targetDir, $name) {
+		$target = $targetDir.DIRECTORY_SEPARATOR.$name;
+		return ftp_rename($this->connect, $source, $target) ? $target : false;
+	}
+		
+	/**
+	 * Remove file
+	 *
+	 * @param  string  $path  file path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _unlink($path) {
+		return ftp_delete($this->connect, $path);
+	}
+
+	/**
+	 * Remove dir
+	 *
+	 * @param  string  $path  dir path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _rmdir($path) {
+		return ftp_rmdir($this->connect, $path);
+	}
+	
+	/**
+	 * Create new file and write into it from file pointer.
+	 * Return new file path or false on error.
+	 *
+	 * @param  resource  $fp   file pointer
+	 * @param  string    $dir  target dir path
+	 * @param  string    $name file name
+	 * @param  array     $stat file stat (required by some virtual fs)
+	 * @return bool|string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _save($fp, $dir, $name, $stat) {
+		$path = $dir.'/'.$name;
+		return ftp_fput($this->connect, $path, $fp, $this->ftpMode($path))
+			? $path
+			: false;
+	}
+	
+	/**
+	 * Get file contents
+	 *
+	 * @param  string  $path  file path
+	 * @return string|false
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _getContents($path) {
+		$contents = '';
+		if (($fp = $this->_fopen($path))) {
+			while (!feof($fp)) {
+			  $contents .= fread($fp, 8192);
+			}
+			$this->_fclose($fp, $path);
+			return $contents;
+		}
+		return false;
+	}
+	
+	/**
+	 * Write a string to a file
+	 *
+	 * @param  string  $path     file path
+	 * @param  string  $content  new file content
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _filePutContents($path, $content) {
+		$res = false;
+
+		if ($this->tmp) {
+			$local = $this->tmp.DIRECTORY_SEPARATOR.md5($path).'.txt';
+			
+			if (@file_put_contents($local, $content, LOCK_EX) !== false
+			&& ($fp = @fopen($local, 'rb'))) {
+				clearstatcache();
+				$res  = ftp_fput($this->connect, $path, $fp, $this->ftpMode($path));
+				@fclose($fp);
+			}
+			file_exists($local) && @unlink($local);
+		}
+
+		return $res;
+	}
+
+	/**
+	 * Detect available archivers
+	 *
+	 * @return void
+	 **/
+	protected function _checkArchivers() {
+		// die('Not yet implemented. (_checkArchivers)');
+		return array();
+	}
+
+	/**
+	 * Unpack archive
+	 *
+	 * @param  string  $path  archive path
+	 * @param  array   $arc   archiver command and arguments (same as in $this->archivers)
+	 * @return true
+	 * @return void
+	 * @author Dmitry (dio) Levashov
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _unpack($path, $arc) {
+		die('Not yet implemented. (_unpack)');
+		return false;
+	}
+
+	/**
+	 * Recursive symlinks search
+	 *
+	 * @param  string  $path  file/dir path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _findSymlinks($path) {
+		die('Not yet implemented. (_findSymlinks)');
+		if (is_link($path)) {
+			return true;
+		}
+		if (is_dir($path)) {
+			foreach (scandir($path) as $name) {
+				if ($name != '.' && $name != '..') {
+					$p = $path.DIRECTORY_SEPARATOR.$name;
+					if (is_link($p)) {
+						return true;
+					}
+					if (is_dir($p) && $this->_findSymlinks($p)) {
+						return true;
+					} elseif (is_file($p)) {
+						$this->archiveSize += filesize($p);
+					}
+				}
+			}
+		} else {
+			$this->archiveSize += filesize($path);
+		}
+		
+		return false;
+	}
+
+	/**
+	 * Extract files from archive
+	 *
+	 * @param  string  $path  archive path
+	 * @param  array   $arc   archiver command and arguments (same as in $this->archivers)
+	 * @return true
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _extract($path, $arc)
+	{
+		// get current directory
+		$cwd = getcwd();
+
+		$tmpDir = $this->tempDir();
+		if (!$tmpDir) {
+			return false;
+		}
+
+		$basename = $this->_basename($path);
+		$localPath = $tmpDir . DIRECTORY_SEPARATOR . $basename;
+
+		if (!ftp_get($this->connect, $localPath, $path, FTP_BINARY)) {
+			//cleanup
+			$this->deleteDir($tmpDir);
+			return false;
+		}
+
+		$remoteDirectory = dirname($path);
+		chdir($tmpDir);
+		$command = escapeshellcmd($arc['cmd'] . ' ' . $arc['argc'] . ' "' . $basename . '"');
+		$descriptorspec = array(
+			0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+			1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+			2 => array("pipe", "w") // stderr is a file to write to
+		);
+
+			
+		$process = proc_open($command, $descriptorspec, $pipes, $cwd);
+
+		if (is_resource($process)) {
+			fclose($pipes[0]);
+			fclose($pipes[1]);
+			$return_value = proc_close($process);
+		}
+
+		unlink($basename);
+		$filesToProcess = elFinderVolumeFTP::listFilesInDirectory($tmpDir, true);
+		if(!$filesToProcess) {
+			$this->setError(elFinder::ERROR_EXTRACT_EXEC, $tmpDir." is not a directory");
+			$this->deleteDir($tmpDir); //cleanup
+			return false;
+		}
+		if (count($filesToProcess) > 1) {
+
+			// for several files - create new directory
+			// create unique name for directory
+			$name = basename($path);
+			if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) {
+				$name = substr($name, 0, strlen($name) - strlen($m[0]));
+			}
+
+			$test = dirname($path) . DIRECTORY_SEPARATOR . $name;
+			if ($this->stat($test)) {
+				$name = $this->uniqueName(dirname($path), $name, '-', false);
+			}
+
+			$newPath = dirname($path) . DIRECTORY_SEPARATOR . $name;
+
+			$success = $this->_mkdir(dirname($path), $name);
+			foreach ($filesToProcess as $filename) {
+				if (!$success) {
+					break;
+				}
+				$targetPath = $newPath . DIRECTORY_SEPARATOR . $filename;
+				if (is_dir($filename)) {
+					$success = $this->_mkdir($newPath, $filename);
+				} else {
+					$success = ftp_put($this->connect, $targetPath, $filename, FTP_BINARY);
+				}
+			}
+			unset($filename);
+
+		} else {
+			$filename = $filesToProcess[0];
+			$newPath = $remoteDirectory . DIRECTORY_SEPARATOR . $filename;
+			$success = ftp_put($this->connect, $newPath, $filename, FTP_BINARY);
+		}
+
+		// return to initial directory
+		chdir($cwd);
+
+		//cleanup
+		if(!$this->deleteDir($tmpDir)) {
+			return false;
+		}
+		
+		if (!$success) {
+			$this->setError(elFinder::ERROR_FTP_UPLOAD_FILE, $newPath);
+			return false;
+		}
+		$this->clearcache();
+		return $newPath;
+	}
+
+	/**
+	 * Create archive and return its path
+	 *
+	 * @param  string  $dir    target dir
+	 * @param  array   $files  files names list
+	 * @param  string  $name   archive name
+	 * @param  array   $arc    archiver options
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _archive($dir, $files, $name, $arc)
+	{
+		// get current directory
+		$cwd = getcwd();
+
+		$tmpDir = $this->tempDir();
+		if (!$tmpDir) {
+			return false;
+		}
+
+		//download data
+		if (!$this->ftp_download_files($dir, $files, $tmpDir)) {
+			//cleanup
+			$this->deleteDir($tmpDir);
+			return false;
+		}
+
+		// go to the temporary directory
+		chdir($tmpDir);
+
+		// path to local copy of archive
+		$path = $tmpDir . DIRECTORY_SEPARATOR . $name;
+
+		$file_names_string = "";
+		foreach (scandir($tmpDir) as $filename) {
+			if ('.' == $filename) {
+				continue;
+			}
+			if ('..' == $filename) {
+				continue;
+			}
+			$file_names_string = $file_names_string . '"' . $filename . '" ';
+		}
+		$command = escapeshellcmd($arc['cmd'] . ' ' . $arc['argc'] . ' "' . $name . '" ' . $file_names_string);
+		
+		$descriptorspec = array(
+			0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+			1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+			2 => array("pipe", "w") // stderr is a file to write to
+		);
+
+			
+		$process = proc_open($command, $descriptorspec, $pipes, $cwd);
+
+		if (is_resource($process)) {
+			fclose($pipes[0]);
+			fclose($pipes[1]);
+			$return_value = proc_close($process);
+		}
+
+		$remoteArchiveFile = $dir . DIRECTORY_SEPARATOR . $name;
+
+		// upload archive
+		if (!ftp_put($this->connect, $remoteArchiveFile, $path, FTP_BINARY)) {
+			$this->setError(elFinder::ERROR_FTP_UPLOAD_FILE, $remoteArchiveFile);
+			$this->deleteDir($tmpDir); //cleanup
+			return false;
+		}
+
+		// return to initial work directory
+		chdir($cwd);
+
+		//cleanup
+		if(!$this->deleteDir($tmpDir)) {
+			return false;
+		}
+
+		return $remoteArchiveFile;
+	}
+
+	/**
+	 * Create writable temporary directory and return path to it.
+	 * @return string path to the new temporary directory or false in case of error.
+	 */
+	private function tempDir()
+	{
+		$tempPath = tempnam($this->tmp, 'elFinder');
+		if (!$tempPath) {
+			$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
+			return false;
+		}
+		$success = unlink($tempPath);
+		if (!$success) {
+			$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
+			return false;
+		}
+		$success = mkdir($tempPath, 0700, true);
+		if (!$success) {
+			$this->setError(elFinder::ERROR_CREATING_TEMP_DIR, $this->tmp);
+			return false;
+		}
+		return $tempPath;
+	}
+
+	/**
+	 * Gets in a single FTP request an array of absolute remote FTP paths of files and
+	 * folders in $remote_directory omitting symbolic links.
+	 * @param $remote_directory string remote FTP path to scan for file and folders recursively
+	 * @return array of elements each of which is an array of two elements:
+	 * <ul>
+	 * <li>$item['path'] - absolute remote FTP path</li>
+	 * <li>$item['type'] - either 'f' for file or 'd' for directory</li>
+	 * </ul>
+	 */
+	protected function ftp_scan_dir($remote_directory)
+	{
+		$buff = ftp_rawlist($this->connect, $remote_directory, true);
+		$next_folder = false;
+		$items = array();
+		foreach ($buff as $str) {
+			if ('' == $str) {
+				$next_folder = true;
+				continue;
+			}
+			if ($next_folder) {
+				$remote_directory = preg_replace('/\:/', '', $str);
+				$next_folder = false;
+				$item = array();
+				$item['path'] = $remote_directory;
+				$item['type'] = 'd'; // directory
+				$items[] = $item;
+				continue;
+			}
+			$info = preg_split("/\s+/", $str, 9);
+			$type = substr($info[0], 0, 1);
+			switch ($type) {
+				case 'l' : //omit symbolic links
+				case 'd' :
+					break;
+				default:
+					$remote_file_path = $remote_directory . DIRECTORY_SEPARATOR . $info[8];
+					$item = array();
+					$item['path'] = $remote_file_path;
+					$item['type'] = 'f'; // normal file
+					$items[] = $item;
+			}
+		}
+		return $items;
+	}
+
+	/**
+	 * Downloads specified files from remote directory
+	 * if there is a directory among files it is downloaded recursively (omitting symbolic links).
+	 * @param $remote_directory string remote FTP path to a source directory to download from.
+	 * @param array $files list of files to download from remote directory.
+	 * @param $dest_local_directory string destination folder to store downloaded files.
+	 * @return bool true on success and false on failure.
+	 */
+	private function ftp_download_files($remote_directory, array $files, $dest_local_directory)
+	{
+		$contents = $this->ftp_scan_dir($remote_directory);
+		if (!isset($contents)) {
+			$this->setError(elFinder::ERROR_FTP_DOWNLOAD_FILE, $remote_directory);
+			return false;
+		}
+		foreach ($contents as $item) {
+			$drop = true;
+			foreach ($files as $file) {
+				if ($remote_directory . DIRECTORY_SEPARATOR . $file == $item['path'] || strstr($item['path'], $remote_directory . DIRECTORY_SEPARATOR . $file . DIRECTORY_SEPARATOR)) {
+					$drop = false;
+					break;
+				}
+			}
+			if ($drop) continue;
+			$relative_path = str_replace($remote_directory, '', $item['path']);
+			$local_path = $dest_local_directory . DIRECTORY_SEPARATOR . $relative_path;
+			switch ($item['type']) {
+				case 'd':
+					$success = mkdir($local_path);
+					break;
+				case 'f':
+					$success = ftp_get($this->connect, $local_path, $item['path'], FTP_BINARY);
+					break;
+				default:
+					$success = true;
+			}
+			if (!$success) {
+				$this->setError(elFinder::ERROR_FTP_DOWNLOAD_FILE, $remote_directory);
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Delete local directory recursively.
+	 * @param $dirPath string to directory to be erased.
+	 * @return bool true on success and false on failure.
+	 */
+	private function deleteDir($dirPath)
+	{
+		if (!is_dir($dirPath)) {
+			$success = unlink($dirPath);
+		} else {
+			$success = true;
+			foreach (array_reverse(elFinderVolumeFTP::listFilesInDirectory($dirPath, false)) as $path) {
+				$path = $dirPath . DIRECTORY_SEPARATOR . $path;
+				if(is_link($path)) {
+					unlink($path);
+				} else if (is_dir($path)) {
+					$success = rmdir($path);
+				} else {
+					$success = unlink($path);
+				}
+				if (!$success) {
+					break;
+				}
+			}
+			if($success) {
+				$success = rmdir($dirPath);
+			}
+		}
+		if(!$success) {
+			$this->setError(elFinder::ERROR_RM, $dirPath);
+			return false;
+		}
+		return $success;
+	}
+
+	/**
+	 * Returns array of strings containing all files and folders in the specified local directory.
+	 * @param $dir
+	 * @param string $prefix
+	 * @internal param string $path path to directory to scan.
+	 * @return array array of files and folders names relative to the $path
+	 * or an empty array if the directory $path is empty,
+	 * <br />
+	 * false if $path is not a directory or does not exist.
+	 */
+	private static function listFilesInDirectory($dir, $omitSymlinks, $prefix = '')
+	{
+		if (!is_dir($dir)) {
+			return false;
+		}
+		$excludes = array(".","..");
+		$result = array();
+		$files = scandir($dir);
+		if(!$files) {
+			return array();
+		}
+		foreach($files as $file) {
+			if(!in_array($file, $excludes)) {
+				$path = $dir.DIRECTORY_SEPARATOR.$file;
+				if(is_link($path)) {
+					if($omitSymlinks) {
+						continue;
+					} else {
+						$result[] = $prefix.$file;
+					}
+				} else if(is_dir($path)) {
+					$result[] = $prefix.$file.DIRECTORY_SEPARATOR;
+					$subs = elFinderVolumeFTP::listFilesInDirectory($path, $omitSymlinks, $prefix.$file.DIRECTORY_SEPARATOR);
+					if($subs) {
+						$result = array_merge($result, $subs);
+					}
+					
+				} else {
+					$result[] = $prefix.$file;
+				}
+			}
+		}
+		return $result;
+	}
+
+/**
+	 * Resize image
+	 * @param string $hash
+	 * @param int $width
+	 * @param int $height
+	 * @param int $x
+	 * @param int $y
+	 * @param string $mode
+	 * @param string $bg
+	 * @param int $degree
+	 * @return array|bool|false
+	 */
+	public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0) {
+		if ($this->commandDisabled('resize')) {
+			return $this->setError(elFinder::ERROR_PERM_DENIED);
+		}
+
+		if (($file = $this->file($hash)) == false) {
+			return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
+		}
+
+		if (!$file['write'] || !$file['read']) {
+			return $this->setError(elFinder::ERROR_PERM_DENIED);
+		}
+
+		$path = $this->decode($hash);
+
+		$tmpDir = $this->tempDir();
+		if (!$tmpDir) {
+			return false;
+		}
+		
+		$local_path = $tmpDir . DIRECTORY_SEPARATOR . basename($path);
+		$remote_directory = ftp_pwd($this->connect);
+		$success = ftp_get($this->connect, $local_path, $path, FTP_BINARY);
+		if (!$success) {
+			$this->setError(elFinder::ERROR_FTP_DOWNLOAD_FILE, $remote_directory);
+			return false;
+		}
+
+		if (!$this->canResize($path, $file)) {
+			return $this->setError(elFinder::ERROR_UNSUPPORT_TYPE);
+		}
+
+		switch($mode) {
+
+			case 'propresize':
+				$result = $this->imgResize($local_path, $width, $height, true, true);
+				break;
+
+			case 'crop':
+				$result = $this->imgCrop($local_path, $width, $height, $x, $y);
+				break;
+
+			case 'fitsquare':
+				$result = $this->imgSquareFit($local_path, $width, $height, 'center', 'middle', ($bg ? $bg : $this->options['tmbBgColor']));
+				break;
+
+			case 'rotate':
+				$result = $this->imgRotate($local_path, $degree, ($bg ? $bg : $this->options['tmbBgColor']));
+				break;
+
+			default:
+				$result = $this->imgResize($local_path, $width, $height, false, true);
+				break;
+		}
+
+		if ($result) {
+			
+			// upload to FTP and clear temp local file
+
+			if (!ftp_put($this->connect, $path, $local_path, FTP_BINARY)) {
+				$this->setError(elFinder::ERROR_FTP_UPLOAD_FILE, $path);
+				$this->deleteDir($tmpDir); //cleanup
+			}
+			
+			$this->clearcache();
+			return $this->stat($path);
+		}
+
+		$this->setError(elFinder::ERROR_UNKNOWN);
+		return false;
+	}
+
+} // END class
+

+ 134 - 0
main/inc/lib/elfinder/php/elFinderVolumeFTPIIS.class.php

@@ -0,0 +1,134 @@
+<?php
+
+/**
+ * Simple elFinder driver for IIS FTP
+ *
+ **/
+class elFinderVolumeFTPIIS extends elFinderVolumeFTP {
+	
+	/**
+	 * Connect to ftp server
+	 *
+	 * @return bool
+	 **/
+	protected function connect() {
+		if (!($this->connect = ftp_connect($this->options['host'], $this->options['port'], $this->options['timeout']))) {
+			return $this->setError('Unable to connect to FTP server '.$this->options['host']);
+		}
+		if (!ftp_login($this->connect, $this->options['user'], $this->options['pass'])) {
+			$this->umount();
+			return $this->setError('Unable to login into '.$this->options['host']);
+		}
+		
+		// switch off extended passive mode - may be usefull for some servers
+		//@ftp_exec($this->connect, 'epsv4 off' );
+		// enter passive mode if required
+		$this->options['mode'] = 'active';
+		ftp_pasv($this->connect, $this->options['mode'] == 'passive');
+
+		// enter root folder
+		if (!ftp_chdir($this->connect, $this->root))
+		{
+			$this->umount();
+			return $this->setError('Unable to open root folder.');
+		}
+		
+		$stat = array();
+		$stat['name'] = $this->root;
+		$stat['mime'] = 'directory';
+		$this->filesCache[$this->root] = $stat;
+		$this->cacheDir($this->root);
+		
+		return true;
+	}
+	
+	/**
+	 * Parse line from ftp_rawlist() output and return file stat (array)
+	 *
+	 * @param  string  $raw  line from ftp_rawlist() output
+	 * @return array
+	 **/
+	protected function parseRaw($raw) {
+		$info = preg_split("/\s+/", $raw, 9);
+		$stat = array();
+
+		$stat['name'] = join(" ", array_slice($info, 3, 9));
+		$stat['read'] = true;
+		if ($info[2] == '<DIR>')
+		{
+			$stat['size'] = 0;
+			$stat['mime'] = 'directory';
+		}
+		else
+		{
+			$stat['size'] = $info[2];
+			$stat['mime'] = $this->mimetype($stat['name']);
+		}
+
+		return $stat;
+	}
+	
+	/**
+	 * Cache dir contents
+	 *
+	 * @param  string  $path  dir path
+	 * @return void
+	 **/
+	protected function cacheDir($path) {
+		$this->dirsCache[$path] = array();
+
+		if (preg_match('/\'|\"/', $path)) {
+			foreach (ftp_nlist($this->connect, $path) as $p) {
+				if (($stat = $this->_stat($p)) &&empty($stat['hidden'])) {
+					// $files[] = $stat;
+					$this->dirsCache[$path][] = $p;
+				}
+			}
+			return;
+		}
+		foreach (ftp_rawlist($this->connect, $path) as $raw) {
+			if (($stat = $this->parseRaw($raw))) {
+				$p    = $path.DIRECTORY_SEPARATOR.$stat['name'];
+					// $files[] = $stat;
+					$this->dirsCache[$path][] = $p;
+					//$stat['name'] = $p;
+					$this->filesCache[$p] = $stat;
+			}
+		}
+	}
+
+	protected function _stat($path) {
+		$stat = array();
+
+		$stat = $this->filesCache[$path];
+		
+		if (empty($stat))
+		{
+			$this->cacheDir($this->_dirname($path));
+			$stat = $this->filesCache[$path];
+			
+		}
+		
+		return $stat;
+	}
+	
+
+	protected function ftp_scan_dir($remote_directory)
+	{
+		$buff = ftp_rawlist($this->connect, $remote_directory, true);
+		$items = array();
+		foreach ($buff as $str) {
+			$info = preg_split("/\s+/", $str, 9);
+			$remote_file_path = $remote_directory . DIRECTORY_SEPARATOR . join(" ", array_slice($info, 3, 9));
+			$item = array();
+			$item['type'] = $info[2] == '<DIR>' ? 'd' : 'f';
+			$item['path'] = $remote_file_path;
+			$items[] = $item;
+			
+			if ($item['type'] == 'd')
+				$items = array_merge($items, $this->ftp_scan_dir($item['path']));
+		}
+		return $items;
+	}
+} // END class
+

+ 106 - 176
main/inc/lib/elfinder/php/elFinderVolumeLocalFileSystem.class.php

@@ -7,7 +7,7 @@
  * @author Troex Nevelin
  **/
 class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
-	
+
 	/**
 	 * Driver id
 	 * Must be started from letter and contains [a-z0-9]
@@ -16,14 +16,21 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 * @var string
 	 **/
 	protected $driverId = 'l';
-	
+
 	/**
 	 * Required to count total archive files size
 	 *
 	 * @var int
 	 **/
 	protected $archiveSize = 0;
-	
+
+	/**
+	 * Canonicalized absolute pathname of $root
+	 *
+	 * @var strung
+	 */
+	protected $aroot;
+
 	/**
 	 * Constructor
 	 * Extend options with required fields
@@ -38,11 +45,11 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		$this->options['quarantine'] = '.quarantine';  // quarantine folder name - required to check archive (must be hidden)
 		$this->options['maxArcFilesSize'] = 0;        // max allowed archive files size (0 - no limit)
 	}
-	
+
 	/*********************************************************************/
 	/*                        INIT AND CONFIGURE                         */
 	/*********************************************************************/
-	
+
 	/**
 	 * Configure after successfull mount.
 	 *
@@ -52,7 +59,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function configure() {
 		$this->aroot = realpath($this->root);
 		$root = $this->stat($this->root);
-		
+
 		if ($this->options['quarantine']) {
 			$this->attributes[] = array(
 				'pattern' => '~^'.preg_quote(DIRECTORY_SEPARATOR.$this->options['quarantine']).'$~',
@@ -62,7 +69,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 				'hidden'  => true
 			);
 		}
-		
+
 		// chek thumbnails path
 		if ($this->options['tmbPath']) {
 			$this->options['tmbPath'] = strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false
@@ -73,7 +80,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		}
 
 		parent::configure();
-		
+
 		// if no thumbnails url - try detect it
 		if ($root['read'] && !$this->tmbURL && $this->URL) {
 			if (strpos($this->tmbPath, $this->root) === 0) {
@@ -95,15 +102,15 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 			$this->archivers['extract'] = array();
 			$this->disabled[] = 'extract';
 		}
-		
+
 	}
-	
+
 	/*********************************************************************/
 	/*                               FS API                              */
 	/*********************************************************************/
 
 	/*********************** paths/urls *************************/
-	
+
 	/**
 	 * Return parent directory path
 	 *
@@ -137,7 +144,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _joinPath($dir, $name) {
 		return $dir.DIRECTORY_SEPARATOR.$name;
 	}
-	
+
 	/**
 	 * Return normalized path, this works the same as os.path.normpath() in Python
 	 *
@@ -155,13 +162,13 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		} else {
 			$initial_slashes = false;
 		}
-			
-		if (($initial_slashes) 
-		&& (strpos($path, '//') === 0) 
+
+		if (($initial_slashes)
+		&& (strpos($path, '//') === 0)
 		&& (strpos($path, '///') === false)) {
 			$initial_slashes = 2;
 		}
-			
+
 		$initial_slashes = (int) $initial_slashes;
 
 		$comps = explode('/', $path);
@@ -170,9 +177,9 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 			if (in_array($comp, array('', '.'))) {
 				continue;
 			}
-				
-			if (($comp != '..') 
-			|| (!$initial_slashes && !$new_comps) 
+
+			if (($comp != '..')
+			|| (!$initial_slashes && !$new_comps)
 			|| ($new_comps && (end($new_comps) == '..'))) {
 				array_push($new_comps, $comp);
 			} elseif ($new_comps) {
@@ -184,10 +191,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		if ($initial_slashes) {
 			$path = str_repeat('/', $initial_slashes) . $path;
 		}
-		
+
 		return $path ? $path : '.';
 	}
-	
+
 	/**
 	 * Return file path related to root dir
 	 *
@@ -198,7 +205,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _relpath($path) {
 		return $path == $this->root ? '' : substr($path, strlen($this->root)+1);
 	}
-	
+
 	/**
 	 * Convert path related to root dir into real path
 	 *
@@ -209,7 +216,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _abspath($path) {
 		return $path == DIRECTORY_SEPARATOR ? $this->root : $this->root.DIRECTORY_SEPARATOR.$path;
 	}
-	
+
 	/**
 	 * Return fake path started from root dir
 	 *
@@ -220,7 +227,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _path($path) {
 		return $this->rootName.($path == $this->root ? '' : $this->separator.$this->_relpath($path));
 	}
-	
+
 	/**
 	 * Return true if $path is children of $parent
 	 *
@@ -232,9 +239,9 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _inpath($path, $parent) {
 		return $path == $parent || strpos($path, $parent.DIRECTORY_SEPARATOR) === 0;
 	}
-	
-	
-	
+
+
+
 	/***************** file stat ********************/
 
 	/**
@@ -252,7 +259,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 *
 	 * If file does not exists - returns empty array or false.
 	 *
-	 * @param  string  $path    file path 
+	 * @param  string  $path    file path
 	 * @return array|false
 	 * @author Dmitry (dio) Levashov
 	 **/
@@ -263,8 +270,17 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 			return $stat;
 		}
 
+		//Verifies the given path is the root or is inside the root. Prevents directory traveral.
+		if (!$this->aroot) {
+			// for Inheritance class ( not calling parent::configure() )
+			$this->aroot = realpath($this->root);
+		}
+		if (!$this->_inpath(realpath($path), $this->aroot)) {
+			return $stat;
+		}
+
 		if ($path != $this->root && is_link($path)) {
-			if (($target = $this->readlink($path)) == false 
+			if (($target = $this->readlink($path)) == false
 			|| $target == $path) {
 				$stat['mime']  = 'symlink-broken';
 				$stat['read']  = false;
@@ -280,9 +296,9 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		} else {
 			$size = @filesize($path);
 		}
-		
+
 		$dir = is_dir($path);
-		
+
 		$stat['mime']  = $dir ? 'directory' : $this->mimetype($path);
 		$stat['ts']    = filemtime($path);
 		$stat['read']  = is_readable($path);
@@ -290,10 +306,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		if ($stat['read']) {
 			$stat['size'] = $dir ? 0 : $size;
 		}
-		
+
 		return $stat;
 	}
-	
+
 
 	/**
 	 * Return true if path is dir and has at least one childs directory
@@ -317,10 +333,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Return object width and height
-	 * Ususaly used for images, but can be realize for video etc...
+	 * Usualy used for images, but can be realize for video etc...
 	 *
 	 * @param  string  $path  file path
 	 * @param  string  $mime  file mime type
@@ -329,12 +345,12 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 **/
 	protected function _dimensions($path, $mime) {
 		clearstatcache();
-		return strpos($mime, 'image') === 0 && ($s = @getimagesize($path)) !== false 
-			? $s[0].'x'.$s[1] 
+		return strpos($mime, 'image') === 0 && ($s = @getimagesize($path)) !== false
+			? $s[0].'x'.$s[1]
 			: false;
 	}
 	/******************** file/dir content *********************/
-	
+
 	/**
 	 * Return symlink target file
 	 *
@@ -346,17 +362,17 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		if (!($target = @readlink($path))) {
 			return false;
 		}
-		
+
 		if (substr($target, 0, 1) != DIRECTORY_SEPARATOR) {
 			$target = dirname($path).DIRECTORY_SEPARATOR.$target;
 		}
-		
+
 		$atarget = realpath($target);
-		
+
 		if (!$atarget) {
 			return false;
 		}
-		
+
 		$root  = $this->root;
 		$aroot = $this->aroot;
 
@@ -366,7 +382,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 
 		return false;
 	}
-		
+
 	/**
 	 * Return files list in directory.
 	 *
@@ -376,7 +392,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 **/
 	protected function _scandir($path) {
 		$files = array();
-		
+
 		foreach (scandir($path) as $name) {
 			if ($name != '.' && $name != '..') {
 				$files[] = $path.DIRECTORY_SEPARATOR.$name;
@@ -384,7 +400,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		}
 		return $files;
 	}
-		
+
 	/**
 	 * Open file and return file pointer
 	 *
@@ -396,7 +412,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _fopen($path, $mode='rb') {
 		return @fopen($path, 'r');
 	}
-	
+
 	/**
 	 * Close opened file
 	 *
@@ -407,9 +423,9 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _fclose($fp, $path='') {
 		return @fclose($fp);
 	}
-	
+
 	/********************  file/dir manipulations *************************/
-	
+
 	/**
 	 * Create dir and return created dir path or false on failed
 	 *
@@ -428,7 +444,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 
 		return false;
 	}
-	
+
 	/**
 	 * Create file and return it's path or false on failed
 	 *
@@ -439,7 +455,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 **/
 	protected function _mkfile($path, $name) {
 		$path = $path.DIRECTORY_SEPARATOR.$name;
-		
+
 		if (($fp = @fopen($path, 'w'))) {
 			@fclose($fp);
 			@chmod($path, $this->options['fileMode']);
@@ -447,7 +463,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Create symlink
 	 *
@@ -460,7 +476,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _symlink($source, $targetDir, $name) {
 		return @symlink($source, $targetDir.DIRECTORY_SEPARATOR.$name);
 	}
-	
+
 	/**
 	 * Copy file into another file
 	 *
@@ -473,7 +489,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _copy($source, $targetDir, $name) {
 		return copy($source, $targetDir.DIRECTORY_SEPARATOR.$name);
 	}
-	
+
 	/**
 	 * Move file into another parent dir.
 	 * Return new file path or false.
@@ -488,7 +504,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		$target = $targetDir.DIRECTORY_SEPARATOR.$name;
 		return @rename($source, $target) ? $target : false;
 	}
-		
+
 	/**
 	 * Remove file
 	 *
@@ -510,7 +526,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _rmdir($path) {
 		return @rmdir($path);
 	}
-	
+
 	/**
 	 * Create new file and write into it from file pointer.
 	 * Return new file path or false on error.
@@ -518,10 +534,11 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 * @param  resource  $fp   file pointer
 	 * @param  string    $dir  target dir path
 	 * @param  string    $name file name
+	 * @param  array     $stat file stat (required by some virtual fs)
 	 * @return bool|string
 	 * @author Dmitry (dio) Levashov
 	 **/
-	protected function _save($fp, $dir, $name, $mime, $w, $h) {
+	protected function _save($fp, $dir, $name, $stat) {
 		$path = $dir.DIRECTORY_SEPARATOR.$name;
 
 		if (!($target = @fopen($path, 'wb'))) {
@@ -536,7 +553,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		clearstatcache();
 		return $path;
 	}
-	
+
 	/**
 	 * Get file contents
 	 *
@@ -547,7 +564,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	protected function _getContents($path) {
 		return file_get_contents($path);
 	}
-	
+
 	/**
 	 * Write a string to a file
 	 *
@@ -570,96 +587,8 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 * @return void
 	 **/
 	protected function _checkArchivers() {
-		if (!function_exists('exec')) {
-			$this->options['archivers'] = $this->options['archive'] = array();
-			return;
-		}
-		$arcs = array(
-			'create'  => array(),
-			'extract' => array()
-			);
-		
-		//exec('tar --version', $o, $ctar);
-		$this->procExec('tar --version', $o, $ctar);
-
-		if ($ctar == 0) {
-			$arcs['create']['application/x-tar']  = array('cmd' => 'tar', 'argc' => '-cf', 'ext' => 'tar');
-			$arcs['extract']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-xf', 'ext' => 'tar');
-			//$test = exec('gzip --version', $o, $c);
-			unset($o);
-			$test = $this->procExec('gzip --version', $o, $c);
-
-			if ($c == 0) {
-				$arcs['create']['application/x-gzip']  = array('cmd' => 'tar', 'argc' => '-czf', 'ext' => 'tgz');
-				$arcs['extract']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-xzf', 'ext' => 'tgz');
-			}
-			unset($o);
-			//$test = exec('bzip2 --version', $o, $c);
-			$test = $this->procExec('bzip2 --version', $o, $c);
-			if ($c == 0) {
-				$arcs['create']['application/x-bzip2']  = array('cmd' => 'tar', 'argc' => '-cjf', 'ext' => 'tbz');
-				$arcs['extract']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-xjf', 'ext' => 'tbz');
-			}
-		}
-		unset($o);
-		//exec('zip --version', $o, $c);
-		$this->procExec('zip -v', $o, $c);
-		if ($c == 0) {
-			$arcs['create']['application/zip']  = array('cmd' => 'zip', 'argc' => '-r9', 'ext' => 'zip');
-		}
-		unset($o);
-		$this->procExec('unzip --help', $o, $c);
-		if ($c == 0) {
-			$arcs['extract']['application/zip'] = array('cmd' => 'unzip', 'argc' => '',  'ext' => 'zip');
-		} 
-		unset($o);
-		//exec('rar --version', $o, $c);
-		$this->procExec('rar --version', $o, $c);
-		if ($c == 0 || $c == 7) {
-			$arcs['create']['application/x-rar']  = array('cmd' => 'rar', 'argc' => 'a -inul', 'ext' => 'rar');
-			$arcs['extract']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'x -y',    'ext' => 'rar');
-		} else {
-			unset($o);
-			//$test = exec('unrar', $o, $c);
-			$test = $this->procExec('unrar', $o, $c);
-			if ($c==0 || $c == 7) {
-				$arcs['extract']['application/x-rar'] = array('cmd' => 'unrar', 'argc' => 'x -y', 'ext' => 'rar');
-			}
-		}
-		unset($o);
-		//exec('7za --help', $o, $c);
-		$this->procExec('7za --help', $o, $c);
-		if ($c == 0) {
-			$arcs['create']['application/x-7z-compressed']  = array('cmd' => '7za', 'argc' => 'a', 'ext' => '7z');
-			$arcs['extract']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'e -y', 'ext' => '7z');
-			
-			if (empty($arcs['create']['application/x-gzip'])) {
-				$arcs['create']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'a -tgzip', 'ext' => 'tar.gz');
-			}
-			if (empty($arcs['extract']['application/x-gzip'])) {
-				$arcs['extract']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'e -tgzip -y', 'ext' => 'tar.gz');
-			}
-			if (empty($arcs['create']['application/x-bzip2'])) {
-				$arcs['create']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2', 'ext' => 'tar.bz');
-			}
-			if (empty($arcs['extract']['application/x-bzip2'])) {
-				$arcs['extract']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2 -y', 'ext' => 'tar.bz');
-			}
-			if (empty($arcs['create']['application/zip'])) {
-				$arcs['create']['application/zip'] = array('cmd' => '7za', 'argc' => 'a -tzip -l', 'ext' => 'zip');
-			}
-			if (empty($arcs['extract']['application/zip'])) {
-				$arcs['extract']['application/zip'] = array('cmd' => '7za', 'argc' => 'e -tzip -y', 'ext' => 'zip');
-			}
-			if (empty($arcs['create']['application/x-tar'])) {
-				$arcs['create']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'a -ttar -l', 'ext' => 'tar');
-			}
-			if (empty($arcs['extract']['application/x-tar'])) {
-				$arcs['extract']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'e -ttar -y', 'ext' => 'tar');
-			}
-		}
-		
-		$this->archivers = $arcs;
+		$this->archivers = $this->getArchivers();
+		return;
 	}
 
 	/**
@@ -691,12 +620,12 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		if (is_link($path)) {
 			return true;
 		}
-		
+
 		if (is_dir($path)) {
 			foreach (scandir($path) as $name) {
 				if ($name != '.' && $name != '..') {
 					$p = $path.DIRECTORY_SEPARATOR.$name;
-					if (is_link($p)) {
+					if (is_link($p) || !$this->nameAccepted($name)) {
 						return true;
 					}
 					if (is_dir($p) && $this->_findSymlinks($p)) {
@@ -707,9 +636,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 				}
 			}
 		} else {
+
 			$this->archiveSize += filesize($path);
 		}
-		
+
 		return false;
 	}
 
@@ -719,30 +649,30 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 * @param  string  $path  archive path
 	 * @param  array   $arc   archiver command and arguments (same as in $this->archivers)
 	 * @return true
-	 * @author Dmitry (dio) Levashov, 
+	 * @author Dmitry (dio) Levashov,
 	 * @author Alexey Sukhotin
 	 **/
 	protected function _extract($path, $arc) {
-		
+
 		if ($this->quarantine) {
 			$dir     = $this->quarantine.DIRECTORY_SEPARATOR.str_replace(' ', '_', microtime()).basename($path);
 			$archive = $dir.DIRECTORY_SEPARATOR.basename($path);
-			
+
 			if (!@mkdir($dir)) {
 				return false;
 			}
-			
+
 			chmod($dir, 0777);
-			
+
 			// copy in quarantine
 			if (!copy($path, $archive)) {
 				return false;
 			}
-			
+
 			// extract in quarantine
 			$this->_unpack($archive, $arc);
-			@unlink($archive);
-			
+			unlink($archive);
+
 			// get files list
 			$ls = array();
 			foreach (scandir($dir) as $i => $name) {
@@ -750,19 +680,19 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 					$ls[] = $name;
 				}
 			}
-			
+
 			// no files - extract error ?
 			if (empty($ls)) {
 				return false;
 			}
-			
+
 			$this->archiveSize = 0;
-			
+
 			// find symlinks
 			$symlinks = $this->_findSymlinks($dir);
 			// remove arc copy
 			$this->remove($dir);
-			
+
 			if ($symlinks) {
 				return $this->setError(elFinder::ERROR_ARC_SYMLINKS);
 			}
@@ -771,14 +701,14 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 			if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
 				return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
 			}
-			
-			
-			
+
+
+
 			// archive contains one item - extract in archive dir
 			if (count($ls) == 1) {
 				$this->_unpack($path, $arc);
 				$result = dirname($path).DIRECTORY_SEPARATOR.$ls[0];
-				
+
 
 			} else {
 				// for several files - create new directory
@@ -791,22 +721,22 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 				if (file_exists($test) || is_link($test)) {
 					$name = $this->uniqueName(dirname($path), $name, '-', false);
 				}
-				
+
 				$result  = dirname($path).DIRECTORY_SEPARATOR.$name;
 				$archive = $result.DIRECTORY_SEPARATOR.basename($path);
 
 				if (!$this->_mkdir(dirname($path), $name) || !copy($path, $archive)) {
 					return false;
 				}
-				
+
 				$this->_unpack($archive, $arc);
 				@unlink($archive);
 			}
-			
+
 			return file_exists($result) ? $result : false;
 		}
 	}
-	
+
 	/**
 	 * Create archive and return its path
 	 *
@@ -815,15 +745,15 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 	 * @param  string  $name   archive name
 	 * @param  array   $arc    archiver options
 	 * @return string|bool
-	 * @author Dmitry (dio) Levashov, 
+	 * @author Dmitry (dio) Levashov,
 	 * @author Alexey Sukhotin
 	 **/
 	protected function _archive($dir, $files, $name, $arc) {
 		$cwd = getcwd();
 		chdir($dir);
-		
+
 		$files = array_map('escapeshellarg', $files);
-		
+
 		$cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.implode(' ', $files);
 		$this->procExec($cmd, $o, $c);
 		chdir($cwd);
@@ -831,5 +761,5 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
 		$path = $dir.DIRECTORY_SEPARATOR.$name;
 		return file_exists($path) ? $path : false;
 	}
-	
-} // END class 
+
+} // END class

+ 69 - 5
main/inc/lib/elfinder/php/elFinderVolumeMySQL.class.php

@@ -209,6 +209,53 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver {
 		return $this->query($sql) && $this->db->affected_rows > 0;
 	}
 
+	/**
+	 * Search files
+	 *
+	 * @param  string  $q  search string
+	 * @param  array   $mimes
+	 * @return array
+	 * @author Dmitry (dio) Levashov
+	 **/
+	public function search($q, $mimes) {
+		$result = array();
+
+		$sql = 'SELECT f.id, f.parent_id, f.name, f.size, f.mtime AS ts, f.mime, f.read, f.write, f.locked, f.hidden, f.width, f.height, 0 AS dirs 
+				FROM %s AS f 
+				WHERE f.name RLIKE "%s"';
+		
+		$sql = sprintf($sql, $this->tbf, $this->db->real_escape_string($q));
+		
+		if (($res = $this->query($sql))) {
+			while ($row = $res->fetch_assoc()) {
+				if ($this->mimeAccepted($row['mime'], $mimes)) {
+					$id = $row['id'];
+					if ($row['parent_id']) {
+						$row['phash'] = $this->encode($row['parent_id']);
+					} 
+
+					if ($row['mime'] == 'directory') {
+						unset($row['width']);
+						unset($row['height']);
+					} else {
+						unset($row['dirs']);
+					}
+
+					unset($row['id']);
+					unset($row['parent_id']);
+
+
+
+					if (($stat = $this->updateCache($id, $row)) && empty($stat['hidden'])) {
+						$result[] = $stat;
+					}
+				}
+			}
+		}
+		
+		return $result;
+	}
+
 	/**
 	 * Return temporary file path for required file
 	 *
@@ -298,9 +345,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver {
 				}
 			}
 			@unlink($img);
-			if (!empty($file['tmb']) && $file['tmb'] != "1") {
-				$this->rmTmb($file['tmb']);
-			}
+			$this->rmTmb($file);
 			$this->clearcache();
 			return $this->stat($path);
 		}
@@ -397,6 +442,20 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver {
 		return $this->db->real_escape_string($realPath);
 	}
 
+	/**
+	 * Recursive files search
+	 *
+	 * @param  string  $path   dir path
+	 * @param  string  $q      search string
+	 * @param  array   $mimes
+	 * @return array
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function doSearch($path, $q, $mimes) {
+		return array();
+	}
+
+
 	/*********************** paths/urls *************************/
 	
 	/**
@@ -708,7 +767,7 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver {
 	protected function _move($source, $targetDir, $name) {
 		$sql = 'UPDATE %s SET parent_id=%d, name="%s" WHERE id=%d LIMIT 1';
 		$sql = sprintf($sql, $this->tbf, $targetDir, $this->db->real_escape_string($name), $source);
-		return $this->query($sql) && $this->db->affected_rows > 0;
+		return $this->query($sql) && $this->db->affected_rows > 0 ? $source : false;
 	}
 		
 	/**
@@ -754,12 +813,17 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver {
 	 * @param  resource  $fp   file pointer
 	 * @param  string    $dir  target dir path
 	 * @param  string    $name file name
+	 * @param  array     $stat file stat (required by some virtual fs)
 	 * @return bool|string
 	 * @author Dmitry (dio) Levashov
 	 **/
-	protected function _save($fp, $dir, $name, $mime, $w, $h) {
+	protected function _save($fp, $dir, $name, $stat) {
 		$this->clearcache();
 		
+		$mime = $stat['mime'];
+		$w = !empty($stat['width'])  ? $stat['width']  : 0;
+		$h = !empty($stat['height']) ? $stat['height'] : 0;
+		
 		$id = $this->_joinPath($dir, $name);
 		rewind($fp);
 		$stat = fstat($fp);

+ 732 - 0
main/inc/lib/elfinder/php/elFinderVolumeS3.class.php

@@ -0,0 +1,732 @@
+<?php
+
+/**
+ * @file
+ * 
+ * elFinder driver for Amazon S3 (SOAP) filesystem.
+ *
+ * @author Dmitry (dio) Levashov,
+ * @author Alexey Sukhotin
+ * */
+class elFinderVolumeS3 extends elFinderVolumeDriver {
+	protected $driverId = 's3s';
+	
+	protected $s3;
+	
+	public function __construct() {
+		$opts = array(
+			'accesskey'          => '',
+			'secretkey'          => '',
+			'bucket'          => '',
+			'tmpPath' => '',
+		);
+		$this->options = array_merge($this->options, $opts); 
+		$this->options['mimeDetect'] = 'internal';
+
+	}
+	
+	
+	protected function init() {
+		if (!$this->options['accesskey'] 
+		||  !$this->options['secretkey'] 
+		||  !$this->options['bucket']) {
+			return $this->setError('Required options undefined.');
+		}
+		
+		$this->s3 = new S3SoapClient($this->options['accesskey'], $this->options['secretkey']);
+		
+		$this->root = $this->options['path'];
+		
+		$this->rootName = 's3';
+		
+		return true;
+	}
+	
+	protected function configure() {
+		parent::configure();
+		if (!empty($this->options['tmpPath'])) {
+			if ((is_dir($this->options['tmpPath']) || @mkdir($this->options['tmpPath'])) && is_writable($this->options['tmpPath'])) {
+				$this->tmpPath = $this->options['tmpPath'];
+			}
+		}
+		$this->mimeDetect = 'internal';
+	}
+	
+	/**
+	 * Return parent directory path
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _dirname($path) {
+	
+		$newpath =  preg_replace("/\/$/", "", $path);
+		$dn = substr($path, 0, strrpos($newpath, '/')) ;
+		
+		if (substr($dn, 0, 1) != '/') {
+		 $dn = "/$dn";
+		}
+		
+		return $dn;
+	}
+
+	/**
+	 * Return file name
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _basename($path) {
+		return basename($path);
+	}
+
+	
+	
+	/**
+	 * Join dir name and file name and return full path.
+	 * Some drivers (db) use int as path - so we give to concat path to driver itself
+	 *
+	 * @param  string  $dir   dir path
+	 * @param  string  $name  file name
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+		protected function _joinPath($dir, $name) {
+		return $dir.DIRECTORY_SEPARATOR.$name;
+	}
+	
+	/**
+	 * Return normalized path, this works the same as os.path.normpath() in Python
+	 *
+	 * @param  string  $path  path
+	 * @return string
+	 * @author Troex Nevelin
+	 **/
+	protected function _normpath($path) {
+		$tmp =  preg_replace("/^\//", "", $path);
+		$tmp =  preg_replace("/\/\//", "/", $tmp);
+		$tmp =  preg_replace("/\/$/", "", $tmp);
+		return $tmp;
+	}
+
+	/**
+	 * Return file path related to root dir
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _relpath($path) {
+	
+		
+		$newpath = $path;
+		
+		
+		if (substr($path, 0, 1) != '/') {
+			$newpath = "/$newpath";
+		}
+		
+		$newpath =  preg_replace("/\/$/", "", $newpath);
+	
+		$ret = ($newpath == $this->root) ? '' : substr($newpath, strlen($this->root)+1);
+		
+		return $ret;
+	}
+	
+	/**
+	 * Convert path related to root dir into real path
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _abspath($path) {
+		return $path == $this->separator ? $this->root : $this->root.$this->separator.$path;
+	}
+	
+	/**
+	 * Return fake path started from root dir
+	 *
+	 * @param  string  $path  file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _path($path) {
+		return $this->rootName.($path == $this->root ? '' : $this->separator.$this->_relpath($path));
+	}
+	
+	/**
+	 * Return true if $path is children of $parent
+	 *
+	 * @param  string  $path    path to check
+	 * @param  string  $parent  parent path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _inpath($path, $parent) {
+		return $path == $parent || strpos($path, $parent.'/') === 0;
+	}
+
+	
+	/**
+	 * Converting array of objects with name and value properties to
+	 * array[key] = value
+	 * @param  array  $metadata  source array
+	 * @return array
+	 * @author Alexey Sukhotin
+	 **/
+	protected function metaobj2array($metadata) {
+		$arr = array();
+		
+		if (is_array($metadata)) {
+			foreach ($metadata as $meta) {
+				$arr[$meta->Name] = $meta->Value;
+			}
+		} else {
+			$arr[$metadata->Name] = $metadata->Value;
+		}
+		return $arr;
+	}
+	
+	/**
+	 * Return stat for given path.
+	 * Stat contains following fields:
+	 * - (int)    size    file size in b. required
+	 * - (int)    ts      file modification time in unix time. required
+	 * - (string) mime    mimetype. required for folders, others - optionally
+	 * - (bool)   read    read permissions. required
+	 * - (bool)   write   write permissions. required
+	 * - (bool)   locked  is object locked. optionally
+	 * - (bool)   hidden  is object hidden. optionally
+	 * - (string) alias   for symlinks - link target path relative to root path. optionally
+	 * - (string) target  for symlinks - link target path. optionally
+	 *
+	 * If file does not exists - returns empty array or false.
+	 *
+	 * @param  string  $path    file path 
+	 * @return array|false
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _stat($path) {
+	
+		$stat = array(
+		 'size' => 0,
+		 'ts' => time(),
+		 'read' => true,
+		 'write' => true,
+		 'locked' => false,
+		 'hidden' => false,
+		 'mime' => 'directory',
+		);
+		
+		
+		if ($this->root == $path) {
+			return $stat;
+		}
+
+
+		$np = $this->_normpath($path);
+		
+		try {
+			$obj = $this->s3->GetObject(array('Bucket' => $this->options['bucket'], 'Key' => $np , 'GetMetadata' => true, 'InlineData' => false, 'GetData' => false));
+		} catch (Exception $e) {
+		
+		}
+			
+		if (!isset($obj) || ($obj->GetObjectResponse->Status->Code != 200)) {
+			$np .= '/';
+			try {
+				$obj = $this->s3->GetObject(array('Bucket' => $this->options['bucket'], 'Key' => $np , 'GetMetadata' => true, 'InlineData' => false, 'GetData' => false));
+			} catch (Exception $e) {
+		
+			}
+		}
+			
+		if (!(isset($obj) && $obj->GetObjectResponse->Status->Code == 200)) {
+				return array();
+		}
+		
+		$mime = '';
+		
+		$metadata = $this->metaobj2array($obj->GetObjectResponse->Metadata);
+			
+		$mime = $metadata['Content-Type'];
+		
+		if (!empty($mime)) {
+		 $stat['mime'] = ($mime == 'binary/octet-stream') ? 'directory' : $mime;
+		}
+		
+		if (isset($obj->GetObjectResponse->LastModified)) {
+			$stat['ts'] = strtotime($obj->GetObjectResponse->LastModified);
+		}
+			
+		try {
+			$files = $this->s3->ListBucket(array('Bucket' => $this->options['bucket'], 'Prefix' => $np, 'Delimiter' => '/'))->ListBucketResponse->Contents;
+		} catch (Exception $e) {
+			
+		}
+			
+		if (!is_array($files)) {
+			$files = array($files);
+		}
+		
+		foreach ($files as $file) {
+			if ($file->Key == $np) {
+				$stat['size'] = $file->Size;
+			}
+		}
+
+		return $stat;
+	}
+	
+	
+
+	/***************** file stat ********************/
+
+		
+	/**
+	 * Return true if path is dir and has at least one childs directory
+	 *
+	 * @param  string  $path  dir path
+	 * @return bool
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _subdirs($path) {
+		$stat = $this->_stat($path);
+		
+		if ($stat['mime'] == 'directory') {
+		 $files = $this->_scandir($path);
+		 foreach ($files as $file) {
+			$fstat = $this->_stat($file);
+			if ($fstat['mime'] == 'directory') {
+				return true;
+			}
+		 }
+		
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Return object width and height
+	 * Ususaly used for images, but can be realize for video etc...
+	 *
+	 * @param  string  $path  file path
+	 * @param  string  $mime  file mime type
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	 protected function _dimensions($path, $mime) {
+		return false;
+	 }
+	
+	/******************** file/dir content *********************/
+
+	/**
+	 * Return files list in directory
+	 *
+	 * @param  string  $path  dir path
+	 * @return array
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _scandir($path) {
+		
+		$s3path = preg_replace("/^\//", "", $path) . '/';
+		
+		$files = $this->s3->ListBucket(array('Bucket' => $this->options['bucket'], 'delimiter' => '/', 'Prefix' => $s3path))->ListBucketResponse->Contents;
+	
+		$finalfiles = array();
+		
+		foreach ($files as $file) {
+			if (preg_match("|^" . $s3path . "[^/]*/?$|", $file->Key)) {
+				$fname = preg_replace("/\/$/", "", $file->Key);
+				$fname = $file->Key;
+				
+				if ($fname != preg_replace("/\/$/", "", $s3path)) {
+					
+				}
+				
+				$finalfiles[] = $fname;
+			}
+		}
+		
+		sort($finalfiles);
+		return $finalfiles;
+	}
+	
+	/**
+	 * Return temporary file path for required file
+	 *
+	 * @param  string  $path   file path
+	 * @return string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function tmpname($path) {
+		return $this->tmpPath.DIRECTORY_SEPARATOR.md5($path);
+	}
+	
+	/**
+	 * Open file and return file pointer
+	 *
+	 * @param  string  $path  file path
+	 * @param  bool    $write open file for writing
+	 * @return resource|false
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _fopen($path, $mode="rb") {
+	
+		$tn = $this->tmpname($path);
+	
+		$fp = $this->tmbPath
+			? @fopen($tn, 'w+')
+			: @tmpfile();
+		
+
+		if ($fp) {
+
+			try {
+				$obj = $this->s3->GetObject(array('Bucket' => $this->options['bucket'], 'Key' => $this->_normpath($path) , 'GetMetadata' => true, 'InlineData' => true, 'GetData' => true));
+			}	catch (Exception $e) {
+		
+			}
+				
+			$mime = '';
+		
+			$metadata = $this->metaobj2array($obj->GetObjectResponse->Metadata);
+
+			fwrite($fp, $obj->GetObjectResponse->Data);
+			rewind($fp);
+			return $fp;
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Close opened file
+	 * 
+	 * @param  resource  $fp    file pointer
+	 * @param  string    $path  file path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _fclose($fp, $path='') {
+		@fclose($fp);
+		if ($path) {
+			@unlink($this->tmpname($path));
+		}
+	}
+	
+	/********************  file/dir manipulations *************************/
+	
+	/**
+	 * Create dir and return created dir path or false on failed
+	 *
+	 * @param  string  $path  parent dir path
+	 * @param string  $name  new directory name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _mkdir($path, $name) {
+		
+		$newkey = $this->_normpath($path);
+		$newkey = preg_replace("/\/$/", "", $newkey);
+		$newkey = "$newkey/$name/";
+
+		try {
+			$obj = $this->s3->PutObjectInline(array('Bucket' => $this->options['bucket'], 'Key' => $newkey , 'ContentLength' => 0, 'Data' => ''));
+		} catch (Exception $e) {
+		
+		}
+		
+		if (isset($obj)) {
+			return "$path/$name";
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Create file and return it's path or false on failed
+	 *
+	 * @param  string  $path  parent dir path
+	 * @param string  $name  new file name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov,
+	 * @author Alexey Sukhotin
+	 **/
+	 protected function _mkfile($path, $name) {
+		$newkey = $this->_normpath($path);
+		$newkey = preg_replace("/\/$/", "", $newkey);
+		$newkey = "$newkey/$name";
+
+		try {
+			$obj = $this->s3->PutObjectInline(array('Bucket' => $this->options['bucket'], 'Key' => $newkey , 'ContentLength' => 0, 'Data' => '', 'Metadata' => array(array('Name' => 'Content-Type', 'Value' => 'text/plain'))));
+		} catch (Exception $e) {
+		
+		}
+		
+		if (isset($obj)) {
+			return "$path/$name";
+		}
+		
+		return false;
+
+	 }
+	
+	/**
+	 * Create symlink
+	 *
+	 * @param  string  $source     file to link to
+	 * @param  string  $targetDir  folder to create link in
+	 * @param  string  $name       symlink name
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	 protected function _symlink($source, $targetDir, $name) {
+		return false;
+	 }
+	
+	/**
+	 * Copy file into another file (only inside one volume)
+	 *
+	 * @param  string  $source  source file path
+	 * @param  string  $target  target dir path
+	 * @param  string  $name    file name
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	 protected function _copy($source, $targetDir, $name) {
+		return false;
+	 }
+	
+	/**
+	 * Move file into another parent dir.
+	 * Return new file path or false.
+	 *
+	 * @param  string  $source  source file path
+	 * @param  string  $target  target dir path
+	 * @param  string  $name    file name
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _move($source, $targetDir, $name) {
+		return false;
+	}
+	
+	/**
+	 * Remove file
+	 *
+	 * @param  string  $path  file path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _unlink($path) {
+		
+		$newkey = $this->_normpath($path);
+		$newkey = preg_replace("/\/$/", "", $newkey);
+
+		try {
+			$obj = $this->s3->DeleteObject(array('Bucket' => $this->options['bucket'], 'Key' => $newkey));
+		} catch (Exception $e) {
+		
+		}
+		
+		/*$fp = fopen('/tmp/eltest.txt','a+');
+		
+		fwrite($fp, 'key='.$newkey);*/
+		
+		if (is_object($obj)) {
+			//fwrite($fp, 'obj='.var_export($obj,true));
+			
+			if (isset($obj->DeleteObjectResponse->Code)) {
+				$rc = $obj->DeleteObjectResponse->Code;
+				
+				if (substr($rc, 0, 1) == '2') {
+					return true;
+				}
+			}
+		}
+
+			
+		//fclose($fp);
+		
+		return false;
+	}
+
+	/**
+	 * Remove dir
+	 *
+	 * @param  string  $path  dir path
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _rmdir($path) {
+		return $this->_unlink($path . '/');
+	}
+
+	/**
+	 * Create new file and write into it from file pointer.
+	 * Return new file path or false on error.
+	 *
+	 * @param  resource  $fp   file pointer
+	 * @param  string    $dir  target dir path
+	 * @param  string    $name file name
+	 * @return bool|string
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _save($fp, $dir, $name, $mime, $w, $h) {
+		return false;
+	}
+	
+	/**
+	 * Get file contents
+	 *
+	 * @param  string  $path  file path
+	 * @return string|false
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _getContents($path) {
+		return false;
+	}
+	
+	/**
+	 * Write a string to a file
+	 *
+	 * @param  string  $path     file path
+	 * @param  string  $content  new file content
+	 * @return bool
+	 * @author Dmitry (dio) Levashov
+	 **/
+	protected function _filePutContents($path, $content) {
+		return false;
+	}
+
+	/**
+	 * Extract files from archive
+	 *
+	 * @param  string  $path file path
+	 * @param  array   $arc  archiver options
+	 * @return bool
+	 * @author Dmitry (dio) Levashov, 
+	 * @author Alexey Sukhotin
+	 **/
+	 protected function _extract($path, $arc) {
+		return false;
+	 }
+
+	/**
+	 * Create archive and return its path
+	 *
+	 * @param  string  $dir    target dir
+	 * @param  array   $files  files names list
+	 * @param  string  $name   archive name
+	 * @param  array   $arc    archiver options
+	 * @return string|bool
+	 * @author Dmitry (dio) Levashov, 
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _archive($dir, $files, $name, $arc) {
+		return false;
+	}
+
+	/**
+	 * Detect available archivers
+	 *
+	 * @return void
+	 * @author Dmitry (dio) Levashov, 
+	 * @author Alexey Sukhotin
+	 **/
+	protected function _checkArchivers() {
+		
+	}
+
+}
+
+/**
+ * SoapClient extension with Amazon S3 WSDL and request signing support
+ *
+ * @author Alexey Sukhotin
+ **/
+class S3SoapClient extends SoapClient {
+
+	private $accesskey = ''; 
+	private $secretkey = '';
+	public $client = NULL;
+	
+
+	public function __construct($key = '', $secret = '') {
+		$this->accesskey = $key;
+		$this->secretkey = $secret;
+		parent::__construct('http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.wsdl');
+	}
+	
+	
+	/**
+	 * Method call wrapper which adding S3 signature and default arguments to all S3 operations
+	 *
+	 * @author Alexey Sukhotin
+	 **/
+	public function __call($method, $arguments) {
+		
+		/* Getting list of S3 web service functions which requires signing */
+		$funcs = $this->__getFunctions();
+		
+		$funcnames  = array();
+		
+		foreach ($funcs as $func) {
+			preg_match("/\S+\s+([^\)]+)\(/", $func, $m);
+	
+			if (isset($m[1])) {
+				$funcnames[] = $m[1];
+			}
+		}
+		
+		/* adding signature to arguments */
+		if (in_array("{$method}", $funcnames)) {
+		
+			if (is_array($arguments[0])) {
+				$arguments[0] = array_merge($arguments[0], $this->sign("{$method}"));
+			} else {
+				$arguments[0] = $this->sign("{$method}");
+			}
+
+		}
+		
+		/*$fp = fopen('/tmp/s3debug.txt', 'a+');
+		fwrite($fp, 'method='."{$method}". ' timestamp='.date('Y-m-d H:i:s').' args='.var_export($arguments,true) . "\n");
+		fclose($fp);*/
+		return parent::__call($method, $arguments);
+	}
+
+	/**
+	 * Generating signature and timestamp for specified S3 operation
+	 *
+	 * @param  string  $operation    S3 operation name
+	 * @return array
+	 * @author Alexey Sukhotin
+	 **/
+	protected function sign($operation) {
+	
+		$params = array(
+			'AWSAccessKeyId' => $this->accesskey,
+			'Timestamp' => gmdate('Y-m-d\TH:i:s.000\Z'),
+		);
+
+		$sign_str = 'AmazonS3' . $operation . $params['Timestamp'];
+		
+		$params['Signature'] = base64_encode(hash_hmac('sha1', $sign_str, $this->secretkey, TRUE));
+		
+		return $params;
+	}
+	
+}
+
+?>

+ 157 - 0
main/inc/lib/elfinder/php/plugins/AutoResize/plugin.php

@@ -0,0 +1,157 @@
+<?php
+
+class elFinderPluginAutoResize {
+
+	private $opts = array();
+
+	public function __construct($opts) {
+		$defaults = array(
+			'enable'         => true,       // For control by volume driver
+			'maxWidth'       => 1024,       // Path to Water mark image
+			'maxHeight'      => 1024,       // Margin right pixel
+			'quality'        => 95,         // JPEG image save quality
+			'targetType'     => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP // Target image formats ( bit-field )
+		);
+
+		$this->opts = array_merge($defaults, $opts);
+
+	}
+
+	public function onUpLoadPreSave(&$path, &$name, $src, $elfinder, $volume) {
+		$opts = $this->opts;
+		$volOpts = $volume->getOptionsPlugin('AutoResize');
+		if (is_array($volOpts)) {
+			$opts = array_merge($this->opts, $volOpts);
+		}
+		
+		if (! $opts['enable']) {
+			return false;
+		}
+		
+		$srcImgInfo = @getimagesize($src);
+		if ($srcImgInfo === false) {
+			return false;
+		}
+		
+		// check target image type
+		$imgTypes = array(
+				IMAGETYPE_GIF => IMG_GIF,
+				IMAGETYPE_JPEG => IMG_JPEG,
+				IMAGETYPE_PNG => IMG_PNG,
+				IMAGETYPE_WBMP => IMG_WBMP,
+		);
+		if (! ($opts['targetType'] & $imgTypes[$srcImgInfo[2]])) {
+			return false;
+		}
+		
+		if ($srcImgInfo[0] > $opts['maxWidth'] || $srcImgInfo[1] > $opts['maxHeight']) {
+			return $this->resize($src, $srcImgInfo, $opts['maxWidth'], $opts['maxHeight'], $opts['quality']);
+		}
+		
+		return false;
+	}
+	
+	private function resize($src, $srcImgInfo, $maxWidth, $maxHeight, $quality) {
+		$zoom = min(($maxWidth/$srcImgInfo[0]),($maxHeight/$srcImgInfo[1]));
+		$width = round($srcImgInfo[0] * $zoom);
+		$height = round($srcImgInfo[1] * $zoom);
+		
+		if (class_exists('Imagick')) {
+			return $this->resize_imagick($src, $width, $height, $quality);
+		} else {
+			return $this->resize_gd($src, $width, $height, $quality, $srcImgInfo);
+		}
+	}
+	
+	private function resize_gd($src, $width, $height, $quality, $srcImgInfo) {
+		switch ($srcImgInfo['mime']) {
+			case 'image/gif':
+				if (@imagetypes() & IMG_GIF) {
+					$oSrcImg = @imagecreatefromgif($src);
+				} else {
+					$ermsg = 'GIF images are not supported';
+				}
+				break;
+			case 'image/jpeg':
+				if (@imagetypes() & IMG_JPG) {
+					$oSrcImg = @imagecreatefromjpeg($src) ;
+				} else {
+					$ermsg = 'JPEG images are not supported';
+				}
+				break;
+			case 'image/png':
+				if (@imagetypes() & IMG_PNG) {
+					$oSrcImg = @imagecreatefrompng($src) ;
+				} else {
+					$ermsg = 'PNG images are not supported';
+				}
+				break;
+			case 'image/wbmp':
+				if (@imagetypes() & IMG_WBMP) {
+					$oSrcImg = @imagecreatefromwbmp($src);
+				} else {
+					$ermsg = 'WBMP images are not supported';
+				}
+				break;
+			default:
+				$oSrcImg = false;
+				$ermsg = $srcImgInfo['mime'].' images are not supported';
+				break;
+		}
+		
+		if ($oSrcImg &&  false != ($tmp = imagecreatetruecolor($width, $height))) {
+			
+			if (!imagecopyresampled($tmp, $oSrcImg, 0, 0, 0, 0, $width, $height, $srcImgInfo[0], $srcImgInfo[1])) {
+				return false;
+			}
+		
+			switch ($srcImgInfo['mime']) {
+				case 'image/gif':
+					imagegif($tmp, $src);
+					break;
+				case 'image/jpeg':
+					imagejpeg($tmp, $src, $quality);
+					break;
+				case 'image/png':
+					if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
+						imagealphablending($tmp, false);
+						imagesavealpha($tmp, true);
+					}
+					imagepng($tmp, $src);
+					break;
+				case 'image/wbmp':
+					imagewbmp($tmp, $src);
+					break;
+			}
+			
+			imagedestroy($oSrcImg);
+			imagedestroy($tmp);
+		
+			return true;
+		
+		}
+		return false;
+	}
+	
+	private function resize_imagick($src, $width, $height, $quality) {
+		try {
+			$img = new imagick($src);
+		
+			if (strtoupper($img->getImageFormat()) === 'JPEG') {
+				$img->setImageCompression(imagick::COMPRESSION_JPEG);
+				$img->setCompressionQuality($quality);
+			}
+			
+			$img->resizeImage($width, $height, Imagick::FILTER_LANCZOS, true);
+			
+			$result = $img->writeImage($src);
+			
+			$img->clear();
+			$img->destroy();
+			
+			return $result ? true : false;
+		} catch (Exception $e) {
+			return false;
+		}
+	}
+}

+ 119 - 0
main/inc/lib/elfinder/php/plugins/Normalizer/plugin.php

@@ -0,0 +1,119 @@
+<?php
+/**
+ * elFinder Plugin Normalizer
+ * 
+ * UTF-8 Normalizer of file-name and file-path etc.
+ * nfc(NFC): Canonical Decomposition followed by Canonical Composition
+ * nfkc(NFKC): Compatibility Decomposition followed by Canonical
+ * 
+ * This plugin require Class "Normalizer" (PHP 5 >= 5.3.0, PECL intl >= 1.0.0)
+ * or PEAR package "I18N_UnicodeNormalizer"
+ * 
+ * ex. binding, configure on connector options
+ *	$opts = array(
+ *		'bind' => array(
+ *			'mkdir.pre mkfile.pre rename.pre' => 'Plugin.Normalizer.cmdPreprocess',
+ *			'upload.presave' => array(
+ *				'Plugin.Normalizer.onUpLoadPreSave'
+ *			)
+ *		),
+ *		// global configure (optional)
+ *		'plugin' => array(
+ *			'Normalizer' = array(
+ *				'enable' => true,
+ *				'nfc'    => true,
+ *				'nfkc'   => true
+ *			)
+ *		),
+ *		// each volume configure (optional)
+ *		'roots' => array(
+ *			array(
+ *				'driver' => 'LocalFileSystem',
+ *				'path'   => '/path/to/files/',
+ *				'URL'    => 'http://localhost/to/files/'
+ *				'plugin' => array(
+ *					'Normalizer' = array(
+ *						'enable' => true,
+ *						'nfc'    => true,
+ *						'nfkc'   => true
+ *					)
+ *				)
+ *			)
+ *		)
+ *	);
+ *
+ * @package elfinder
+ * @author Naoki Sawada
+ * @license New BSD
+ */
+class elFinderPluginNormalizer
+{
+	private $opts = array();
+	
+	public function __construct($opts) {
+		$defaults = array(
+			'enable' => true, // For control by volume driver
+			'nfc'    => true, // Canonical Decomposition followed by Canonical Composition
+			'nfkc'   => true  // Compatibility Decomposition followed by Canonical
+		);
+	
+		$this->opts = array_merge($defaults, $opts);
+	}
+	
+	public function cmdPreprocess($cmd, &$args, $elfinder, $volume) {
+		$opts = $this->getOpts($volume);
+		if (! $opts['enable']) {
+			return false;
+		}
+		
+		if (isset($args['name'])) {
+			$args['name'] = $this->normalize($args['name'], $opts);
+		}
+		return true;
+	}
+	
+	public function onUpLoadPreSave(&$path, &$name, $src, $elfinder, $volume) {
+		$opts = $this->getOpts($volume);
+		if (! $opts['enable']) {
+			return false;
+		}
+		
+		if ($path) {
+			$path = $this->normalize($path, $opts);
+		}
+		$name = $this->normalize($name, $opts);
+		return false;
+	}
+	
+	private function getOpts($volume) {
+		$opts = $this->opts;
+		if (is_object($volume)) {
+			$volOpts = $volume->getOptionsPlugin('Normalizer');
+			if (is_array($volOpts)) {
+				$opts = array_merge($this->opts, $volOpts);
+			}
+		}
+		return $opts;
+	}
+	
+	private function normalize($str, $opts) {
+		if (class_exists('Normalizer')) {
+			if ($opts['nfc'] && ! Normalizer::isNormalized($str, Normalizer::FORM_C))
+				$str = Normalizer::normalize($str, Normalizer::FORM_C);
+			if ($opts['nfkc'] && ! Normalizer::isNormalized($str, Normalizer::FORM_KC))
+				$str = Normalizer::normalize($str, Normalizer::FORM_KC);
+		} else {
+			if (! class_exists('I18N_UnicodeNormalizer')) {
+				@ include_once 'I18N/UnicodeNormalizer.php';
+			}
+			if (class_exists('I18N_UnicodeNormalizer')) {
+				$normalizer = new I18N_UnicodeNormalizer();
+				if ($opts['nfc'])
+					$str = $normalizer->normalize($str, 'NFC');
+				if ($opts['nfkc'])
+					$str = $normalizer->normalize($str, 'NFKC');
+			}
+		}
+		return $str;
+	}
+}

BIN
main/inc/lib/elfinder/php/plugins/Watermark/logo.png


+ 243 - 0
main/inc/lib/elfinder/php/plugins/Watermark/plugin.php

@@ -0,0 +1,243 @@
+<?php
+
+class elFinderPluginWatermark {
+
+	private $opts = array();
+	private $watermarkImgInfo = null;
+
+	public function __construct($opts) {
+		$defaults = array(
+			'enable'         => true,       // For control by volume driver
+			'source'         => 'logo.png', // Path to Water mark image
+			'marginRight'    => 5,          // Margin right pixel
+			'marginBottom'   => 5,          // Margin bottom pixel
+			'quality'        => 95,         // JPEG image save quality
+			'transparency'   => 70,         // Water mark image transparency ( other than PNG )
+			'targetType'     => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
+			'targetMinPixel' => 200         // Target image minimum pixel size
+		);
+
+		$this->opts = array_merge($defaults, $opts);
+
+	}
+
+	public function onUpLoadPreSave(&$path, &$name, $src, $elfinder, $volume) {
+		
+		$opts = $this->opts;
+		$volOpts = $volume->getOptionsPlugin('Watermark');
+		if (is_array($volOpts)) {
+			$opts = array_merge($this->opts, $volOpts);
+		}
+		
+		if (! $opts['enable']) {
+			return false;
+		}
+		
+		$srcImgInfo = @getimagesize($src);
+		if ($srcImgInfo === false) {
+			return false;
+		}
+		
+		// check water mark image
+		if (! file_exists($opts['source'])) {
+			$opts['source'] = dirname(__FILE__) . "/" . $opts['source'];
+		}
+		if (is_readable($opts['source'])) {
+			$watermarkImgInfo = @getimagesize($opts['source']);
+			if (! $watermarkImgInfo) {
+				return false;
+			}
+		} else {
+			return false;
+		}
+		
+		$watermark = $opts['source'];
+		$marginLeft = $opts['marginRight'];
+		$marginBottom = $opts['marginBottom'];
+		$quality = $opts['quality'];
+		$transparency = $opts['transparency'];
+
+		// check target image type
+		$imgTypes = array(
+			IMAGETYPE_GIF => IMG_GIF,
+			IMAGETYPE_JPEG => IMG_JPEG,
+			IMAGETYPE_PNG => IMG_PNG,
+			IMAGETYPE_WBMP => IMG_WBMP,
+		);
+		if (! ($opts['targetType'] & $imgTypes[$srcImgInfo[2]])) {
+			return false;
+		}
+		
+		// check target image size
+		if ($opts['targetMinPixel'] > 0 && $opts['targetMinPixel'] > min($srcImgInfo[0], $srcImgInfo[1])) {
+			return false;
+		}
+		
+		$watermark_width = $watermarkImgInfo[0];
+		$watermark_height = $watermarkImgInfo[1];
+		$dest_x = $srcImgInfo[0] - $watermark_width - $marginLeft;
+		$dest_y = $srcImgInfo[1] - $watermark_height - $marginBottom;
+		
+		if (class_exists('Imagick')) {
+			return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo);
+		} else {
+			return $this->watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo);
+		}
+	}
+	
+	private function watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo) {
+		
+		try {
+			// Open the original image
+			$img = new Imagick($src);
+			
+			// Open the watermark
+			$watermark = new Imagick($watermark);
+			
+			// Set transparency
+			if (strtoupper($watermark->getImageFormat()) !== 'PNG') {
+				$watermark->setImageOpacity($transparency/100);
+			}
+			
+			// Overlay the watermark on the original image
+			$img->compositeImage($watermark, imagick::COMPOSITE_OVER, $dest_x, $dest_y);
+			
+			// Set quality
+			if (strtoupper($img->getImageFormat()) === 'JPEG') {
+				$img->setImageCompression(imagick::COMPRESSION_JPEG);
+				$img->setCompressionQuality($quality);
+			}
+			
+			$result = $img->writeImage($src);
+			
+			$img->clear();
+			$img->destroy();
+			$watermark->clear();
+			$watermark->destroy();
+			
+			return $result ? true : false;
+		} catch (Exception $e) {
+			return false;
+		}
+	}
+	
+	private function watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo) {
+		
+		$watermark_width = $watermarkImgInfo[0];
+		$watermark_height = $watermarkImgInfo[1];
+				
+		$ermsg = '';
+		switch ($watermarkImgInfo['mime']) {
+			case 'image/gif':
+				if (@imagetypes() & IMG_GIF) {
+					$oWatermarkImg = @imagecreatefromgif($watermark);
+				} else {
+					$ermsg = 'GIF images are not supported';
+				}
+				break;
+			case 'image/jpeg':
+				if (@imagetypes() & IMG_JPG) {
+					$oWatermarkImg = @imagecreatefromjpeg($watermark) ;
+				} else {
+					$ermsg = 'JPEG images are not supported';
+				}
+				break;
+			case 'image/png':
+				if (@imagetypes() & IMG_PNG) {
+					$oWatermarkImg = @imagecreatefrompng($watermark) ;
+				} else {
+					$ermsg = 'PNG images are not supported';
+				}
+				break;
+			case 'image/wbmp':
+				if (@imagetypes() & IMG_WBMP) {
+					$oWatermarkImg = @imagecreatefromwbmp($watermark);
+				} else {
+					$ermsg = 'WBMP images are not supported';
+				}
+				break;
+			default:
+				$oWatermarkImg = false;
+				$ermsg = $watermarkImgInfo['mime'].' images are not supported';
+				break;
+		}
+		
+		if (! $ermsg) {
+			switch ($srcImgInfo['mime']) {
+				case 'image/gif':
+					if (@imagetypes() & IMG_GIF) {
+						$oSrcImg = @imagecreatefromgif($src);
+					} else {
+						$ermsg = 'GIF images are not supported';
+					}
+					break;
+				case 'image/jpeg':
+					if (@imagetypes() & IMG_JPG) {
+						$oSrcImg = @imagecreatefromjpeg($src) ;
+					} else {
+						$ermsg = 'JPEG images are not supported';
+					}
+					break;
+				case 'image/png':
+					if (@imagetypes() & IMG_PNG) {
+						$oSrcImg = @imagecreatefrompng($src) ;
+					} else {
+						$ermsg = 'PNG images are not supported';
+					}
+					break;
+				case 'image/wbmp':
+					if (@imagetypes() & IMG_WBMP) {
+						$oSrcImg = @imagecreatefromwbmp($src);
+					} else {
+						$ermsg = 'WBMP images are not supported';
+					}
+					break;
+				default:
+					$oSrcImg = false;
+					$ermsg = $srcImgInfo['mime'].' images are not supported';
+					break;
+			}
+		}
+		
+		if ($ermsg || false === $oSrcImg || false === $oWatermarkImg) {
+			return false;
+		}
+		
+		if ($srcImgInfo['mime'] === 'image/png') {
+			if (function_exists('imagecolorallocatealpha')) {
+				$bg = imagecolorallocatealpha($oSrcImg, 255, 255, 255, 127);
+				imagefill($oSrcImg, 0, 0 , $bg);
+			}
+		}
+		
+		if ($watermarkImgInfo['mime'] === 'image/png') {
+			imagecopy($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
+		} else {
+			imagecopymerge($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $transparency);
+		}
+		
+		switch ($srcImgInfo['mime']) {
+			case 'image/gif':
+				imagegif($oSrcImg, $src);
+				break;
+			case 'image/jpeg':
+				imagejpeg($oSrcImg, $src, $quality);
+				break;
+			case 'image/png':
+				if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
+					imagealphablending($oSrcImg, false);
+					imagesavealpha($oSrcImg, true);
+				}
+				imagepng($oSrcImg, $src);
+				break;
+			case 'image/wbmp':
+				imagewbmp($oSrcImg, $src);
+				break;
+		}
+
+		imageDestroy($oSrcImg);
+		imageDestroy($oWatermarkImg);
+		
+		return true;
+	}
+}

BIN
main/inc/lib/elfinder/rm.wav


Some files were not shown because too many files changed in this diff